Javascript冲突检测系统don';不要忽略阻塞碰撞
我在使用EaselJS和碰撞检测系统开发小型游戏的过程中遇到了问题,我需要别人的帮助。当英雄(圆形位图)碰撞一个对象,并且第一个对象后面有另一个对象时,就会发生问题,即使第二个碰撞被阻止,英雄也会与两个对象碰撞。以下是图像说明: 问题的原因非常简单,即使问题本身不是:Javascript冲突检测系统don';不要忽略阻塞碰撞,javascript,jquery,html,collision-detection,easeljs,Javascript,Jquery,Html,Collision Detection,Easeljs,我在使用EaselJS和碰撞检测系统开发小型游戏的过程中遇到了问题,我需要别人的帮助。当英雄(圆形位图)碰撞一个对象,并且第一个对象后面有另一个对象时,就会发生问题,即使第二个碰撞被阻止,英雄也会与两个对象碰撞。以下是图像说明: 问题的原因非常简单,即使问题本身不是: rects.forEach(function (rect) { // Affect all rects // Collision detection:
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");
}
});
该碰撞检测系统基于圆的未来位置(而不是其实际位置),如果圆的下一个位置与矩形相交,它将反弹。问题是,如果未来位置与两个矩形相交,则圆将在两个矩形中反弹-即使实际的圆移动被另一个矩形阻挡,并且无法到达第二个矩形
更新:请注意,此问题仅在由于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");
}
});
rects.forEach(函数(rect){//影响所有的rect
//碰撞检测:
//(这必须在xvel/yvel的每次更改后进行)
//下一个圆位置计算:
var nextposx=circle.x+event.delta/1000*xvel*20,
nextposy=circle.y+event.delta/1000*yvel*20;
//对象之间的碰撞(矩形和圆形):
如果(下一个方向+高度(圆)>矩形y&&
下一步OSX+宽度(圆形)>矩形x&&
nextposx矩形x+矩形宽度){
cls(“权利”);
}
if(圆y>矩形y+矩形高度){
cls(“底部”);
}
}
//舞台碰撞:
如果(nextposy<0){//与舞台顶部碰撞。相信我。
cls(“底部”);//建议反向碰撞侧!
}
if(nextposx<0){
cls(“权利”);
}
if(nextposx+width(圆圈)>stage.canvas.width){
cls(“左”);
}
if(nextposy+height(圆圈)>stage.canvas.height){
cls(“top”);
}
});
您必须独立处理水平和垂直碰撞 我对你的JS小提琴做了一些小改动: 现在应该可以了,我所做的是把你的一张支票分成两张:
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");
}
}
if(nextposy+height(圆圈)>rect.y&&
圆x+宽度(圆)>矩形x&&
圆x<矩形x+矩形宽度&&
下一个多边形<矩形y+矩形高度){
if(圆y+高度(圆)矩形y+矩形高度){
cls(“底部”);
}
}
if(nextposx+宽度(圆)>矩形x&&
nextposx矩形y&&
圆y<直线y+直线高度){
if(圆x+宽度(圆)矩形x+矩形宽度){
cls(“权利”);
}
}
原因是,如果同时检查两个方向,它将阻止两个方向的移动(或使其反弹)(如图片中的红色数字)-即使它可以移动到一个方向。检查水平/垂直的顺序通常并不重要,通常只有当你的“英雄”100%边对边接近另一个对象时才重要。但你能做的是首先检查速度较高的方向,所以如果| velX |>velY |那么你首先检查水平碰撞
而且我要说的是,检查后直接申请新职位更安全,现在,它进行两次独立检查,然后应用两个方向的移动-我不确定,但我可以想象这可能会导致以后出现一些问题。这解决了我的第一个问题,因为它只是取消了对100%边到边碰撞的支持,产生一个新问题:没有边到边的碰撞。如果我检查哪个方向的速度更高,当
yvel==xvel
时会发生什么?如果在本例中,yvel>xvel
,那么也会有边到边的碰撞,因为您使用的是boinding box。但这是一种罕见的情况,仅当您的圆的边界框的右上边缘直接位于碰撞矩形的左下边缘时才有关系。如果先选中“水平”,则球将位于矩形的右下方;如果先选中“垂直”,则球将位于矩形的左侧。但是这些案例非常罕见,它们几乎不会发生——无论如何,如果你想抓住这些案例,你可以先使用更高的速度。(如果它们相等,只需使用标准案例)您的问题仅在按下“向上”和“左/右”时发生-原因是,您的检测在一步中检查两个方向,并优先选择水平碰撞。对于您的问题,您将得到的唯一“解释”是使用调试器逐步检查代码,并了解代码的实际功能。。。你现在要求的是有人为你解释你自己编写的代码。我已经更新了这个问题