さて、あなたはヘビのゲームを作っているので、私たちはあなたが何をしたいのかを知っています。既存のコードを変更するのではなく、正しい軌道に乗せようとした方が便利だと思います.
論理的なゲーム グリッドが 60x60 であるとします。したがって、スネークピースはこのグリッドのどこにでも配置でき、X と Y の値は 0 から 59 の間です。これは次のことを意味します。
左上隅のヘビの一部は[0, 0]
右上隅にあるヘビのかけらは[59, 0]
さらに、ヘビがいくつかのセグメントで構成されていると仮定しましょう。開始する 4 つのセグメントはどうですか。これは、4 つの位置の配列を保持する必要があることを意味します。
[position1, position2, position3, position4]
前面を選択する必要があるため、配列の最後がヘビの「前面」であるとしましょう。左上の 4 つの位置を選択すると、ヘビは次のようになります。
var mySnake = [[0, 0], [1,0], [2,0], [3,0]]
ボード上は次のようになります。
++++OOOOOOOO
OOOOOOOOOOOO
OOOOOOOOOOOO
これは、これまでと同じように、左から右に 4 つのスネークピースが配置されていることを意味します。問題は、これらの場所を保存することで、永続的な状態をプログラムに追加したことです。
さて、ヘビは面白いゲームです。なぜなら、ヘビを「動かす」ということは、実際には次の 2 つのことを意味するからです。
- 最後の(テール)ピースを取り除く
- ヘビに新しいピースを追加する
したがって、これらの両方を行うヘビを動かす関数を作成する必要があります。方向に基づいて作成します。
// modifies a snake's array
function moveSnake(snake, direction) {
// First we must remove a piece of the snake's tail, which is at the start of the array
// There's a built in command in JavaScript for this called shift()
snake.shift();
// Now we must add the new piece!
// To tell where we need to go we must look at the last location:
var lastLoc = snake[snake.length - 1];
// Just to be a little more clear:
var lastX = lastLoc[0];
var lastY = lastLoc[1];
switch (direction) {
case 'up':
snake.push([lastX, lastY-1]);
break;
case 'down':
snake.push([lastX, lastY+1]);
break;
case 'left':
snake.push([lastX-1, lastY]);
break;
case 'right':
snake.push([lastX+1, lastY]);
break;
}
// redraw after every move!
drawSnake(ctx, mySnake);
}
この方法では、次のことができます。
var mySnake = [[0, 0], [1,0], [2,0], [3,0]];
moveSnake(mySnake, 'down');
// mySnake is now [[1,0], [2,0], [3,0], [3,1]];
ヘビは次のようになります。
O+++OOOOOOOO
OOO+OOOOOOOO
OOOOOOOOOOOO
さて、このメソッドはかなりばかげており、実際のスネーク ゲームでは、いくつかの条件を追加する必要があります。通常:
- 新しいヘビが食べ物の上にある場合、尾の部分は削除されず、代わりにヘビが+1ブロック長くなります
- 新しいピースが 60x60 グリッドの外にある場合、ユーザーはゲームに負けます
- 新しいピースが他のヘビのピースのいずれかがすでに存在する場所にある場合、ユーザーはゲームに負けます
残念ながら、それらはここでは行われていません
まだすべてを描画する必要がありますが、ヘビの位置を追跡しているので、簡単です。ヘビの各部分に 1 つの正方形を描くだけです。
function drawSnake(context, snake) {
// Remember to clear the board!
ctx.clearRect(0, 0, 600, 600);
var length = snake.length;
for (var i = 0; i < length; i++) {
context.fillStyle = 'teal';
// position is its own array and looks like: [x, y]
var position = snake[i];
// our logical snake board is 60x60, but the real canvas is 600x600,
// so we multiply x and y by 10.
// We also use "9" for the width and height so theres a tiny gap
context.fillRect(position[0]*10, position[1]*10, 9, 9);
}
}
完成したデモはこちらをご覧ください。
http://jsfiddle.net/FsqXE/
矢印キーでスネークを制御して moveSnake メソッドを表示できることに注意してください。ただし、通常のスネーク ゲームではタイマーによって制御される動きがあり、通常、ユーザーは次の可能な方向のみを変更できます。