javascript - 球与弧、弧与弧的碰撞检测
问题描述
我正在用 JavaScript 制作一个乒乓球风格的游戏,其中桨是弯曲的。我已经在 2 个球之间发生了碰撞,但我似乎对球和弧线有问题。
我已经看过这个线程了:
但我似乎无法让那里的答案对我有用。也许是因为我画的弧线不同。这是我的变量以及桨如何被绘制到画布上。当玩家按下一个键时,桨的角度会增加,因此它围绕玩家旋转。
如果有人可以提供帮助,我将不胜感激。
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 名球员,而 player 数组只包含 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");
}
}
解决方案
这对我有用:
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
推荐阅读
- python - 使用 python 请求弹出身份验证
- java - 使用 Java、Spring 和 Spring Boot 在特定列上设置监听器
- wordpress - 手动向新用户发送包含帐户详细信息的 Wordpress 电子邮件?
- r - 如何在 Shiny R 中修改条件面板中的标题
- java - 如何比较可选
与长 - java - Spring Boot - 如何通过带有查询参数的 url 发送 POST 请求并将响应存储在方法中?
- c++ - 跨文件访问全局变量
- arrays - React - Redux:存储中的数组未正确更新
- javascript - 用于提取 URL 特征的 Chrome 扩展内容脚本
- javascript - Playwright Allure 报告没有显示我之前的试运行视频?