(Javascript)弹球夹在墙上

(Javascript) Bouncing balls clip into wall

本文关键字:Javascript      更新时间:2023-09-26

document.addEventListener("DOMContentLoaded", function(event){
	var context,
		width = window.screen.availWidth - 120,
		height = window.screen.availHeight - 120,
		xTemp, 
		yTemp,
		x = [], 
		y = [], 
		dx = [0], 
		dy = [5], 
		gravity = [1],
		bounceTime = [1],
		canvas = document.getElementById("bouncingField"), 
		isSpawned = 0,
		image = new Image();
		
	document.getElementById("bouncingField").width = width;
	document.getElementById("bouncingField").height = height;
	
	//Image to use as ball texture
	image.src = "http://www.freeiconspng.com/uploads/soccer-ball-icon-14.png";
		
	//Run func init on page load
	window.onload = init;
	
	//Get 2d context and repaint every 10 milliseconds
	context = bouncingField.getContext('2d');
	setInterval(repaint, 10);
	
	canvas.onclick = function setSpawnTrue(){
		if(!isSpawned){
			x[0] = xTemp;
			y[0] = yTemp;
		} else{
			x.push(xTemp);
			y.push(yTemp);
			dx.push(0);
			dy.push(5);
			gravity.push(1);
			bounceTime.push(1);
		}
		
		isSpawned = 1;
	}
	
	//Draws the various entities
	function draw(){
		context = bouncingField.getContext('2d');
		for(var i = 0; i < x.length; i++){	
			//context.beginPath();
			//context.fillStyle = "#00ccff";
			//Draw circles of r = 25 at coordinates x and y
			//context.arc(x[i], y[i], 25, 0, Math.PI*2, true);
			context.drawImage(image, x[i], y[i], 50, 50);
			//context.closePath();
			//context.fill();
		}
	}
	//Repaints entities, essentially animating them	
	function repaint(){
		for(var i = 0; i < x.length; i++){
			context.clearRect(0, 0, 2000, 2000);
			if(x[i] < 20 || x[i] > width) dx[i] *= -1;
			if(y[i] < 20 || y[i] > height) {
				dy[i] *= -1;
				//We add bounceTime to dy so that it gradually loses speed
				dy[i] += bounceTime[i];
				//Inverting graviy to slow down on rise
				gravity[i] *= -1;
			}
			
			x[i] += dx[i];
			//Gravity affects the ball bounce speed, that gradually slows down.
			y[i] += dy[i] + gravity[i];
			//bounceTime gradually reduces the amount of speed the ball has
			gravity[i] += 0.2 * bounceTime[i];
			bounceTime[i] += 0.01;
			if(isSpawned){
				draw();
			}
		}
	}
	
	//Initializes Event.MOUSEMOVE to capture cursor coordinates
	function init(){
		if(window.Event){
			document.captureEvents(Event.MOUSEMOVE);
		}
		document.onmousemove = getCoordinates;
	}
		
	//Gets mouse coordinates and puts them into xTemp and yTemp
	function getCoordinates(e){
		xTemp = (window.Event) ? e.pageX : event.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);
		yTemp = (window.Event) ? e.pageY : event.clientY + (document.documentElement.scrollRight ? document.documentElement.scrollRight : document.body.scrollRight);
		xTemp -= 14;
		yTemp -= 14;
	}
});
body{
	background-color: #555555;
}
#bouncingField{
	border-style: solid;
	border-width: 10px;
	border-color: white;
}
<HTML>
	<HEAD>
		<TITLE>
			Wingin' it
		</TITLE>
		
		<script type="text/javascript" src="script.js"></script>
		
		<link href="style.css" rel="stylesheet" type="text/css">
	
	</HEAD>
	
	<BODY>
		<CANVAS id="bouncingField" width="0" height="0"></CANVAS>
	</BODY>
</HTML>

我正在做一个简单的JavaScript项目,创建模拟重力和从地板或墙上反弹的弹跳球。问题是,有时它们会夹在地板上"喷出来",直到从屏幕上消失。知道为什么吗?我一直试图通过每次碰撞时添加一个微小的超时来解决这个问题,但JS没有睡眠,所以我现在很困惑。

提前感谢:(

我希望这能有所帮助。棘手的部分是做出令人信服的"停止"。

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>