我在画布中有2个元素,我想让两个元素相互碰撞,当它们碰撞时其中一个应该反转它的速度,我没有得到碰撞它们的逻辑,这是我的代码。
https://codepen.io/Thakur92411/pen/vjXJqq?editors=0011
<canvas id="canvas"></canvas>
这是我的javascript
var can_width = document.querySelector("canvas").width = 500;
var can_height = document.querySelector("canvas").height = 500;
var c = document.getElementById("canvas");
ctx = c.getContext("2d");
var x = 200;
var dx = 6;
var y = 300;
var dy = 5;
var radius = 30;
var rx = 400;
var ry = 200;
function animate(){
requestAnimationFrame(animate);
ctx.clearRect(0,0,can_width,can_height);
ctx.beginPath();
ctx.strokeStyle="red";
ctx.fillStyle="#FF0000";
ctx.arc(x, y, radius, 0, 2 * Math.PI);
ctx.fillRect(rx,ry,20,100);
ctx.fill();
ctx.stroke();
if((can_height-y)-radius > x )
{
dx = + dx;
}
if(x + radius > can_width || x - radius < 0 || can_width - ( can_width-rx )-radius < x )
{
dx = - dx;
}
else if (y + radius > can_height || y - radius < 0 ){
dy = - dy;
}
console.log(rx);
x += dx;
y += dy;
}
animate();
答案 0 :(得分:1)
我写了一个简单的算法来检查圆是否与桨碰撞。并且还使桨叶可移动。有关详细信息,请参阅以下演示和注释...
var can_width = document.querySelector("canvas").width = 500;
var can_height = document.querySelector("canvas").height = 500;
var c = document.getElementById("canvas");
ctx = c.getContext("2d");
var x = 200,
dx = 6;
var y = 300,
dy = 5;
var radius = 30;
var rx = 400,
ry = 200;
var paddleWidth = 20,
paddleHeight = 100;
var isCollided = false;
function animate() {
requestAnimationFrame(animate);
ctx.clearRect(0, 0, can_width, can_height);
ctx.beginPath();
ctx.strokeStyle = "red";
ctx.fillStyle = "#FF0000";
ctx.arc(x, y, radius, 0, 2 * Math.PI);
ctx.fillRect(rx, ry, paddleWidth, paddleHeight);
ctx.fill();
ctx.stroke();
// x y inXRange x y
// (xLeft, yTop) atTop (xRight, yTop)
// ---------
// | |
// atLeft | | atRight
// inYRange | | inYRange
// ---------
// (xLeft, yBot) atBot (xRight, yBot)
// inXRange
// the coordinates of the paddle
var xLeft = rx,
xRight = rx + paddleWidth,
yTop = ry,
yBot = ry + paddleHeight;
// check if in specific range (see the figure above)
var inXRange = x >= xLeft && x <= xRight,
inYRange = y >= yTop && y <= yBot;
// check if in specific area (see the figure above)
var atTop = y <= yTop,
atBot = y >= yBot,
atLeft = x <= xLeft,
atRight = x >= xRight;
// check if collides with 4 boundaries
var outXLeft = (x - radius) <= 0,
outXRight = (x + radius) >= can_width,
outYTop = (y - radius) <= 0,
outYBot = (y + radius) >= can_height
isCollided = false;
// collides with any of boundaries
if(outXLeft || outXRight || outYTop || outYBot) {
// if collides with boundary...
// left : set circle's x to radius
// right: set circle's x to can_width-radius
// or do nothing
x = outXLeft ? radius : outXRight ? (can_width - radius) : x;
// if collides with boundary...
// top: set circle's y to radius
// bot: set circle's y to can_height-radius
// or do nothing
y = outYTop ? radius : outYBot ? (can_height - radius) : y;
// if collides with boundary...
// right: set dx to negative
// left : set dx to positive
// or do nothing
dx = outXRight ? -Math.abs(dx) : outXLeft ? Math.abs(dx) : dx;
// if collides with boundary...
// bot: set dy to negative
// top: set dy to positive
// or do nothing
dy = outYBot ? -Math.abs(dy) : outYTop ? Math.abs(dy) : dy;
}
else {
// if doesn't collide with any of boundaries, then...
// if center point of the circle is at...,
// calculate the distance between center point and the paddle...
// atLeft : xLeft - x
// atRight: xRight - x
// not both of them: doesn't matter, calculate the rY distance is enough
var rX = Math.abs(atLeft ? xLeft - x : atRight ? x - xRight : 0);
// atTop : yTop - y
// atRight: yBot - y
// not both of them: doesn't matter, calculate the rX distance is enough
var rY = Math.abs(atTop ? yTop - y : atBot ? y - yBot : 0);
// if both rX and rY are less than radius means the circle collides with the paddle
if(rX <= radius && rY <= radius) {
// if center point of the circle is at...
// atLeft : set dx to negative
// atRight: set dx to positive
// or do nothing
dx = atLeft ? -Math.abs(dx) : atRight ? Math.abs(dx) : dx;
// atTop: set dy to negative
// atBot: set dy to positive
// or do nothing
dy = atTop ? -Math.abs(dy) : atBot ? Math.abs(dy) : dy;
}
}
x += dx;
y += dy;
}
animate();
// move the paddle vertically
c.addEventListener('mousemove', function(e){
var maxHeight = can_height - paddleHeight;
var _ry = e.clientY - paddleHeight/2;
ry = _ry <= 0 ? 0 : (_ry >= maxHeight) ? maxHeight : _ry;
})
&#13;
canvas {
background: #ddd
}
body {
margin: 0px;
}
&#13;
<canvas id="canvas"></canvas>
&#13;
答案 1 :(得分:0)
尝试添加此条件:
if( x + radius >= rx ) {
if( y - radius < ry + 100 ) {
if( y + radius > ry ) {
alert( "colision" );
}
}
}
编辑:Fiddle Here
如果有效,请告诉我