在我的碰撞检测系统上使用EaselJS进行迷你游戏开发时遇到问题,我需要别人的帮助。当英雄(一个圆形位图)与一个对象碰撞,并且第一个对象后面还有另一个对象时,即使第二个碰撞被阻止,英雄也会与两个对象碰撞,就会发生此问题。这是图片说明:
问题的原因确实很简单,即使问题本身并非如此:
该碰撞检测系统基于圆的 future 位置(而不是其实际位置),然后,如果圆的下一个位置与矩形相交,它将反弹。问题是,如果将来的位置与两个矩形相交,则该圆将在两个矩形中反弹-即使实际的圆运动被另一个矩形阻止并且无法到达第二个矩形。
更新:请注意,仅由于由于rect创建顺序而按住向上箭头时才会发生此问题。
这是相关的JavaScript代码:
rects.forEach(function (rect) { // Affect all rects
// Collision detection:
// (This MUST BE after every change in xvel/yvel)
// Next circle position calculation:
var nextposx = circle.x + event.delta / 1000 * xvel * 20,
nextposy = circle.y + event.delta / 1000 * yvel * 20;
// Collision between objects (Rect and Circle):
if (nextposy + height(circle) > rect.y &&
nextposx + width(circle) > rect.x &&
nextposx < rect.x + rect.width &&
nextposy < rect.y + rect.height) {
if (circle.y + height(circle) < rect.y) {
cls("top");
}
if (circle.x + width(circle) < rect.x) {
cls("left");
}
if (circle.x > rect.x + rect.width) {
cls("right");
}
if (circle.y > rect.y + rect.height) {
cls("bottom");
}
}
// Stage collision:
if (nextposy < 0) { // Collided with TOP of stage. Trust me.
cls("bottom"); // Inverted collision side is proposital!
}
if (nextposx < 0) {
cls("right");
}
if (nextposx + width(circle) > stage.canvas.width) {
cls("left");
}
if (nextposy + height(circle) > stage.canvas.height) {
cls("top");
}
});
JSFiddle
最佳答案
您必须分别处理水平和垂直碰撞。
我对您的JS fiddle 做了一些小的更改:http://jsfiddle.net/Kf6cv/1/
它现在应该可以正常工作,我所做的是将您的一张支票分成两张:
if (nextposy + height(circle) > rect.y &&
circle.x + width(circle) > rect.x &&
circle.x < rect.x + rect.width &&
nextposy < rect.y + rect.height) {
if (circle.y + height(circle) < rect.y) {
cls("top");
}
if (circle.y > rect.y + rect.height) {
cls("bottom");
}
}
if (nextposx + width(circle) > rect.x &&
nextposx < rect.x + rect.width &&
circle.y + height(circle) > rect.y &&
circle.y < rect.y + rect.height) {
if (circle.x + width(circle) < rect.x) {
cls("left");
}
if (circle.x > rect.x + rect.width) {
cls("right");
}
}
这样做的原因是,如果立即检查两个方向,即使它可能向一个方向移动,也将防止两个方向的移动(或使其反弹)(如图片中的红色数字)。通常,水平/垂直检查的顺序无关紧要,通常仅在“英雄”以100%的边对边方法接近另一个对象时才重要。但是您可以做的是先检查较高方向的方向,因此| velX | > | velY |然后您首先检查水平碰撞。
我还要说,检查后直接应用新位置比较安全,现在它先进行两次独立检查,然后应用两个方向的移动-我不确定,但是我可以想象这可能导致稍后一些问题。