2017-04-02 17 views
1

デフォルトでは、キャンバスの矩形は左から右に移動する必要があります。キーを押すと、下に動き始めます。上記のコードを使用してキャンバス:キーを押したときの不思議な動作

var canvas = document.getElementById('canvas'), 
 
    ctx = canvas.getContext('2d'), 
 
    x = 0, 
 
    y = 0; 
 

 
function draw(x_move, y_move) { 
 
    requestAnimationFrame(function() { 
 
    draw(x_move, y_move); 
 
    }); 
 
    ctx.beginPath(); 
 
    ctx.rect(x, y, 20, 20); 
 
    ctx.clearRect(0, 0, canvas.width, canvas.height); 
 
    ctx.fillStyle = "#ffffff"; 
 
    ctx.fill(); 
 
    ctx.closePath(); 
 
    x = x + x_move; 
 
    y = y + y_move; 
 
} 
 

 
draw(1, 0); 
 

 
document.addEventListener('keydown', function(event) { 
 
    //console.log(event.keyCode); 
 
    if (event.keyCode == 40) { 
 
    draw(0, 1); 
 
    } 
 
});
canvas { background-color: red; }
<canvas id="canvas" width="600" height="400"></canvas>

、あなたは少なくとも通知は二つの問題があります下キーを押すと

  1. 、矩形は下に移動だけでなく、右に動き続けます。
  2. ダウンキーを何度も押し続けると、速度が上がります。

これらの問題を解決するにはどうすればよいですか?

+0

のような関数の形で行動を含めることができるのkeydownとからkeyupイベントでキー状態オブジェクトを変更し、ドロー機能は、その状態キーオブジェクトの状態を確認しています。あなたのコード内でdraw()を何度も呼び出さないでください。 – Chris

答えて

1

私はこれがあると信じて:ように、いくつかのdownwardTrajectory変数を変更adjustDownwardTrajectory()こと

document.addEventListener('keydown', function(event) { 
    //console.log(event.keyCode); 
    if (event.keyCode == 40) { 
    adjustDownwardTrajectory(); 
    } 
}); 

と持っている:あなたはこのような何かを行うことができ、ちょうど下に押すことによって、正方形の軌道を調整したいですあなたがしたいこと(そしてあなたは近くにいた!)。私はこれがあなたが探していた行動であることを願っています。

関連ポイント:それはあなたが誤ってプログラムの他の部分でそれらを変更しないように、これらの機能で閉鎖中まで x_movey_moveをラップするのは良い考えかもしれません。そうすることで、四角形の方向を変更するために実装する関数は、これらの変数にプライベートアクセスすることになります。

var canvas = document.getElementById('canvas'), 
 
    ctx = canvas.getContext('2d'), 
 
    x = 0, 
 
    y = 0; 
 

 
var x_move = 1; 
 
var y_move = 0; 
 

 
function draw() { 
 
    requestAnimationFrame(function() { 
 
    draw(); 
 
    }); 
 

 
    ctx.beginPath(); 
 
    ctx.rect(x, y, 20, 20); 
 
    ctx.clearRect(0, 0, canvas.width, canvas.height); 
 
    ctx.fillStyle = "#ffffff"; 
 
    ctx.fill(); 
 
    ctx.closePath(); 
 
    x = x + x_move; 
 
    y = y + y_move; 
 
} 
 

 
draw(); 
 

 
document.addEventListener('keydown', function(event) { 
 
    //console.log(event.keyCode); 
 
    if (event.keyCode == 40) { 
 
    x_move = 0; 
 
    y_move = 1; 
 
    } 
 
});
canvas { 
 
    background-color: red; 
 
}
<canvas id="canvas" width="600" height="400"></canvas>

+0

ありがとう、それは簡単に修正され、それは素晴らしい作品です! –

2

あなたはあなたが今、再帰的draw()を呼んでいる

requestAnimationFrame(function() { 
    draw(x_move, y_move); 
    }); 

を呼び出して参照してください。

draw()に電話するたびに、それは何度も繰り返し呼び出されます。 keydownイベントから呼び出すと、頻繁に2倍、2度目に3回頻繁に呼び出します。

あなたの目的が何であるかは完全には分かりませんが、

function draw(x_move, y_move) { 
    requestAnimationFrame(function() { 
    draw(x_move, y_move); 
    }); 
    ctx.beginPath(); 
    ctx.rect(x, y, 20, 20); 
    ctx.clearRect(0, 0, canvas.width, canvas.height); 
    ctx.fillStyle = "#ffffff"; 
    ctx.fill(); 
    ctx.closePath(); 
    x = x + x_move; 
    y = y + y_move + downwardTrajectory; 
} 
+0

ありがとう、これについて知っておいてよかった! –

0

keyboardEvent.keyCode減価償却資産です。 keyboardEvent.codeまたはkeyboardEvent.keyを使用して、キーコードを覚えようとするよりもはるかに管理しやすい名前付きキーを提供する必要があります。

rectではなくfillRectを使用できます。beginPathfillを使用する必要はありません。closePathを使用する必要はありません。形状を閉じる(つまり、最後の点から最初の行に行を追加する)場合にのみ使用します。rectは既に閉じています

コールバックを引数として直接設定できます​​

関連するデータをまとめてグループ化することができます。この場合、正方形は、位置がx,yであり、デルタ位置(x_move,y_move)がオブジェクト内でより良い位置にあります。関連するデータがあることを示す良い例は、同じ名前を一連の変数に追加することです。オブジェクトはまたdrawupdate

const canvas = document.getElementById('canvas'); 
const ctx = canvas.getContext('2d'); 

// list of named keys to record state of 
const keys = { 
    ArrowDown: false, 
}; 
// create key event listeners 
document.addEventListener('keydown', keyEvent); 
document.addEventListener('keyup', keyEvent); 

// define the square 
const square = { 
    x : 0, // position 
    y : 0, 
    dx : 0, // delta pos 
    dy : 0, 
    draw() { // function to render the square 
     ctx.fillStyle = "#ffffff"; 
     ctx.fillRect(this.x, this.y, 20, 20); 
    }, 
    update() { // function to update square 
     if(keys.ArrowDown){ 
      this.dx = 0; 
      this.dy = 1; 
     }else { 
      this.dx = 1; 
      this.dy = 0; 
     } 
     this.x += this.dx; 
     this.y += this.dy; 
    } 
} 

// main animation update function called once per frame 1/60th second 
function update() { 
    requestAnimationFrame(update); 
    ctx.clearRect(0, 0, canvas.width, canvas.height); 
    square.update(); 
    square.draw(); 
} 

// key event records named key state (false up, true down) 
function keyEvent (event) { 
    if(keys[event.code] !== undefined){ 
     keys[event.code] = event.type === "keydown"; 
    } 
} 
関連する問題