gpt4 book ai didi

javascript - 当我使用 lineTo 和 moveTo 绘制桨时,如何使用 Javascript 在 Breakout 中移动桨?

转载 作者:行者123 更新时间:2023-11-28 07:26:36 26 4
gpt4 key购买 nike

我目前正在尝试制作大学版的 Breakout。谢谢你帮我画桨。我现在发现自己无法使球在 Canvas 边缘弹跳 - 除了中间。我尝试过对 ball.x 和 ball.y 添加和减去分数(大于或等于 canvas.width 和 canvas.height 都有效),但对于小于或等于 0,似乎没有成功。这是 JavaScript 代码:

    var canvas = document.getElementById("breakout");
var ctx = canvas.getContext("2d");
var PADDLE_WIDTH_PX = canvas.width / 5;
var PADDLE_HEIGHT_PX = 10;
var PADDLE_SPEED = 450;

var ball = {
x: canvas.width / 2, //pixels
y: canvas.height / 2, //pixels
xSpeed: 500, //pixels per second
ySpeed: 500, //pixels per second
radius: 100 //the ball is exceptionally large so that I can see what part of the ball is surpassing the canvas edge before the motion is reversed
}

var paddle = {
//radius: 5,
/*speed: 500,
TopRight: ctx.moveTo(canvas.width / 1.35, canvas.height - (canvas.height / 12.5)),
TopSide: ctx.lineTo(canvas.width / 2, canvas.height - (canvas.height / 12.5)),
RightSide: ctx.lineTo(canvas.width / 1.35, canvas.height - (canvas.height / 27.5)),
BottomLeft: ctx.moveTo(canvas.width / 2, canvas.height - (canvas.height / 27.5)),
LeftSide: ctx.lineTo(canvas.width / 2, canvas.height - (canvas.height / 12.5)),
BottomSide: ctx.lineTo(canvas.width / 1.35, canvas.height - (canvas.height / 27.5))*/
xSpeed: 450,
x: (canvas.width - PADDLE_WIDTH_PX) / 2,
y: canvas.height - PADDLE_HEIGHT_PX
}

var keysDown = {};
window.addEventListener("keydown",function(e) {
keysDown[e.keyCode] = true;
});
window.addEventListener("keyup",function(e) {
delete keysDown[e.keyCode];
});


function render() {
//clear the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height)
// draw the ball
ctx.fillStyle = "white";
ctx.beginPath();
ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
ctx.beginPath();
//ctx.fillStyle = "red";
/*ctx.moveTo(canvas.width - (2*paddle.x), canvas.height - (2*paddle.y));
/*ctx.lineTo(canvas.width / 2, canvas.height - (canvas.height / 12.5));
ctx.lineTo(canvas.width / 1.35, canvas.height - (canvas.height / 27.5));
ctx.moveTo(canvas.width / 2, canvas.height - (canvas.height / 27.5));
ctx.lineTo(canvas.width / 2, canvas.height - (canvas.height / 12.5));
ctx.lineTo(canvas.width / 1.35, canvas.height - (canvas.height / 27.5));
ctx.fill();
ctx.closePath();*/
/*ctx.lineTo(canvas.width - (2*paddle.x), canvas.height - paddle.y);
ctx.moveTo(canvas.width - paddle.x, canvas.height - paddle.y);
ctx.lineTo(canvas.width - paddle.x, canvas.height - (2*paddle.y));
ctx.lineTo(canvas.width - (2*paddle.x), (canvas.height -paddle.y));*/
ctx.fillRect(paddle.x, paddle.y, PADDLE_WIDTH_PX, PADDLE_HEIGHT_PX);
/*ctx.closePath();
ctx.fill();*/
}

function update(elapsed) {
//update the ball position according to the elapsed time
ball.y += ball.ySpeed * elapsed;
ball.x += ball.xSpeed * elapsed;
/*paddle.TopRight += paddle.speed * elapsed;
paddle.BottomLeft += paddle.speed * elapsed;
paddle.RightSide += paddle.speed * elapsed;
paddle.LeftSide += paddle.speed * elapsed;
paddle.TopSide += paddle.speed * elapsed;
paddle.BottomSide += paddle.speed * elapsed;*/
/*paddle.x += paddle.xSpeed * elapsed;
paddle.y += paddle.xSpeed * elapsed;*/

//bounce the ball of all edges
if (37 in keysDown && paddle.x > 0)
paddle.x -= PADDLE_SPEED * elapsed;
if (39 in keysDown && paddle.x + PADDLE_WIDTH_PX < canvas.width)
paddle.x += PADDLE_SPEED * elapsed;

if (ball.x+(ball.x/7) >= canvas.width) {
ball.x -= 5;
ball.xSpeed *= -1;
}
if (ball.x-(ball.x/7) <= 0) {
ball.x += 5;
ball.xSpeed *= -1;
}
if (ball.y+(ball.y/100) <= 0) {
ball.y += 5;
ball.ySpeed *= -1;
}
if (ball.y+(ball.y/3) >= canvas.height) {
ball.y -= 5;
ball.ySpeed *= -1;
}

/*
The problem here is that sometimes the ball gets 'stuck' to an edge.

This can occur when the ball passes beyond an edge in a frame when the
elapsed time is relatively large. In some cases, when the elapsed time in the
next frame is relatively short, the ball doesn't reach the edge to get back
into play. This results in another flip of the velocity and the ball becomes
'trapped' on the edge.

e.g.
xSpeed = -500, x = 10, elapsed = 0.2 => xSpeed = 500, x = -90 (xMovement = -100)
xSpeed = 500, x = -90, elapsed = 0.1 => xSpeed = -500, x = -40 (xMovement = +50)
xSpeed = -500, x = -40, elapsed = 0.1 => xSpeed = 500, x = -40 (xMovement = -50)
and so on ...until a larger elapsed time occurs in the right direction

The fix for this is to move the ball to the edge when the velocity is flipped.
*/
}

var previous;
function run(timestamp) {
if (!previous) previous = timestamp; //start with no elapsed time
var elapsed = (timestamp - previous) / 1000; //work out the elapsed time
update(elapsed); //update the game with the elapsed time
render(); //render the scene
previous = timestamp; //set the (globally defined) previous timestamp ready for next time
window.requestAnimationFrame(run); //ask browser to call this function again, when it's ready
}

//trigger the game loop
window.requestAnimationFrame(run);

感谢您花时间阅读本文--困惑的学生

最佳答案

桨存在许多问题。

首先,您可能希望它具有固定大小,所以让我们定义它的尺寸位于文件的开头(将其放在代码的前两行之后,因为它使用 canvas 将桨宽度设置为其宽度的 1/5 - 我认为这就是您尝试过的要做的事):

var PADDLE_WIDTH_PX = canvas.width / 5;
var PADDLE_HEIGHT_PX = 10;

通过这个,您可以将桨初始化为位于 Canvas 的底部和中间:

var paddle = {
x: (canvas.width - PADDLE_WIDTH_PX) / 2,
y: canvas.height - PADDLE_HEIGHT_PX
}

xy 是桨的左上角,因此右侧位于 x + PADDLE_WIDTH_PX 处,底部位于位于 y + PADDLE_HEIGHT_PX
知道了这一点,您可以画一条穿过所有四个 Angular 的路径,如下所示:

ctx.beginPath();
ctx.moveTo(paddle.x, paddle.y);
ctx.lineTo(paddle.x + PADDLE_WIDTH_PX, paddle.y);
ctx.lineTo(paddle.x + PADDLE_WIDTH_PX, paddle.y + PADDLE_HEIGHT_PX);
ctx.lineTo(paddle.x, paddle.y + PADDLE_HEIGHT_PX);
ctx.lineTo(paddle.x, paddle.y);
ctx.closePath();

但是由于桨只是一个矩形,所以使用绘制矩形的方法更容易 - fillRect,如下所示:

ctx.fillRect(paddle.x, paddle.y, PADDLE_WIDTH_PX, PADDLE_HEIGHT_PX);

无论哪种方式,桨的所有四个 Angular 都会一起移动,因此它不会增大或缩小。

因此,如果将其放入 render 函数中,它看起来像这样:

function render() {
//clear the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height)
// draw the ball
ctx.fillStyle = "white";
ctx.beginPath();
ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();

// draw the paddle
ctx.fillStyle = "red";
ctx.fillRect(paddle.x, paddle.y, PADDLE_WIDTH_PX, PADDLE_HEIGHT_PX);
}

最后一件事是让桨在按下左右箭头键时移动。

只有按下向左箭头或向右箭头时,桨才会移动。否则它的速度是 0 并且它坐在它的位置上。因此 paddle 对象不需要 xSpeed 成员变量。
此外,桨仅水平移动,因此只有其 x 变量发生变化,y 始终相同。

我们首先在文件开头定义桨的速度:

var PADDLE_SPEED = 300;

然后让我们将移动逻辑放入update函数中:

if (37 in keysDown && paddle.x > 0)
paddle.x -= PADDLE_SPEED * elapsed;
else if (39 in keysDown && paddle.x + PADDLE_WIDTH_PX < canvas.width)
paddle.x += PADDLE_SPEED * elapsed;

您可以注意到,仅当按下箭头键且桨叶不在边缘时,桨叶位置才会发生变化。

所有其他处理paddle的代码都应该从update函数中删除,这样它看起来像这样(我已经删除了大部分注释):

function update(elapsed) {
//update the ball position according to the elapsed time
ball.y += ball.ySpeed * elapsed;
ball.x += ball.xSpeed * elapsed;

if (37 in keysDown && paddle.x > 0)
paddle.x -= PADDLE_SPEED * elapsed;
else if (39 in keysDown && paddle.x + PADDLE_WIDTH_PX < canvas.width)
paddle.x += PADDLE_SPEED * elapsed;

//bounce the ball of all edges
if/*(*/(ball.x /*- (ball.x / 2))*/<= 0) {
ball.x = 1;
ball.xSpeed *= -1;
}
if /*(*/(ball.x /*+ (ball.x / 2))*/>= canvas.width) {
ball.x = ball.x -1;
ball.xSpeed *= -1;
}
if/*(*/(ball.y /*- (ball.y / 2))*/<= 0) {
ball.y = 1;
ball.ySpeed *= -1;
}
if /*(*/(ball.y /*+ (ball.y / 2))*/>= canvas.height) {
ball.y = ball.y -1;
ball.ySpeed *= -1;
}
}

关于javascript - 当我使用 lineTo 和 moveTo 绘制桨时,如何使用 Javascript 在 Breakout 中移动桨?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29588091/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com