好吧,首先,该工程的代码。
<html>
<head>
<style>
body, html {
margin: 0;
padding: 0;
}
#canvas {
background-color: black;
}
</style>
<script>
function drawArc() {
ctx.beginPath();
ctx.fillStyle = "white";
ctx.arc(ax, ay, radius, 0, 2 * Math.PI);
ctx.fill();
ctx.closePath();
};
function update() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawArc();
ax += avx;
ay -= avy;
avy -= 0.2;
if (ay + radius >= canvas.height) {
avy *= -0.8;
avx *= 0.9;
};
if (ax + radius >= canvas.width) {
avx = -avx;
};
if (ax - radius <= 0) {
avx = -avx;
};
}
function onload()
{
canvas = document.getElementById('canvas');
ctx = canvas.getContext('2d');
ax = 50;
ay = 50;
avx = 5;
avy = 2;
radius = 50;
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
setInterval(update, 10);
}
</script>
<style>
</style>
</head>
<body onload="onload()">
<canvas id="canvas"></canvas>
</body>
</html>
二,问题是什么。我认为我遇到的最大问题是您提供的代码在全局上下文中具有变量和操作,这些变量和操作依赖于尚未创建的页面元素。这意味着无法创建canvas和cxt的变量,因为canvas标签尚未创建。我把所有这些都放到了一个函数中,我可以在页面加载完成后调用,并且从那里一切正常。现在,当调用该函数时,画布已经存在,您可以使用它创建上下文并执行其他操作。
第三个基于问题标题,你想知道为什么它停止弹跳。我认为你已经正确地创造了一个弹跳球,可以从墙壁和地板上弹开,但由于重力和与地面的非弹性碰撞而失去了能量。就我个人而言,我没有完成代码,但它看起来很棒。你为什么要改变它。如果你想让它永远弹跳,那么与墙壁和地板的碰撞就需要100%的弹性 - 这意味着你不会失去任何能量,并且你的球弹跳时间与之前一样高。在与FLOOR的交互中,您使用下面的代码。这有一个抑制效果,并最终将你的球降为零能量。
avy *= -0.8;//could be -1
avx *= 0.9;//could be 1
然而,这又产生了另一个问题。您使用的代码需要缓冲或球在每次反弹时弹跳得更高。这是因为你正在加速这条线和获得能量。
avy -= 0.2;
您另外一个答案建议你减少润版,而不是通过改变这一行完全删除它。你将不得不调整它,使其具有你想要的行为。
avy *= -0.8;//-0.8 is too little? -1 is too much
最后编辑,我承诺。我其实有很多乐趣。问题并非如此简单,以至于您只需放入仿真物理并获得球弹跳的良好模拟。即使你输入所有正确的方程,你仍然会得到一个小的永久反弹,因为这是现实生活中发生的。当球足够慢地移动并且足够靠近地面时,其他力(不是重力,但强,弱和电磁吸引力)占主导地位,并导致球停止移动。所以,我再一次轻扫一下,改善了物理学。这并不完美,但在某些时候,你必须要问的是,模拟的FIDELITY比平滑行为与我想要看到的要更重要。希望这可以帮助。
<html>
<head>
<style>
body, html {
margin: 0;
padding: 0;
}
#canvas {
background-color: black;
}
</style>
<script>
function drawArc() {
ctx.beginPath();
ctx.fillStyle = "white";
ctx.arc(xPos, yPos, radius, 0, 2 * Math.PI);
ctx.fill();
ctx.closePath();
};
function update() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawArc();
var dx = xVel*timeStep;
var dy = yVel*timeStep;
if(yVel<radius && yVel>-radius && canvas.height-(yPos+radius) < .1)
{
yVel = 0;
yPos = canvas.height-radius;
dy=0;
//friction affects xVel
xVel *= fFloor;
}
else if (yPos + dy + radius >= canvas.height) {
//you will be below the floor; there is a bounce
//find the rest of the falling interval
var remainingY = canvas.height-(yPos+radius);
//find the rest of the time step
var remainingTime = remainingY/yVel;
//add acceleration for that time
yVel += gravity * remainingTime
//friction affects xVel
xVel *= fFloor;
//elasticity affects yVel
yVel *= eFloor;
//now you are bouncing up
//what is time up
remainingTime = timeStep - remainingTime;
//set final position
yPos = canvas.height + (yVel*remainingTime) - radius;
//add acceleration for that time
yVel += gravity * remainingTime;
}
else
{
//do not hit the floor, falling the whole time
yPos += dy;
yVel += gravity * timeStep;
}
if (xPos + dx + radius >= canvas.width)
{
//hit a wall; there is a bounce
//find the rest of the interval
var remainingX = canvas.width-(xPos+radius);
//find the rest of the time step
var remainingTime = remainingX/xVel;
//no horizontal acceleration
//friction affects yVel
yVel *= fWall;
//elasticity affects xVel
xVel *= eWall;
//now you are bouncing back
//what is time up
remainingTime = timeStep - remainingTime;
//set final position
xPos = canvas.width + (xVel*remainingTime) - radius;
//no horizontal acceleration
}
else if (xPos + dx - radius <= 0) {
//hit a wall; there is a bounce
//find the rest of the interval
var remainingX = (xPos - radius);
//find the rest of the time step
var remainingTime = remainingX/xVel;
//no horizontal acceleration
//friction affects yVel
yVel *= fWall;
//elasticity affects xVel
xVel *= eWall;
//now you are bouncing back
//what is time up
remainingTime = timeStep - remainingTime;
//set final position
xPos = xVel*remainingTime+radius;
//no horizontal acceleration
}
else {
//never hit a wall; flying the whole time
xPos += dx;
}
}
function onload()
{
canvas = document.getElementById('canvas');
ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
radius = 15;
xPos = Math.random()*(canvas.width-(2*radius))+radius;
yPos = Math.random()*(canvas.height-(2*radius))+radius;
xVel = Math.random()*100-50;
yVel = Math.random()*100-50;
gravity = 9.8;
eWall = -1;
eFloor = -.8;
fFloor = .9;
fWall = .9;
interval = 10;
timeStep = .1;//apparent time step
setInterval(update, interval);
}
</script>
<style>
</style>
</head>
<body onload="onload()">
<canvas id="canvas"></canvas>
</body>
</html>
你想让它永远反弹吗? –
你预计会发生什么?你已经编码,在每次击球时,球的速度都会降低(摩擦)。所以在一段时间后球停止移动是正常的。 – trincot
如果你不想松动高度,你需要跟踪每次反弹时的所有动能。这个答案http://stackoverflow.com/a/34187884/3877726演示如何做一个简单的弹跳球随着时间的推移不会消耗能量。 http://stackoverflow.com/a/34187884/3877726 – Blindman67