使用 setinterval 和 settimeout 时乒乓球拍滴答作响
pong paddles ticking when using setinterval and settiomeout
所以我正在尝试创建一个乒乓球游戏,乒乓球的拍子很响..
我正在为球和球拍使用两个功能,我也在使用 canvas
运动有桨叶对象和事件监听器
请帮助:)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Pong</title>
<script type="text/javascript">
function canvas() {
var can = document.getElementById('theCanvas');
can.style.backgroundColor = "black";
var ctx = can.getContext('2d');
var keys = [];
var ball = {
x: (can.width-10)/2,
y: (can.width-10)/2,
dx: 8,
dy: 8
}
var playerOne = {
x: can.width-50,
y: (can.width-50)/2,
H: 100,
W: 20,
hitDir: 0
}
var playerTwo = {
x: 50,
y: (can.width-50)/2,
H: 100,
W: 20,
hitDir: 0
}
ctx.fillStyle ="white";
ctx.fillRect(playerOne.x,playerOne.y,playerOne.W,playerOne.H);
ctx.fillRect(playerTwo.x,playerTwo.y,playerTwo.W,playerTwo.H);
function draw()
{
ctx.clearRect(0,0, 800,800);
ctx.beginPath();
ctx.fillStyle="#0000ff";
ctx.arc(ball.x,ball.y,10,0,Math.PI*2,true);
ctx.closePath();
ctx.fill();
if( ball.x<10 || ball.x>790)
{
ball.dx=-ball.dx
}
if( ball.y<10 || ball.y>790) {
ball.dy=-ball.dy
}
ball.x+=ball.dx;
ball.y+=ball.dy;
ctx.fillStyle ="white";
ctx.fillRect(playerOne.x,playerOne.y,playerOne.W,playerOne.H);
ctx.fillRect(playerTwo.x,playerTwo.y,playerTwo.W,playerTwo.H);
}
setInterval(draw,10);
function move() {
ctx.clearRect(0,0,800,800);
if (keys[38]) {
playerTwo.y-=10;
}
if (keys[40]) {
playerTwo.y+=10;
}
ctx.fillStyle ="white";
ctx.fillRect(playerOne.x,playerOne.y,playerOne.W,playerOne.H);
ctx.fillRect(playerTwo.x,playerTwo.y,playerTwo.W,playerTwo.H);
ctx.clearRect(0,0, 800,800);
ctx.beginPath();
ctx.fillStyle="#0000ff";
ctx.arc(ball.x,ball.y,10,0,Math.PI*2,true);
ctx.closePath();
ctx.fill();
setTimeout(move, 1000/60);
}
move();
document.body.addEventListener("keydown", function (e) {
keys[e.keyCode] = true;
});
document.body.addEventListener("keyup", function (e) {
keys[e.keyCode] = false;
});
}
</script>
</head>
<body onload="canvas()">
<canvas id="theCanvas" width="800" height="800"></canvas>
</body>
</html>
感谢您提出有趣的问题。
您要做的是将两个 setInterval/setTimeout 组合成一个渲染函数。然后由单个 window.requestAnimationFrame 函数使用,当浏览器准备好绘制下一帧时调用该函数。这优于 setTimeout 或 setInterval,这可能是 "ticking" 的原因,因为您的 canvas 可能在浏览器尚未准备好呈现该帧时尝试绘制该帧。
我也将您的游戏重构为以下伪代码
1) Set up the canvas and event listeners
2) Declare the render function
2a) Change the position data of the ball & paddles
2b) Render the ball & paddles based on its data
2c) request another animation frame
3) request an animation frame with the render function
所以我正在尝试创建一个乒乓球游戏,乒乓球的拍子很响.. 我正在为球和球拍使用两个功能,我也在使用 canvas 运动有桨叶对象和事件监听器 请帮助:)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Pong</title>
<script type="text/javascript">
function canvas() {
var can = document.getElementById('theCanvas');
can.style.backgroundColor = "black";
var ctx = can.getContext('2d');
var keys = [];
var ball = {
x: (can.width-10)/2,
y: (can.width-10)/2,
dx: 8,
dy: 8
}
var playerOne = {
x: can.width-50,
y: (can.width-50)/2,
H: 100,
W: 20,
hitDir: 0
}
var playerTwo = {
x: 50,
y: (can.width-50)/2,
H: 100,
W: 20,
hitDir: 0
}
ctx.fillStyle ="white";
ctx.fillRect(playerOne.x,playerOne.y,playerOne.W,playerOne.H);
ctx.fillRect(playerTwo.x,playerTwo.y,playerTwo.W,playerTwo.H);
function draw()
{
ctx.clearRect(0,0, 800,800);
ctx.beginPath();
ctx.fillStyle="#0000ff";
ctx.arc(ball.x,ball.y,10,0,Math.PI*2,true);
ctx.closePath();
ctx.fill();
if( ball.x<10 || ball.x>790)
{
ball.dx=-ball.dx
}
if( ball.y<10 || ball.y>790) {
ball.dy=-ball.dy
}
ball.x+=ball.dx;
ball.y+=ball.dy;
ctx.fillStyle ="white";
ctx.fillRect(playerOne.x,playerOne.y,playerOne.W,playerOne.H);
ctx.fillRect(playerTwo.x,playerTwo.y,playerTwo.W,playerTwo.H);
}
setInterval(draw,10);
function move() {
ctx.clearRect(0,0,800,800);
if (keys[38]) {
playerTwo.y-=10;
}
if (keys[40]) {
playerTwo.y+=10;
}
ctx.fillStyle ="white";
ctx.fillRect(playerOne.x,playerOne.y,playerOne.W,playerOne.H);
ctx.fillRect(playerTwo.x,playerTwo.y,playerTwo.W,playerTwo.H);
ctx.clearRect(0,0, 800,800);
ctx.beginPath();
ctx.fillStyle="#0000ff";
ctx.arc(ball.x,ball.y,10,0,Math.PI*2,true);
ctx.closePath();
ctx.fill();
setTimeout(move, 1000/60);
}
move();
document.body.addEventListener("keydown", function (e) {
keys[e.keyCode] = true;
});
document.body.addEventListener("keyup", function (e) {
keys[e.keyCode] = false;
});
}
</script>
</head>
<body onload="canvas()">
<canvas id="theCanvas" width="800" height="800"></canvas>
</body>
</html>
感谢您提出有趣的问题。
您要做的是将两个 setInterval/setTimeout 组合成一个渲染函数。然后由单个 window.requestAnimationFrame 函数使用,当浏览器准备好绘制下一帧时调用该函数。这优于 setTimeout 或 setInterval,这可能是 "ticking" 的原因,因为您的 canvas 可能在浏览器尚未准备好呈现该帧时尝试绘制该帧。
我也将您的游戏重构为以下伪代码
1) Set up the canvas and event listeners
2) Declare the render function
2a) Change the position data of the ball & paddles
2b) Render the ball & paddles based on its data
2c) request another animation frame
3) request an animation frame with the render function