好吧,首先,該工程的代碼。
<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