简体   繁体   English

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

[英]How do I move the paddle in Breakout using Javascript - when I've drawn the paddle using lineTo and moveTo?

I'm currently trying to make a version of Breakout for university. 我目前正在尝试制作大学版Breakout。 Thanks for helping me to draw the paddle. 感谢您帮助我画桨。 I now find myself unable to cause the ball to bounce on the edge of the canvas - except in the middle. 现在,我发现自己无法使球在画布边缘反弹(中间除外)。 I've tried both adding and subtracting fractions to ball.x and ball.y (greater than or equal to canvas.width and canvas.height both work) but for less than or equal to 0, nothing seems to be successful. 我已经尝试过在ball.x和ball.y中添加和减去分数(大于或等于canvas.width和canvas.height都可以工作),但是对于小于或等于0的情况,似乎没有成功。 Here's the javascript code: 这是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);

Thanks for taking the time to read this --ConfusedStudent 感谢您抽出宝贵的时间阅读--ConfusedStudent

There is a number of issues with the paddle. 桨板存在许多问题。

First of all you probably want it to be of a fixed size, so let's define its dimensions at the beginning of the file (put it after the first two lines of your code because it uses the canvas to set the paddle width to 1/5th of its width - I think that's what you tried to do): 首先,您可能希望它的大小固定,因此让我们在文件的开头定义其尺寸(将其放在代码的前两行之后,因为它使用canvas将桨叶宽度设置为1/5的宽度-我认为这就是您尝试做的事情:

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

With this you can initialize the paddle to be at the bottom of the canvas and in the middle: 这样,您可以将桨叶初始化为位于画布的底部和中间:

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

x and y are the top-left corner of the paddle, so the right side is at x + PADDLE_WIDTH_PX and the bottom side is at y + PADDLE_HEIGHT_PX . xy是球拍的左上角,因此右侧是x + PADDLE_WIDTH_PX ,而底端是y + PADDLE_HEIGHT_PX
Knowing this, you can draw a path throught all the four corners like this: 知道了这一点,您可以像这样通过所有四个角绘制一条路径:

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();

But since the paddle is just a rectangle, it's easier to use a method for drawing rectangles - fillRect , like this: 但是由于桨只是一个矩形,所以使用绘制矩形的方法更容易fillRect ,如下所示:

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

Either way, all the four corners of the paddle move toggether so it doesn't grow or shrink. 无论哪种方式,桨的所有四个角都一起移动,因此它不会增长或收缩。

So if you put it in your render function, it looks like this: 因此,如果将其放在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);
}

The last thing is to get the paddle to move when the left and right arrow keys are pressed. 最后一件事是在按左右箭头键时使桨叶移动。

The paddle only moves when either arrow left or arrow right is pressed. 仅当按下向左箭头或向右箭头时,桨叶才会移动。 Otherwise its speed is 0 and it sits in its place. 否则,它的速度为0,并且位于其位置。 Therefore the paddle object doesn't need the xSpeed member variable. 因此, paddle对象不需要xSpeed成员变量。
Also, the paddle only moves horizontally so only its x variable changes, y is always the same. 同样,桨仅水平移动,因此只有x变量改变, y始终相同。

Let's first define the speed of the paddle at the beginning of the file: 首先让我们在文件开头定义桨的速度:

var PADDLE_SPEED = 300;

and then let's put the movement logic in the update function: 然后将移动逻辑放在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;

You can notice that the paddle position is only changed if an arrow key is pressed and the paddle is not at the edge. 您会注意到,仅当按下箭头键并且桨叶不在边缘时,桨叶位置才会更改。

All the other code that deals with the paddle should be removed from the update function so that it looks like this (I have removed most of the comments): 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;
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我如何在js中进行桨移动 - How do I make a paddle move in js 如何为JavaScript变量分配坐标,并使用moveTo和lineTo在这些变量周围绘制线? - How can I assign a coordinate to a javascript variable, and draw lines using moveTo and lineTo around these variables? 如何使用桨键使图像在 JavaScript 中移动? - How to make an image moving in JavaScript using paddle keys? JavaScript Breakout-基于球击中桨的水平运动 - JavaScript Breakout - Ball horizontal motion based on where it hits the paddle 击球时如何让球跑得更快? - How to make the ball move faster when it hits paddle? 为什么我在JavaScript中使用moveTo会出错? - Why do I get an error using moveTo in JavaScript? 如何为左桨打开AI时无法纠正右桨的错误? Canvs Javascript中的Pong游戏 - How to fix bug where right paddle doesn't work when AI is switched on for left paddle? Pong game in canvs javascript 在JavaScript中浏览Mozilla突破教程,但由于某种原因我的桨没有被绘制,为什么会这样? - working through the Mozilla breakout tutorial in JavaScript but for some reason my paddle isn't being draw why is this? Codepen,Javascript,如何将keyCode上下添加到paddle - Codepen, Javascript, how to add keyCode up and down to paddle 添加额外的球 object 我每打桨 Canvas - Add extra ball object every tiume i hit paddle Canvas
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM