質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

966閲覧

JavaScript 連続入力の制御ができない

nano_09

総合スコア15

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2020/10/26 15:52

前提・実現したいこと

配列の中の1に乗ると自動で1マス分動く。(これはできてる)
配列の中の1に乗った場合、キーボードからの入力を受け付けずに(乗った瞬間操作できない)、自動で動くようにしたい。(これができない)

発生している問題・エラーメッセージ

自分の中では、
ずっと動いていようが1マスの中で必ずHuman.moveが0の状態が来る
つまり動いていない状態の時が来るので(目では連続して動いているように見える)
動いていたものを止めて、上方向に動かすという処理を考えていたのですが
ずっと動いている時(連続で入力をしている)は、Human.moveが0かつHuman.automaticがtrueの場合でもその1のマスをそのまま突き抜けていってしまうのですが
これは何が原因でそうなっているのでしょうか。

説明(自分の中の設定)
Human.move...動いている状態を表す。
Human.automatic...乗っている場所が自動で動く床かどうかを表す。

該当のソースコード

HTML

1<!DOCTYPE html> 2<html> 3 <head> 4 <meta charset="utf-8"> 5 <link rel="stylesheet" href="Adventure.css"> 6 <script src="../../jquery-3.5.1.min.js"></script> 7 </head> 8 <body> 9 <canvas id="canvas"></canvas> 10 <script type="text/javascript" src="main.js"></script> 11 </body> 12</html>

JavaScript

1var canvas = document.getElementById('canvas'); 2canvas.width = 928; 3canvas.height = 448; 4 5var ctx = canvas.getContext('2d'); 6 7var Human = new Object(); 8Human.img = new Image(); 9Human.img.src = 'img/Human.png'; 10Human.x = 448; 11Human.y = 384; 12Human.move = 0; 13 14var ground = new Image(); 15ground.src = 'img/yuka.png'; 16 17var movefloor = new Image(); 18movefloor.src = 'img/movefloor.png'; 19 20var key = new Object(); 21key.up = false; 22key.down = false; 23key.right = false; 24key.left = false; 25key.push = ''; 26 27var map = [ 28 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 29 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 30 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 31 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 32 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 33 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 34 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 35 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 36 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 37 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 38 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 39 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 40 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 41 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 42]; 43 44window.addEventListener("keydown", keydownfunc, false); 45window.addEventListener("keyup", keyupfunc, false); 46 47function keydownfunc( event ) { 48 var key_code = event.keyCode; 49 if(key_code === 37 && Human.automatic === false){ 50 key.left = true; 51 }else if(key_code === 38 && Human.automatic === false){ 52 key.up = true; 53 }else if(key_code === 39 && Human.automatic === false){ 54 key.right = true; 55 }else if(key_code === 40 && Human.automatic === false){ 56 key.down = true; 57 } 58 //確認用コード 『a』で確認できます 59 else if(key_code === 65){ 60 alert(Human.x + " " + Human.y + " " + Human.move + " " + Human.automatic); 61 } 62 event.preventDefault(); 63} 64 65function keyupfunc( event ) { 66 var key_code = event.keyCode; 67 if(key_code === 37) key.left = false; 68 if(key_code === 38) key.up = false; 69 if(key_code === 39) key.right = false; 70 if(key_code === 40) key.down = false; 71} 72 73function main() { 74 ctx.fillStyle = "rgb( 0, 0, 0 )"; 75 76 ctx.fillRect(0, 0, 960, 448); 77 78 for (var y=0; y<map.length; y++) { 79 for (var x=0; x<map[y].length; x++) { 80 if (map[y][x] === 0) 81 ctx.drawImage(ground,0,0,32,32,32*x,32*y,32,32); 82 if (map[y][x] === 1) 83 ctx.drawImage(movefloor,0,0,96,96,32*x,32*y,96,96); 84 } 85 } 86 87 ctx.drawImage(Human.img, Human.x, Human.y); 88 89 var x = Human.x/32; 90 var y = Human.y/32; 91 92 if ( Human.move === 0 ) { 93 if ( key.left === true ) { 94 x--; 95 if (map[y][x] === 0 || map[y][x] === 1) { 96 Human.move = 32; 97 key.push = 'left'; 98 if(map[y][x] === 11 && aaa === true){ 99 Human.automatic = true; 100 } 101 } 102 } 103 104 if ( key.up === true ) { 105 if ( y > 0) { 106 y--; 107 if (map[y][x] === 0 || map[y][x] ===1) { 108 Human.move = 32; 109 key.push = 'up'; 110 } 111 } 112 } 113 114 if ( key.right === true ) { 115 x++; 116 if (map[y][x] === 0 || map[y][x] === 1) { 117 Human.move = 32; 118 key.push = 'right'; 119 } 120 } 121 122 if ( key.down === true ) { 123 if ( y < 19 ) { 124 y++; 125 if (map[y][x] === 0 || map[y][x] === 1) { 126 Human.move = 32; 127 key.push = 'down'; 128 } 129 } 130 } 131 } 132 133 134 if(Human.move === 0 && map[y][x] === 1){ 135 Human.move = 32; 136 Human.automatic = true; 137 key.push = 'up'; 138 }else if(Human.move === 0 && map[y][x] === 0){ 139 Human.automatic = false; 140 } 141 142 if (Human.move > 0) { 143 Human.move -= 4; 144 if ( key.push === 'left' ) Human.x -= 4; 145 if ( key.push === 'up' ) Human.y -= 4; 146 if ( key.push === 'right' ) Human.x += 4; 147 if ( key.push === 'down' ) Human.y += 4; 148 } 149 150 window.requestAnimationFrame( main ); 151 } 152window.addEventListener('load', main(), false); 153 154

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

設計を変更してください。

1マスが 32px に対して 4px ずつ動かすような例では、「配列をずらす」手法ではなく、
MAPデータから動的生成した大きな絵(Canvas)の指定範囲を表示する手法を用います。

  1. map データ(配列)から大きな絵を作り、バッファ用Canvasに保持しておく。
  2. 表示用のCanvasに ctx.drawImage( canvas, ... ) で描く。
  • MDN 画像を使う  の「切り抜き」セクションにある「大きな画像の指定範囲をCanvasに描く」という方法が基本になり、第一引数の imagecanvasも対応します。

過去のご質問「JavaScriptでcanvasを2つ使う理由」の回答も関連してきます。

※なお、4px分の移動に何フレームを要するかなど、ゲーム進行における時間管理も必要です。

投稿2020/10/26 21:53

AkitoshiManabe

総合スコア5434

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

AkitoshiManabe

2020/10/26 21:57

Canvas 表示にこだわらず、「ゲームコンテンツのプログラミング手法全体を把握する」目的であれば、既存のフレームワーク(ソースコード)を読んでも良いかもしれません。 多少の古さがありますが、enchant.js などは、取っ掛かりに経験される方が多いようです。
nano_09

2020/10/27 00:18

毎度ご回答頂き誠にありがとうございます! いくつか質問させていただきます。 ゲームを作るに当たってかなりの頻度で壁にぶつかってる気がするのですが、これはゲーム制作の基礎ができていないためによるものでしょうか。 また、そのゲーム制作の基本(?)を学ぶ必要があるでしょうか。 自分ではわからない所が出てきた際に今までの様に質問するというスタイルでも大丈夫でしょうか。 ゲーム制作をする際やはりフレームワークを使った方がやりやすいですか? よろしければご回答よろしくお願いします。
AkitoshiManabe

2020/10/27 02:05

> ゲーム制作の基礎ができていないためによるも そのとおりです。先人が築いた既存の手順(フレームワーク)を学ばずに、独自の構想だけで開発されています。ゲームコンテンツはフレームワークで簡単に実現できますし、それを改変するのが最も効率の良い手法になります(「温故知新」です)。 フレームワークを学び直すと、ご質問の「自動で動く」も、特定のオブジェクトにフラグとベクトルを定義するだけで済むと気づくはずですので、フレームワークは学習されたほうが良いと思います。
nano_09

2020/10/27 14:53

試しにenchant.js使ってみたところ、とても簡単に色々実装できるようになりました!! 教えていただきありがとうございます!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問