我正在研究HTML5和JS的赛车游戏。我正试图用箭头键移动汽车。但它不起作用。
如何在画布中移动元素,是否需要在移动元素之前清除整个画布窗口?
代码:
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var yCoordinate = 115;
var canvasWidth = canvas.width;
var canvasHeight = canvas.height;
var distance = 10;
var speed = 0.5;
var angle = 25;
var car = new Image();
car.src = "./images/p1.png";
startGame();
function startGame(){
requestAnimationFrame(moveLane);
}
function moveLane(){
clearCanvas();
drawCar();
drawLane(10 - yCoordinate);
drawLane(60 - yCoordinate);
drawLane(110 - yCoordinate);
//speed of the lane
yCoordinate = yCoordinate - 0.4;
//if lane crossed the bottom boundrary then reset the y co-ordinate
if (yCoordinate <= -145){
yCoordinate = 115;
}
requestAnimationFrame(moveLane);
}
function drawCar(){
context.drawImage(car, canvasWidth/2, canvasHeight/4, car.width*0.4, car.height*0.13);
setCarControls();
}
function moveCarLeft(){
clearCanvas();
var x = canvasWidth/2 - distance;
context.drawImage(car, x, canvasHeight/4, car.width*0.4, car.height*0.13);
}
function drawLane(yCoordinate){
context.fillStyle = "#ffffff";
context.fillRect(canvasWidth/2, yCoordinate, 10, 20);
}
function clearCanvas(){
context.clearRect(0, 0, canvasWidth, canvasHeight);
}
function setCarControls() {
document.addEventListener('keydown', function(e){
switch(e.keyCode){
case 37:
console.log('left');
requestAnimationFrame(moveCarLeft);
break;
case 38:
console.log('up');
break;
case 39:
console.log('right');
break;
case 40:
console.log('down');
break;
}
});
}
答案 0 :(得分:1)
我已经更新了小提琴。校验。您没有使用动态x坐标。
https://jsfiddle.net/6j4c5dod/7/
function moveCarLeft(){
clearCanvas();
currentX = currentX - 0.1;
context.drawImage(car, currentX, canvasHeight/4, car.width*0.4, car.height*0.13);
}
答案 1 :(得分:1)
以下是我的更新演示,了解如何执行此操作:https://jsfiddle.net/mulperi/1daahhap/
游戏的基本思路(通常)是更新功能(游戏循环)和绘制功能。 更新功能是您使用requestAnimationFrame()调用的函数,它包含游戏中需要更新的所有不同内容,例如Player.update()等。 另一方面,绘图功能负责用ctx.clearRect()清除屏幕,然后播放Player.draw()和类似的东西。
在我的示例中,播放器移动是通过监听keydown和keyup并根据键盘上发生的事情将变量切换为true / false来完成的。 Player.update -function仅检查变量并在按下键时移动(例如ArrowLeft)。
完整代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>World's BEstest Game</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<canvas id="canvas" style="border:1px solid black;">
</canvas>
<script>
const c = document.getElementById("canvas");
const ctx = c.getContext("2d");
/*
TODO: Change player to Class based object
*/
keyPresses = {};
player = {
x: 100,
y: 100,
update: () => {
if (keyPresses['ArrowLeft']) {
player.x -= 1;
}
if (keyPresses['ArrowRight']) {
player.x += 1;
}
if (keyPresses['ArrowUp']) {
player.y -= 1;
}
if (keyPresses['ArrowDown']) {
player.y += 1;
}
},
draw: () => {
ctx.fillStyle = "black";
ctx.beginPath();
ctx.arc(player.x, player.y, 10, 0, Math.PI * 2, false);
ctx.closePath();
ctx.fill();
}
};
function listenKeyboard() {
document.addEventListener("keyup", keyUp.bind(this));
document.addEventListener("keydown", keyDown.bind(this));
};
function keyUp(e) {
keyPresses[e.key] = false;
};
function keyDown(e) {
console.log(e.key)
keyPresses[e.key] = true;
};
/*
Everything drawing and graphics related goes here and also
clearing the screen before drawing each frame.
*/
function draw() {
ctx.clearRect(0, 0, 300, 300);
player.draw();
};
/*
All the update methods go here
*/
function update() {
draw();
listenKeyboard();
player.update();
requestAnimationFrame(update);
};
requestAnimationFrame(update);
</script>
</body>
</html>
所以我希望这可以帮助你思考游戏功能的结构,让它更容易阅读和理解,也许会给你一些灵感!快乐的编码:)
答案 2 :(得分:-1)
我认为你有3个选择:
我真的会选择多个画布(对于不像背景天空那样改变的东西,画一次),因为保存/恢复也可能是昂贵的操作。