我试图做到这一点,以使圈子彼此束缚。有时效果很好,但有时会卡住。如何解决?我试图增大碰撞半径,但这显然没有用。
<style>
canvas{height:100%;width:100%;background-color:#0D1B28;}
body{margin:0;}
</style>
<canvas id="cnv"></canvas>
<script>onerror=alert</script>
<script>
balls = []
update = function(){
c.clearRect(0,0,innerWidth,innerHeight)
for(i = 0; i < balls.length; i++){
balls[i].update();
}
requestAnimationFrame(update)
}
function randomSpeed(){return {"x":(Math.random()*(config.speed*2))-config.speed,"y":(Math.random()*(config.speed*2))-config.speed}}
function randomColor(){
return config.colors[Math.round(Math.random()*config.colors.length-1)]
}
config = {"size":100,"speed":3,colors:["#E5AC3D","#D5D4BB","#39868A","#243C41"]}
onload = onresize = function(){cnv.height = innerHeight; cnv.width = innerWidth}
c = cnv.getContext("2d");
Ball = function(){
this.hitbox = [[NaN],[NaN]]
balls.push(this)
this.x = Math.random()*innerWidth
this.y = Math.random()*innerHeight
this.size = Math.random()*10
this.color = randomColor()
this.speed = randomSpeed()
this.update = function(){
if(this.x-this.size/2 <= 0||this.x+this.size/2 >= innerWidth){this.speed.x -= this.speed.x*2}
if(this.y-this.size/2 <= 0||this.y+this.size/2 >= innerHeight){this.speed.y -= this.speed.y*2}
var sh = this.hitbox
var s = balls.indexOf(this)
this.x += this.speed.x
this.y += this.speed.y
c.beginPath();
c.fillStyle = this.color
c.arc(this.x, this.y, this.size, 0, 2 * Math.PI);
c.fill();
var results = balls.filter(function(e){if(e.hitbox[0][0] <= sh[1][0]&&e.hitbox[1][0] >= sh[0][0]&&e.hitbox[0][1] <= sh[1][1]&&e.hitbox[0][1] >= sh[0][1]&&e!=s){return true}})
this.hitbox = [[this.x-this.size/2,this.y-this.size/2],[this.x+this.size/2,this.y+this.size/2]]
if(results.length > 1){this.speed.x -= this.speed.x*2; this.speed.y -= this.speed.y*2}
}
}
for(j = 0; j < 500; j++){
new Ball()
}
update()
</script>
不是一个完整的答案,但至少是一个有效的碰撞检测。
您需要遍历所有球并测试当前选定球和选中球的坐标是否比它们的组合半径更近。
function checkCollision(ball1, ball2) {
const hitDistance = (ball1.size + ball2.size) * 0.5;
const deltaX = (ball1.x - ball2.x);
const deltaY = (ball1.y - ball2.y);
return Math.sqrt(Math.pow(deltaX,2) + Math.pow(deltaY,2))
}