我目前正在尝试学习JavaScript并遵循编程Breakout游戏的教程。我在教程后添加了一些内容。我添加的一件事是随着比赛的进行,球会变得更快。现在我有以下问题。
我的球拍厚度为10px,但在某些时候球的移动速度超过每帧10px /更新。因此,它经常直接通过从其反弹的桨叶。我已经将FPS / UPS从60加倍到120,并将球速除以2.
当然我可以进一步增加fps,但我希望有更高效/优雅版本的handeling这个问题。
这是我用来让球从球拍上反弹的功能:
function ballPaddleHandling() {
var paddleTopEdgeY = canvas.height-PADDLE_DIST_FROM_EDGE;
var paddleBottomEdgeY = paddleTopEdgeY + PADDLE_THICKNESS;
var paddleLeftEdgeX = paddleX;
var paddleRightEdgeX = paddleLeftEdgeX + PADDLE_WIDTH;
if( ballY > paddleTopEdgeY && // below the top of paddle
ballY < paddleBottomEdgeY && // above bottom of paddle
ballX > paddleLeftEdgeX && // right of the left side of paddle
ballX < paddleRightEdgeX) { // left of the left side of paddle
ballSpeedY *= -1;
var centerOfPaddleX = paddleX+PADDLE_WIDTH/2;
var ballDistFromPaddleCenterX = ballX - centerOfPaddleX;
ballSpeedX = ballDistFromPaddleCenterX * 0.35;
if(bricksLeft == 0) {
gameWon = true;
//brickReset();
} // out of bricks
} // ball center inside paddle
} // end of ballPaddleHandling
如果您想查看我的所有代码,可以在此处执行此操作:https://jpst.it/1cHKn
答案 0 :(得分:1)
也许你的问题是:当你把球放在新位置时,新的坐标位于球拍下方,从一帧到另一帧,所以球从未通过球拍,它只是在帧之间传送到桨之后。
也许你需要:评估球的轨迹,当检测到球将在桨Y位置之后,从一帧到另一帧,检查桨是否在中间轨迹并将球放在桨叶上限的新位置
答案 1 :(得分:1)
您可以使用光线命中测试。 为了简化它,您只需测试桨的上表面。
function ballPaddleHandling() {
var paddleTopEdgeY = canvas.height-PADDLE_DIST_FROM_EDGE;
// calculate balls previous position
var px = ballX - ballSpeedX
var py = ballY - ballSpeedY
// calculate trajectory angle
var angle = getAngle(px,py,ballX,ballY)
// calulcate the length of the ray to test
var length = getDist(px,py,ballX,ballY)
// define the line to test as the upper face of the paddle
var line = {x:paddleX, y:paddleTopEdgeY, w:PADDLE_WIDTH}
// get position of hit, or false if no hit occured
var hit_x = rayHitTestHorizontalLine(px,py,angle,length,line)
if(hit_x!==false){
ballSpeedY *= -1;
var centerOfPaddleX = paddleX+PADDLE_WIDTH/2;
var ballDistFromPaddleCenterX = hit_x - centerOfPaddleX;
ballSpeedX = ballDistFromPaddleCenterX * 0.35;
}
}
function rayHitTestHorizontalLine(px,py,angle,length,line){
var dist = (line.y - py)/(-Math.cos(angle))
if(dist>length)
return false
var hit_x = px+Math.sin(angle)*dist
if(hit_x>=line.x && hit_x<=line.x+line.w)
return hit_x
else
return false
}
function getAngle(x1,y1,x2,y2){
return Math.atan2(y2-y1,x2-x1) + Math.PI/2
}
function getDist(x1,y1,x2,y2){
return Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1))
}
让我知道它是否有效,我自己无法真正测试它。