我正在用JavaScript制作乒乓球风格的游戏,桨板是弯曲的。我已经在两个球之间发生碰撞,但似乎在球和弧线方面遇到了麻烦。
我已经看过这个线程了:
Collision detection of a ball with an arc
但是我似乎无法使那里的答案对我有用。也许是因为我画的弧线不同。 这是我的变量,以及如何将球拍绘制到画布上。当玩家按下按键时,桨的角度会增加,因此它会围绕玩家旋转。
如果有人可以提供帮助,我将不胜感激。
https://i.stack.imgur.com/kz0ZV.png
function Player(name, radius, innerColour, outerColour, x, y)
{
this.prop = {
name: name,
innerColour: innerColour,
outerColour: outerColour
};
this.phys = {
x: x,
y: y,
dx: 0,
dy: 0,
mass: radius ** 3,
radius: radius
};
this.padd = {
innerRadius: 65,
outerRadius: 85,
active: true,
startAngle: 225,
centerAngle: 270,
endAngle: 315,
rotation: false
};
this.draw = function()
{
var inR = this.padd.innerRadius;
var outR = this.padd.outerRadius;
var inC = Math.sqrt((inR ** 2) * 2);
var outC = Math.sqrt((outR ** 2) * 2);
var sAng = this.padd.startAngle;
var cAng = this.padd.centerAngle;
var eAng = this.padd.endAngle;
//Draw paddle
ctx.beginPath();
ctx.moveTo(this.rotatePoint(inR, sAng, "x"), this.rotatePoint(inR, sAng, "y"));
ctx.arcTo (this.rotatePoint(inC, cAng, "x"), this.rotatePoint(inC, cAng, "y"),
this.rotatePoint(inR, eAng, "x"), this.rotatePoint(inR, eAng, "y"), inR);
ctx.lineTo(this.rotatePoint(outR, eAng, "x"), this.rotatePoint(outR, eAng, "y"))
ctx.arcTo (this.rotatePoint(outC, cAng, "x"), this.rotatePoint(outC, cAng, "y"),
this.rotatePoint(outR, sAng, "x"), this.rotatePoint(outR, sAng, "y"), outR);
ctx.lineTo(this.rotatePoint(inR, sAng, "x"), this.rotatePoint(inR, sAng, "y"));
ctx.fillStyle = this.prop.outerColour;
ctx.fill();
ctx.closePath();
};
this.rotatePoint = function(radius, angle, axis)
{
var x = this.phys.x;
var y = this.phys.y;
var radians = angle * (Math.PI / 180.0);
var x1 = x + radius;
var newX = Math.cos(radians) * (x1 - x) + x;
var newY = Math.sin(radians) * (x1 - x) + y;
if (axis == "x")
{
return newX;
}
else if (axis == "y")
{
return newY;
}
};
}
编辑:对不起,我忘记添加尝试输入碰撞代码了。 我每帧都运行它,但似乎无法检测到它们何时发生碰撞。
objects数组既是屏幕上的每个球又是2个玩家,并且players数组仅包含2个玩家。
//Calculates events, speed and trajectory for paddle collisions
function paddleCollision()
{
for (var obj in objects)
{
for (var player in players)
{
var sAng = players[player].padd.startAngle * (Math.PI / 180.0);
var eAng = players[player].padd.endAngle * (Math.PI / 180.0);
var inR = players[player].padd.innerRadius;
var outR = players[player].padd.outerRadius;
var ballR = objects[obj].phys.radius;
var collides = false;
var dX = objects[obj].phys.x - players[player].phys.x;
var dY = objects[obj].phys.y - players[player].phys.y;
var dist = Math.sqrt((dX ** 2) + (dY ** 2));
var dir = Math.atan2(dY, dX);
var tanAng = Math.asin(ballR / dist);
var dir0 = dir + tanAng;
var dir1 = dir - tanAng;
if (dist + ballR > inR && dist - ballR < outR)
{
var d = dir > sAng && dir < eAng;
var d0 = dir0 > sAng && dir0 < eAng;
var d1 = dir1 > sAng && dir1 < eAng;
if (d || d0 && d1)
{
collides = true;
}
else if (d0 != d1)
{
var x0 = players[player].phys.x + outR * Math.cos(sAng) - objects[obj].phys.x;
var y0 = players[player].phys.y + outR * Math.sin(sAng) - objects[obj].phys.y;
var x1 = players[player].phys.x + outR * Math.cos(eAng) - objects[obj].phys.x;
var y1 = players[player].phys.y + outR * Math.sin(eAng) - objects[obj].phys.y;
if ((x0 ** 2) + (y0 ** 2) < (ballR ** 2) || (x1 ** 2) + (y1 ** 2) < (ballR ** 2))
{
collides = true;
}
}
}
}
}
if (collides)
{
console.log("HITTING");
}
}
答案 0 :(得分:0)
这对我有用:
function arcsCollision(first, second) {
const dx = first.x - second.x;
const dy = first.y - second.y;
const distance = Math.sqrt(dx**2 + dy**2);
return (
distance
<=
(first.radius + second.radius + 0.1)
);
}
function arcAndRectCollision(arc, rect) {
return (
arc.x - arc.radius < rect.x ||
arc.x + arc.radius > rect.width ||
arc.y - arc.radius < rect.y ||
arc.y + arc.radius > rect.height
);
}
你可以去这个网站了解更多信息。 https://spicyyoghurt.com/tutorials/html5-javascript-game-development/collision-detection-physics