2016-10-01 90 views
1

我正在製作一個簡單的空間遊戲,其中一艘船左右移動以躲避小行星。如何使用箭頭鍵在畫布中平滑移動對象

我學會了將我的船從this video左右移動。

但是,這個動作很塊。我如何順利移動船?

這裏是我的所有代碼:

// JavaScript Document 
 

 
////// Variables ////// 
 
var canvas = {width:300, height:300 }; 
 
var score = 0; 
 

 
var player = { 
 
\t x:canvas.width/2, 
 
\t y:canvas.height-100, 
 
\t speed: 20 
 
}; 
 

 

 

 

 
////// Arrow keys ////// 
 

 
function move(e) { 
 
\t 
 
\t if(e.keyCode == 37) { 
 
\t \t player.x -= player.speed; 
 
\t } 
 
\t if(e.keyCode == 39) { 
 
\t \t player.x += player.speed; \t 
 
\t } 
 
\t 
 
\t update(); 
 
\t 
 
} 
 

 
document.onkeydown = move; 
 

 

 

 
////// other functions ////// 
 

 

 
//function to clear canvas 
 
function clearCanvas() { 
 
\t ctx.clearRect(0,0,canvas.width,canvas.height); 
 
} 
 

 
// Draw Player ship. 
 
function ship(x,y) { 
 
\t var x = player.x; 
 
\t var y = player.y; 
 
\t ctx.fillStyle = "#FFFFFF"; 
 

 
\t ctx.beginPath(); 
 
    ctx.moveTo(x,y); 
 
    ctx.lineTo(x+15,y+50); 
 
    ctx.lineTo(x-15,y+50); 
 
    ctx.fill(); 
 
} 
 

 
// update 
 

 
setInterval (update, 50); 
 

 
function update() { 
 
\t clearCanvas(); 
 
\t ship(); 
 
}
<!doctype html> 
 
<html> 
 
<head> 
 
<meta charset="UTF-8"> 
 
<title>My Game</title> 
 

 
<script src="game-functions.js"></script> 
 
     
 
</head> 
 

 
<body> 
 

 
<canvas id="ctx" width="300" height="300" style="border: thin solid black; background-color: black;"></canvas> 
 
<br> 
 

 

 
<script> 
 
////// Canvas setup ////// 
 
var ctx = document.getElementById("ctx").getContext("2d"); 
 

 

 

 
</script> 
 

 
</body> 
 
</html>

+1

的可能的複製【正文動畫不流暢(http://stackoverflow.com/questions/32365542/body-animation-isnt-smooth) – Kaiido

+0

一般情況下,你的動作如果更頻繁地進行更小的移動(更小的'player.speed')(時間間隔1000/60 = 16.67),將會更平滑。考慮學習[requestAnimationFrame](https://www.paulirish。com/2011/requestanimationframe-for-smart-animating /)這是一個更好的動畫定時循環。 – markE

回答

0
  1. 使用requestAnimationFrame
  2. 不要把update(你渲染)使用keyUp keyDown事件處理程序內
  3. 進行布爾變量(每個directio一個),並將其設置爲keuDown上的true和到false上使用keyUp和內部的渲染功能添加一個簡單的if檢查

TL; DR

讓你的生活變得更加簡單。

您可能需要使用event.key,而不是返回鍵名稱('a','Esc','Space'等),如果您不在鍵碼旁邊放置註釋,則使其更具可讀性。

+2

良好的一般性建議,但由於OP是JavaScript和遊戲開發的新手,您可能需要擴展答案以填補答案和經驗之間的差距。 ;-) – markE

4

這是因爲​​觸發事件相似性,鍵盤將鍵入記事本,因爲它會觸發一旦有一個輕微的延遲,他們會觸發更多的定時器。

由於@Azamantes表示要解決這個,你會希望它被設置爲true上​​和falsekeyup一個布爾值。然後,您將使用主要事件循環與setTimeout/setInterval和/或​​。在下面的例子中,我只是用setInterval爲簡單起見,主循環,因爲你已經擁有了它,我們就可以移動move()成主循環:


注:爲了實現​​看到@坊間的評論這個問題。

另外​​會默認刷新。換句話說,如果您需要控制FPS,那麼您需要添加更多邏輯,這在HTML5遊戲中可能很常見。對於使用受控FPS的​​,請參見this answer

// JavaScript Document 
 

 
////// Variables ////// 
 
var canvas = {width:300, height:300 }; 
 
var score = 0; 
 

 
var player = { 
 
\t x:canvas.width/2, 
 
\t y:canvas.height-100, 
 
\t speed: 3 
 
}; 
 

 
var LEFT = false; 
 
var RIGHT = false; 
 

 

 
////// Arrow keys ////// 
 

 
function move() { 
 
\t 
 
\t if(LEFT) { 
 
\t \t player.x -= player.speed; 
 
\t } 
 
\t if(RIGHT) { 
 
\t \t player.x += player.speed; \t 
 
\t } 
 
\t 
 
} 
 

 
document.onkeydown = function(e) { 
 
\t if(e.keyCode == 37) LEFT = true; 
 
\t if(e.keyCode == 39) RIGHT = true; 
 
} 
 

 
document.onkeyup = function(e) { 
 
\t if(e.keyCode == 37) LEFT = false; 
 
\t if(e.keyCode == 39) RIGHT = false; 
 
} 
 

 

 
////// other functions ////// 
 

 

 
//function to clear canvas 
 
function clearCanvas() { 
 
\t ctx.clearRect(0,0,canvas.width,canvas.height); 
 
} 
 

 
// Draw Player ship. 
 
function ship(x,y) { 
 
\t var x = player.x; 
 
\t var y = player.y; 
 
\t ctx.fillStyle = "#FFFFFF"; 
 

 
\t ctx.beginPath(); 
 
    ctx.moveTo(x,y); 
 
    ctx.lineTo(x+15,y+50); 
 
    ctx.lineTo(x-15,y+50); 
 
    ctx.fill(); 
 
} 
 

 
// update 
 

 
setInterval (update, 10); 
 

 
function update() { 
 
\t clearCanvas(); 
 
\t ship(); 
 
    move(); 
 
}
<!doctype html> 
 
<html> 
 
<head> 
 
<meta charset="UTF-8"> 
 
<title>My Game</title> 
 

 
<script src="game-functions.js"></script> 
 
     
 
</head> 
 

 
<body> 
 

 
<canvas id="ctx" width="300" height="300" style="border: thin solid black; background-color: black;"></canvas> 
 
<br> 
 

 

 
<script> 
 
////// Canvas setup ////// 
 
var ctx = document.getElementById("ctx").getContext("2d"); 
 

 

 

 
</script> 
 

 
</body> 
 
</html>

+0

'requestAnimationFrame會盡可能的刷新它的默認值',nope,這是rAF的重點,在屏幕刷新率時它將被稱爲** only **。 – Kaiido

+0

@Kaiido是的,我的意思是它會像屏幕刷新速度一樣快。這就是'requestAnimationFrame'的要點,爲什麼它不容易控制它的FPS –

相關問題