两个球之间发生碰撞,因此它们可以相互反弹

时间:2019-06-03 17:17:17

标签: javascript html5-canvas

我只想要一个简单的碰撞检测,以便这些球彼此弹起,并且如果您还可以用更好的方式对这些类型的动画进行编码来使我生气,那就不高兴了。我听说使用面向对象的Javascript有一种更好的方法,但是由于我还是一个初学者,因此这对我来说似乎很复杂。请尝试解释您建议我的代码,因为我仍在学习。

var canvas = document.getElementById("canv");
var ctx = canvas.getContext("2d");
var x = canvas.width/2;
var x2 = canvas.width/2;
var y = canvas.height-20;
var y2 = 20;
var ballRadius = 20;
var ballRadius2 = 20;
var dx = 2;
var dy = -2;
var dx2 = 2;
var dy2 = 2;
function drawBall(){
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.beginPath();
    ctx.arc(x, y,ballRadius, 0, Math.PI*2);
    ctx.fillStyle = "green";
    ctx.fill();
    ctx.closePath();
}
function drawBall2(){
    ctx.beginPath();
    ctx.arc(x2, y2,ballRadius2, 0, Math.PI*2);
    ctx.fillStyle = "blue";
    ctx.fill();
    ctx.closePath();
}
function draw(){
    drawBall();
    drawBall2();
    x += dx;
    y += dy;
    x2 += dx2;
    y2 += dy2
    if (x && x2 > canvas.width - ballRadius || x && x2 < ballRadius){
    dx = -dx;
    dx2 = -dx2;
    }
    if (y && y2 > canvas.height - ballRadius || y && y2 < 0){
    dy = -dy;
    dy2 = -dy2;
    }

 }
setInterval(draw, 10);

如果你们能帮助我简化这段代码,请不要感激。

1 个答案:

答案 0 :(得分:-1)

好问题!我想对深入学习javascript和HTML5说好话。这两个工具都是很棒的工具,肯定会帮助您组合一些很棒的项目。

现在问这个问题。您在问如何在两个球之间进行简单的碰撞测试。我将在稍后对此进行解释,但在此之前,我想为您提供Javascript object oriented programming的参考。

两个球之间的碰撞测试与与墙壁的碰撞测试非常相似。主要区别在于您不能仅考虑xy值,而必须同时考虑它们。

请记住,如果球相对于xy的距离等于或小于其组合半径,则需要“反弹”。

x = radius1 + radius2

现在剩下的就是将该逻辑语句转换为javascript逻辑语句。我提供了一种潜在的解决方案,并敦促您在可能的情况下做出更好的解决方案。

//test for 'hits' with eachother
if((Math.abs(ballOne.x - ballTwo.x) < (ballOne.radius + ballTwo.radius)) && (Math.abs(ballOne.y - ballTwo.y) < (ballOne.radius + ballTwo.radius)))
{
    //reverse ball one
    ballOne.dx = -ballOne.dx;
    ballOne.dy = -ballOne.dy;

    //reverse ball two
    ballTwo.dx = -ballTwo.dx;
    ballTwo.dy = -ballTwo.dy;
}

我还提供了我认为对您当前项目而言“更简单”,当然也更简单的解决方案。我建议通读这篇文章并利用上面链接中的文档来更好地理解Javascript OOP。

祝您好运,并祝您编程愉快!

<!DOCTYPE html>
    
    <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta charset="utf-8" />
        <title></title>
    </head>
    <body>
    	<canvas id="canv" width="400" height="400"></canvas>
    
    	<script>
    	//define canvas object
    	var canvas = document.getElementById("canv");
    	var ctx = canvas.getContext("2d");
    
    	//define ball objects
    	var ballOne;
    	var ballTwo;
    
    	//javascript 'constructor function' for ball
    	function Ball(x, y, dx, dy, radius, color){
    		this.x = x;
    		this.y = y;
    		this.dx = dx;
    		this.dy = dy;
    		this.radius = radius;
    		this.color = color;
    	}
    
    	function wallCollisionDetection(balls){
    		
    		//for loop to 'go through' the array of balls
    		var i;
    		for(i = 0; i < balls.length; i++){
    			//collision test between a ball and a wall
    				//x-direction tests
    				if((balls[i].x + balls[i].radius >= canvas.width) || (balls[i].x - balls[i].radius <= 0) ){ balls[i].dx = -balls[i].dx; }
    
    				//y-direction tests
    				if((balls[i].y + balls[i].radius >= canvas.height) || (balls[i].y - balls[i].radius <= 0) ){ balls[i].dy = -balls[i].dy; }
    		}	
    	}
    
    	function updateBall(ball){
    		ball.x += ball.dx;
    		ball.y += ball.dy;
    	}
    	
    	function drawBall(ball){
    		ctx.beginPath();
    		ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI*2);
    		ctx.fillStyle = ball.color;
    		ctx.fill();
    		ctx.closePath();
    	}
    	function draw(){
    
    		//draw both ball objects
    		ctx.clearRect(0, 0, canvas.width, canvas.height);
    		drawBall(ballOne);
    		drawBall(ballTwo);
    		
    		//update the balls' x & y based on the balls' dx & dy
    		updateBall(ballOne);
    		updateBall(ballTwo);
    		
    		//test for 'hits' with the walls
    		wallCollisionDetection([ballOne, ballTwo]);
    		
    		//test for 'hits' with eachother
    		if((Math.abs(ballOne.x - ballTwo.x) < (ballOne.radius + ballTwo.radius)) && (Math.abs(ballOne.y - ballTwo.y) < (ballOne.radius + ballTwo.radius)))
    		{
    			//reverse ball one
    			ballOne.dx = -ballOne.dx;
    			ballOne.dy = -ballOne.dy;
    
    			//reverse ball two
    			ballTwo.dx = -ballTwo.dx;
    			ballTwo.dy = -ballTwo.dy;
    		}
    		
    	}
    	function initializeBalls(){
    		//set-up ball objects
    		ballOne = new Ball(canvas.width / 2, canvas.height - 50, 2, -2, 15, "green");
    		ballTwo = new Ball(canvas.width / 2, 40, 3, 2, 35, "blue");
    	}
    	initializeBalls();
    	setInterval(draw, 10);
    	</script>
    </body>

</html>