1

JavaScript/キャンバスを練習するために、楽しみのためにスネークゲームを作成しています。これまでに持っているのはwhileループでwhile i is < 100, then add a squareあり、使用して正方形が追加されfillRect(10, 10, xCoord, yCoord)、whileループでxCoord = xCoord + 11;正方形が右に移動します間のスペース...ここにリンクがあります:

http://brycemckenney.com/snake_canvas

そして関連するコード:

while(i < 100) {
    // fillRect(x, y, width, height)... x is horizontal and y is vertical...
    context.fillRect(xCoord, yCoord, sW, sH);

    // We want each squere to have one pixel in between them, so we increment by 11, not 10.
    xCoord = xCoord + 11;

    // When i (0) gets to numOfSquares (3), then make the rest white so that you can't see them...
    if (i >= numOfSquares) {
        context.fillStyle = "#FFFFFF";
    }

    //Increment by 1 every loop, so that the squares keep going
    i++;

}

私はヘビをアニメーション化しようとしていますが、さまざまなオプションを試しました。今、私はマージンを追加しようとしています-4つの正方形の右側にあるので、動いているように見えます...それらにマージンを追加することは可能ですか? ここに私が持っているもののスナップショットがあります:

ここに画像の説明を入力

4

2 に答える 2

6

さて、あなたはヘビのゲームを作っているので、私たちはあなたが何をしたいのかを知っています。既存のコードを変更するのではなく、正しい軌道に乗せようとした方が便利だと思います.

論理的なゲーム グリッドが 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 つのことを意味するからです。

  1. 最後の(テール)ピースを取り除く
  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. 新しいヘビが食べ物の上にある場合、尾の部分は削除されず、代わりにヘビが+1ブロック長くなります
  2. 新しいピースが 60x60 グリッドの外にある場合、ユーザーはゲームに負けます
  3. 新しいピースが他のヘビのピースのいずれかがすでに存在する場所にある場合、ユーザーはゲームに負けます

残念ながら、それらはここでは行われていません


まだすべてを描画する必要がありますが、ヘビの位置を追跡しているので、簡単です。ヘビの各部分に 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 メソッドを表示できることに注意してください。ただし、通常のスネーク ゲームではタイマーによって制御される動きがあり、通常、ユーザーは次の可能な方向のみを変更できます。

于 2013-01-12T05:30:53.370 に答える
0

canvas 要素は 2D 描画面であるため、CSS マージンのような (より高いレベルの) ものはサポートしていません。

アニメーションを行うには、キャンバスをクリアしてシーンを再描画し、そのたびに移動するオブジェクトの位置を少しずつ調整する必要があります (移動しているように見えるようにします)。あなたの場合、これは、フレームを最後に再描画したときから 4 ピクセル離れた開始位置で毎回正方形を再描画することを意味します。

MDNのBasic animationsページ (canvas チュートリアルの一部) を参照してください。

于 2013-01-16T11:00:50.533 に答える