我最近做了一个JS Pong游戏。它运作良好,但球很少卡在底部或顶部。它看起来像在墙的中间并不断弹跳。 Video of the issue happening.您可以尝试游戏here。我不知道为什么会出现这个问题,因为逻辑似乎是正确的,并且90%的时间正确地工作。以下是我的程序的两个主要功能:
function moveAll() {
if (showingWinScreen) {
return;
}
computerMovement();
ballX += ballSpeedX;
ballY += ballSpeedY;
if (ballY <= 10) {
ballSpeedY = -ballSpeedY;
} else if (ballY >= HEIGHT - 10) {
ballSpeedY = -ballSpeedY;
}
if (ballX >= WIDTH - 10) {
if ((ballY > paddleY) && (ballY < paddleY + 100)) {
ballSpeedX = -ballSpeedX;
var deltaY = ballY - paddleY - 50;
ballSpeedY = deltaY / 5;
} else {
player1Score++;
ballReset();
}
} else if (ballX <= 10) {
if ((ballY > mouseY - 50) && (ballY < mouseY + 50)) {
ballSpeedX = -ballSpeedX;
deltaY = ballY - mouseY;
ballSpeedY = deltaY / 6;
} else {
player2Score++;
ballReset();
}
}
}
function drawAll() {
if (showingWinScreen) {
colorRect(0, 0, WIDTH, HEIGHT, "black");
canvas.fillStyle = "yellow";
canvas.fillText("Click to continue!", 300, 300);
if (player1Score == WINNING_SCORE) {
canvas.fillText("You won!", 360, 500);
} else if (player2Score == WINNING_SCORE) {
canvas.fillText("The computer beat you!", 280, 500);
}
return;
}
colorRect(0, 0, WIDTH, HEIGHT, "black");
drawNet();
makeCircle(ballX, ballY, 10, 0, Math.PI * 2, "red");
colorRect(790, paddleY, 10, 100, "cyan");
colorRect(0, mouseY - 50, 10, 100, "yellow");
canvas.fillStyle = "white";
canvas.fillText(player1Score + " " + player2Score, 360, 100);
}
感谢您的帮助!
答案 0 :(得分:2)
我认为只有一种情况可能发生:在碰撞框架中,当你降低速度时。
当速度保持不变时,无论如何,你的球总会反弹回到之前的状态。帧位置:
var cvs = document.querySelector("canvas");
var ctx = cvs.getContext("2d");
var balls = [
Ball(50, 50, 0, 5, 5, "red"),
Ball(100, 50, 0, 5, 10, "blue"),
Ball(150, 50, 0, 5, 15, "green"),
Ball(200, 50, 0, 5, 20, "yellow")
];
var next = () => {
updateFrame(balls);
drawFrame(balls);
}
var loop = () => {
requestAnimationFrame(() => {
next();
loop();
});
}
next();
function Ball(x, y, vx, vy, r, color) {
return {
x: x,
y: y,
vx: vx,
vy: vy,
r: r,
color: color
}
};
function updateBall(b) {
b.x += b.vx;
b.y += b.vy;
if (b.y <= b.r ||
b.y >= cvs.height - b.r) {
b.vy *= -1;
}
};
function drawBall(b) {
ctx.beginPath();
ctx.fillStyle = b.color;
ctx.arc(b.x, b.y, b.r, 0, 2 * Math.PI, false);
ctx.fill();
}
function updateFrame(balls) {
balls.forEach(updateBall);
}
function drawFrame(balls) {
ctx.clearRect(0, 0, cvs.width, cvs.height);
balls.forEach(drawBall);
};
&#13;
<canvas width="300" height="150" style="background: #454545"></canvas>
<button onclick="next()">next</button>
<button onclick="loop()">run</button>
&#13;
但是当速度发生变化时,事情就会陷入困境:
var cvs = document.querySelector("canvas");
var ctx = cvs.getContext("2d");
var balls = [
Ball(50, 50, 0, 10, 5, "red"),
Ball(100, 50, 0, 10, 10, "blue"),
Ball(150, 50, 0, 10, 15, "green"),
Ball(200, 50, 0, 10, 20, "yellow")
];
var next = () => {
updateFrame(balls);
drawFrame(balls);
}
var loop = () => {
requestAnimationFrame(() => {
next();
loop();
});
}
next();
function Ball(x, y, vx, vy, r, color) {
return {
x: x,
y: y,
vx: vx,
vy: vy,
r: r,
color: color
}
};
function updateBall(b) {
b.x += b.vx;
b.y += b.vy;
if (b.y <= b.r ||
b.y >= cvs.height - b.r) {
b.vy *= -0.5;
}
};
function drawBall(b) {
ctx.beginPath();
ctx.fillStyle = b.color;
ctx.arc(b.x, b.y, b.r, 0, 2 * Math.PI, false);
ctx.fill();
}
function updateFrame(balls) {
balls.forEach(updateBall);
}
function drawFrame(balls) {
ctx.clearRect(0, 0, cvs.width, cvs.height);
balls.forEach(drawBall);
};
&#13;
<canvas width="300" height="150" style="background: #454545"></canvas>
<button onclick="next()">next</button>
<button onclick="loop()">run</button>
&#13;
在您的情况下,我认为只有当桨碰撞和墙碰撞同时发生时才会发生这种情况。
快速实施的解决方案是在平移球位置之前检查新位置是否有效。如果您不想要精确的位置,可以将球放在碰撞点。请注意,这将产生略微偏离的帧。
E.g:
var newY = ballY + ballSpeedY;
// Top wall
if(newY <= 10) {
ballY = 10;
ballSpeedY = -ballSpeedY;
}
// Bottom wall
else if(newY >= HEIGHT-10){
ballY = HEIGHT - 10;
ballSpeedY = -ballSpeedY;
}
// No collision
else {
ballY = newY;
}
更新:可能发生的更详细的描述
让我们说你的球与你的画布和的顶部边框碰撞,你的划桨在同一个框架中。
首先,你将球移动到碰撞位置:ballY += ballSpeedY;
说你的ballY
是4,你的ballSpeedY
是-5,你将球定位到{ {1}},在墙内。
如果这是唯一的碰撞,你应该没问题。你翻转速度(-1
),所以在下一帧中,你的球应该回到ballSpeedY = -ballSpeedY
,所以-1 + 5 = 4
将再次ballY
,你的球会移动在下一帧中向4
。
现在出现问题,当在4 + 5 = 9
定位的框架中,你也会碰撞桨!当球拍击球时,您可以修改空速:-1
。如果结果是ballSpeedY = deltaY / 5;
,那么你的球就无法在下一帧中退出。例如,您的球将移至< 1
。而不是-1 + 5 = 4
。
现在,你的球无法重新开始比赛,因为下一帧将再次计算碰撞并翻转速度。 这会导致球在卡住时看到的弹性,颤抖效果。
一个天真但相当不错的解决方案,就是只将球的位置更新为有效的位置。即:永远不要碰撞坐标。
答案 1 :(得分:0)
class App extends React.Component {
constructor(props){
super(props)
this.state = { //initial empty details
details : [] // use array
}
}
componentDidMount(){
//place the ajax call where ever you need
$.ajax() //call ajax
.done((data) => {
let array = this.state.details;
array = [...array, {
id: data.id,
trackInfo: {
title: data.title,
artist: data.artist,
album: data.album,
},
trackUrl: data.trackUrl,
albumArt: data.albumArt,
}];
this.setState({
details: array
})
})
}
render() {
if(!this.state.details.id) return false //renders nothing when no details available
return (
<div id="app">
{
this.state.details.map((detail) => {
return <MusicPlayer
id={detail.id}
visualizerType="RIPPLES"
theme={darkTheme}
trackInfo={detail.trackInfo}
trackUrl={detail.trackUrl}
albumArt={detail.albumArt}
utilities={true}>
</MusicPlayer>
});
}
</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById("app")
);