Javascript 球在4-5秒后停止反弹
下面是javascript:Javascript 球在4-5秒后停止反弹,javascript,html,css,canvas,Javascript,Html,Css,Canvas,下面是javascript: var canvas=document.getElementById('canvas'), ctx=canvas.getContext('2d'), ax=50, ay=50, avx=5, avy=2, 半径=50; canvas.width=window.innerWidth; canvas.height=window.innerHeight; 函数drawArc(){ ctx.beginPath(); ctx.fillStyle=“白色”; ctx.弧(ax
var canvas=document.getElementById('canvas'),
ctx=canvas.getContext('2d'),
ax=50,
ay=50,
avx=5,
avy=2,
半径=50;
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
函数drawArc(){
ctx.beginPath();
ctx.fillStyle=“白色”;
ctx.弧(ax,ay,半径,0,2*Math.PI);
ctx.fill();
ctx.closePath();
};
函数更新(){
clearRect(0,0,canvas.width,canvas.height);
drawArc();
ax+=avx;
ay-=avy;
avy-=0.2;
如果(ay+半径>=画布高度){
平均值*=-0.8;
avx*=0.9;
};
如果(轴+半径>=画布宽度){
avx=-avx;
};
如果(ax-radius我想你想要这个:
var canvas=document.getElementById('canvas'),
ctx=canvas.getContext('2d'),
ax=50,
ay=50,
avx=5,
avy=2,
半径=50;
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
函数drawArc(){
ctx.beginPath();
ctx.fillStyle=“白色”;
ctx.弧(ax,ay,半径,0,2*Math.PI);
ctx.fill();
ctx.closePath();
};
var-hitTheGround=0;
函数更新(){
clearRect(0,0,canvas.width,canvas.height);
drawArc();
ax+=avx;
ay-=avy;
avy-=0.2;
如果(ay+半径>=画布高度){
平均值*=-0.8;
avx*=0.9;
}
如果(轴+半径>=画布宽度){
avx=-avx;
}
如果(ax-radius=canvas.height-3){
打地面++;
}
否则{
接地=0;
}
if(hitTheGround==100){//如果它在地面附近跳得太频繁
返回setTimeout(函数(){clearInterval(interval)},1000);
}
}
var interval=setInterval(更新,10);
body,html{
保证金:0;
填充:0;
}
#帆布{
背景色:黑色;
}
简单的回答是,由于你没有将球移离地面,所以你会受到很多打击。下一帧球仍在撞击地面,当你降低它的速度时,它只是停滞不前
在小提琴的第29行后面加上这个
ay = canvas.height - radius;
好的,首先,是有效的代码
<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>
然而,这会产生另一个问题。你正在使用的代码需要阻尼,或者每次反弹时球都反弹得更高。这是因为你在这条线上加速并获得能量
avy -= 0.2;
您的另一个答案建议您减少阻尼,但不要通过更改这一行来完全消除阻尼。您必须调整这一行,使其具有您想要的行为
avy *= -0.8;//-0.8 is too little? -1 is too much
最后一次编辑,我保证。我确实从中得到了很多乐趣。这个问题并不是那么简单,你可以用psuedo物理来很好地模拟一个球的反弹。即使你把所有正确的方程都放进去,你仍然会得到一个小的永久反弹,因为这是现实生活中发生的事情。当球移动得足够慢并且其他力(不是重力,而是强、弱和电磁引力)足够靠近地板控制并使球停止移动。因此,我又打了一次球,大大改善了物理性能。这并不完美,但在某些时候你必须问,模拟的逼真度是否比平滑行为更重要,以匹配我想要看到的。希望这能有所帮助
<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>
正文,html{
保证金:0;
填充:0;
}
#帆布{
背景色:黑色;
}
函数drawArc(){
ctx.beginPath();
ctx.fillStyle=“白色”;
弧(xPos,yPos,半径,0,2*Math.PI);
ctx.fill();
ctx.closePath();
};
函数更新(){
clearRect(0,0,canvas.width,canvas.height);
drawArc();
var dx=xVel*时间步长;
var dy=yVel*时间步长;
if(yVel半径和画布高度-(yPos+半径)<.1)
{
yVel=0;
yPos=画布高度-半径;
dy=0;
//摩擦影响xVel
xVel*=fFloor;
}
否则如果(yPos+dy+radius>=画布高度){
//你将在地板下,有一个弹跳
//找出下降间隔的其余部分
var remainingY=画布高度-(yPos+半径);
//找到剩余的时间步长
var剩余时间=剩余时间/yVel;
//加上当时的加速度
yVel+=重力*剩余时间
//摩擦影响xVel
xVel*=fFloor;
//弹性影响yVel
yVel*=eFloor;
//现在你正在反弹
//什么时间到了
剩余时间=时间步长-剩余时间;
//设定最终位置
yPos=画布高度+(yVel*remainingTime)-半径;
//加上当时的加速度
yVel+=重力*剩余时间;
}
其他的
{
//不要撞到地板上,不要一直摔倒
yPos+=dy;
yVel+=重力*时间步长;
}
如果(xPos+dx+radius>=画布宽度)
{
//撞到墙上;有反弹
//找出间隔的其余部分
var remainingX=canvas.width-(xPos+半径);
//找到剩余的时间步长
var剩余时间=剩余时间x/xVel;
//无水平加速度
//摩擦影响yVel
yVel*=fWall;
//弹性影响xVel
xVel*=eWall;
//现在你正在反弹
//什么时间到了
剩余时间=时间步长-剩余时间;
//设定最终位置
xPos=canvas.width+(xVel*remainingTime)-半径;
//无水平加速度
}
否则,如果(xPos+dx-radius)你想让它永远弹跳吗?你期望发生什么?你已经在每一次落地击球中编码,球的速度会降低(摩擦)。因此,球在一段时间后停止移动是正常的。如果你不想失去高度,你需要跟踪每次弹跳时的所有动能。这个答案演示了如何做一个简单的弹跳球,而不是随着时间的推移而失去能量。我不想永远从一个球弹跳到另一个球,我只想自然地停止弹跳,而不是冻结在某一时刻。通过每次将avy减少0.8,您试图模拟一个能量松弛,其中松弛的能量在实际中不是线性的。但是,您可以将其更改为0.9或更大,以获得更长的动画。我不想要无限的反弹,我只想
<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>