2016-10-14 70 views
0

(JavaScript)的彈跳球夾入牆

document.addEventListener("DOMContentLoaded", function(event){ 
 
\t var context, 
 
\t \t width = window.screen.availWidth - 120, 
 
\t \t height = window.screen.availHeight - 120, 
 
\t \t xTemp, 
 
\t \t yTemp, 
 
\t \t x = [], 
 
\t \t y = [], 
 
\t \t dx = [0], 
 
\t \t dy = [5], 
 
\t \t gravity = [1], 
 
\t \t bounceTime = [1], 
 
\t \t canvas = document.getElementById("bouncingField"), 
 
\t \t isSpawned = 0, 
 
\t \t image = new Image(); 
 
\t \t 
 
\t document.getElementById("bouncingField").width = width; 
 
\t document.getElementById("bouncingField").height = height; 
 
\t 
 
\t //Image to use as ball texture 
 
\t image.src = "http://www.freeiconspng.com/uploads/soccer-ball-icon-14.png"; 
 
\t \t 
 
\t //Run func init on page load 
 
\t window.onload = init; 
 
\t 
 
\t //Get 2d context and repaint every 10 milliseconds 
 
\t context = bouncingField.getContext('2d'); 
 
\t setInterval(repaint, 10); 
 
\t 
 
\t canvas.onclick = function setSpawnTrue(){ 
 
\t \t if(!isSpawned){ 
 
\t \t \t x[0] = xTemp; 
 
\t \t \t y[0] = yTemp; 
 
\t \t } else{ 
 
\t \t \t x.push(xTemp); 
 
\t \t \t y.push(yTemp); 
 
\t \t \t dx.push(0); 
 
\t \t \t dy.push(5); 
 
\t \t \t gravity.push(1); 
 
\t \t \t bounceTime.push(1); 
 
\t \t } 
 
\t \t 
 
\t \t isSpawned = 1; 
 
\t } 
 
\t 
 
\t //Draws the various entities 
 
\t function draw(){ 
 
\t \t context = bouncingField.getContext('2d'); 
 
\t \t for(var i = 0; i < x.length; i++){ \t 
 
\t \t \t //context.beginPath(); 
 
\t \t \t //context.fillStyle = "#00ccff"; 
 
\t \t \t //Draw circles of r = 25 at coordinates x and y 
 
\t \t \t //context.arc(x[i], y[i], 25, 0, Math.PI*2, true); 
 
\t \t \t context.drawImage(image, x[i], y[i], 50, 50); 
 
\t \t \t //context.closePath(); 
 
\t \t \t //context.fill(); 
 
\t \t } 
 
\t } 
 

 
\t //Repaints entities, essentially animating them \t 
 
\t function repaint(){ 
 
\t \t for(var i = 0; i < x.length; i++){ 
 
\t \t \t context.clearRect(0, 0, 2000, 2000); 
 
\t \t \t if(x[i] < 20 || x[i] > width) dx[i] *= -1; 
 
\t \t \t if(y[i] < 20 || y[i] > height) { 
 
\t \t \t \t dy[i] *= -1; 
 
\t \t \t \t //We add bounceTime to dy so that it gradually loses speed 
 
\t \t \t \t dy[i] += bounceTime[i]; 
 
\t \t \t \t //Inverting graviy to slow down on rise 
 
\t \t \t \t gravity[i] *= -1; 
 
\t \t \t } 
 
\t \t \t 
 
\t \t \t x[i] += dx[i]; 
 
\t \t \t //Gravity affects the ball bounce speed, that gradually slows down. 
 
\t \t \t y[i] += dy[i] + gravity[i]; 
 
\t \t \t //bounceTime gradually reduces the amount of speed the ball has 
 
\t \t \t gravity[i] += 0.2 * bounceTime[i]; 
 
\t \t \t bounceTime[i] += 0.01; 
 
\t \t \t if(isSpawned){ 
 
\t \t \t \t draw(); 
 
\t \t \t } 
 
\t \t } 
 
\t } 
 
\t 
 
\t //Initializes Event.MOUSEMOVE to capture cursor coordinates 
 
\t function init(){ 
 
\t \t if(window.Event){ 
 
\t \t \t document.captureEvents(Event.MOUSEMOVE); 
 
\t \t } 
 
\t \t document.onmousemove = getCoordinates; 
 
\t } 
 
\t \t 
 
\t //Gets mouse coordinates and puts them into xTemp and yTemp 
 
\t function getCoordinates(e){ 
 
\t \t xTemp = (window.Event) ? e.pageX : event.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft); 
 
\t \t yTemp = (window.Event) ? e.pageY : event.clientY + (document.documentElement.scrollRight ? document.documentElement.scrollRight : document.body.scrollRight); 
 
\t \t xTemp -= 14; 
 
\t \t yTemp -= 14; 
 
\t } 
 
});
body{ 
 
\t background-color: #555555; 
 
} 
 

 
#bouncingField{ 
 
\t border-style: solid; 
 
\t border-width: 10px; 
 
\t border-color: white; 
 
}
<HTML> 
 
\t <HEAD> 
 
\t \t <TITLE> 
 
\t \t \t Wingin' it 
 
\t \t </TITLE> 
 
\t \t 
 
\t \t <script type="text/javascript" src="script.js"></script> 
 
\t \t 
 
\t \t <link href="style.css" rel="stylesheet" type="text/css"> 
 
\t 
 
\t </HEAD> 
 
\t 
 
\t <BODY> 
 
\t \t <CANVAS id="bouncingField" width="0" height="0"></CANVAS> 
 
\t </BODY> 
 
</HTML>

我工作的一個簡單的JavaScript項目創建模擬重力和彈跳離地板或牆壁的彈跳球。問題是有時他們會在地板上「剪出」,直到它們從屏幕上消失。任何線索爲什麼?我一直試圖通過在每次碰撞時增加一個微小的超時時間來解決這個問題,但JS沒有睡眠,所以現在我只是感到困惑。

預先感謝您:)

+0

本網站不通過設計和調試代碼來搜索你 - 隨時回來後一個問題,如果你有一個真正的* *的問題 –

+2

這是我的代碼,它不起作用。讓它起作用 ! – Arthur

+0

@Alex Leonardi您的彈跳球速度有所變化,因此根據碰撞前球與碰撞物體的接近程度,球可能無法在下一個週期中脫身。這會導致它「卡住」碰撞物體。 – 42shadow42

回答

0

我希望這有助於。棘手的部分是制定一個令人信服的「停止」。

function getCoordinates(event) { return { x: event.offsetX, y: event.offsetY }; } 
 

 
function spawnBall(coords, x, y, dx, dy){ 
 
    x.push(coords.x); 
 
    y.push(coords.y); 
 
    dx.push(0); 
 
    dy.push(2); 
 
} 
 

 
// ========================= 
 
// Draws the various entities 
 
// ========================= 
 
function draw(canvas, image, x, y, width, height) { 
 
    var context = canvas.getContext('2d'); 
 
    context.clearRect(0, 0, canvas.width, canvas.height); 
 
    for(var i = 0; i < x.length; i++){ context.drawImage(image, x[i], y[i], width, height); } 
 
} 
 
// ========================= 
 

 
// ========================= 
 
// At the moment all this is concerned with is the "floor" 
 
// ========================= 
 
function move(x, y, dx, dy, gravity, bounciness, floor){ 
 
    for(var i = 0; i < x.length; i++){ 
 
     // ========================= 
 
     // Ball is close to the floor and not moving very fast, set it to rest 
 
     // otherwise it bounces forever. 
 
     // ========================= 
 
     if (y[i] >= floor - 10 && Math.abs(dy[i]) <= 2 * gravity) { 
 
      dy[i] = 0; 
 
      y[i] = floor; 
 
      continue; 
 
     } 
 
     // ========================= 
 

 
     // ========================= 
 
     // Update the speed and position 
 
     // ========================= 
 
     dy[i] += gravity; 
 
     y[i] += dy[i]; 
 
     // ========================= 
 

 
     // ========================= 
 
     // Simulate a bounce if we "hit" the floor 
 
     // ========================= 
 
     if(y[i] > floor) { 
 
      y[i] = floor - (y[i] - floor); 
 
      dy[i] = -1.0 * bounciness * dy[i]; 
 
     } 
 
     // ========================= 
 
    } 
 
} 
 
// ========================= 
 

 
document.addEventListener("DOMContentLoaded", function(event){ 
 
    var canvas = document.getElementById("bouncingField"); 
 
    canvas.width = window.innerWidth - 50; 
 
    canvas.height = window.innerHeight - 50; 
 

 
    //Image to use as ball texture 
 
    var image = new Image(); 
 
    image.src = "http://www.freeiconspng.com/uploads/soccer-ball-icon-14.png"; 
 

 
    var gravity = 1; 
 
    var ballSize = 50; 
 
    var ballBounciness = 0.8; 
 
    var floor = canvas.height - ballSize; 
 

 
    var x = []; 
 
    var y = []; 
 
    var dx = []; 
 
    var dy = []; 
 

 
    // ========================= 
 
    // This can be done via requestAnimationFrame() 
 
    // https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame 
 
    // ========================= 
 
    var isSpawned = false; 
 
    setInterval(function(){ 
 
     if(!isSpawned){ return; } 
 
     move(x, y, dx, dy, gravity, ballBounciness, floor) 
 
     draw(canvas, image, x, y, ballSize, ballSize); 
 
    }, 10); 
 
    // ========================= 
 

 
    // ========================= 
 
    // Add a ball 
 
    // ========================= 
 
    canvas.onclick = function(event) { 
 
     isSpawned = true; 
 
     var coords = getCoordinates(event); 
 
     spawnBall(coords, x, y, dx, dy); 
 
    } 
 
    // ========================= 
 
});
body { 
 
    background-color: #555555; 
 
} 
 
#bouncingField { 
 
    border-style: solid; 
 
    border-width: 10px; 
 
    border-color: white; 
 
}
<canvas id="bouncingField"></canvas>

+0

謝謝,這讓我有一個想法,在每次彈跳至Y - 40層時重置y球,以彌補週期的損失。:) –