因此,我目前正在重新发明轮子(并学到很多东西),尝试为我的游戏引擎制作一个简单的物理引擎。我一直在互联网上搜索,尝试(但失败)解决我当前的问题。关于这个主题有很多资源,但我发现的资源似乎都不适用于我的情况。
问题简而言之:当两个矩形碰撞时,碰撞分辨率在某些角上无法按预期工作。失败的方式因矩形的尺寸而异。我正在寻找的是一种“最短重叠”的碰撞解决方案或另一个相当简单的解决方案(我愿意接受建议!)。(向下滚动以获得更好的解释和插图)。
警告:以下代码可能不是很有效......
首先,这是我的物理循环。它只是循环遍历所有游戏实体并检查它们是否与任何其他游戏实体发生碰撞。它效率不高(n^2 等等),但目前有效。
updatePhysics: function(step) {
// Loop through entities and update positions based on velocities
for (var entityID in Vroom.entityList) {
var entity = Vroom.entityList[entityID];
if (entity.physicsEnabled) {
switch (entity.entityType) {
case VroomEntity.KINEMATIC:
entity.pos.x += entity.vel.x * step;
entity.pos.y += entity.vel.y * step;
break;
case VroomEntity.DYNAMIC:
// Dynamic stuff
break;
}
}
}
// Loop through entities and detect collisions. Resolve collisions as they are detected.
for (var entityID in Vroom.entityList) {
var entity = Vroom.entityList[entityID];
if (entity.physicsEnabled && entity.entityType !== VroomEntity.STATIC) {
for (var targetID in Vroom.entityList) {
if (targetID !== entityID) {
var target = Vroom.entityList[targetID];
if (target.physicsEnabled) {
// Check if current entity and target is colliding
if (Vroom.collideEntity(entity, target)) {
switch (entity.collisionType) {
case VroomEntity.DISPLACE:
Vroom.resolveTestTest(entity, target);
break;
}
}
}
}
}
}
}
},
这是实际碰撞检测的代码。这似乎也可以正常工作。
collideEntity: function(entity, target) {
if (entity.getBottom() < target.getTop() || entity.getTop() > target.getBottom() || entity.getRight() < target.getLeft() || entity.getLeft() > target.getRight()) {
return false;
}
return true;
},
这就是问题开始出现的地方。我希望实体只是被“推”出目标实体,并将速度设置为 0。只要实体和目标都是完美的正方形,这种方法就可以正常工作。如果假设实体(gif 中的玩家人物)是一个矩形,那么当最长边(X 轴)与目标(正方形)碰撞时,碰撞将会“滑动”。如果我交换播放器尺寸,使其又短又宽,那么 Y 轴也会出现同样的问题。
resolveTestTest: function(entity, target) {
var normalizedX = (target.getMidX() - entity.getMidX());
var normalizedY = (target.getMidY() - entity.getMidY());
var absoluteNormalizedX = Math.abs(normalizedX);
var absoluteNormalizedY = Math.abs(normalizedY);
console.log(absoluteNormalizedX, absoluteNormalizedY);
// The collision is comming from the left or right
if (absoluteNormalizedX > absoluteNormalizedY) {
if (normalizedX < 0) {
entity.pos.x = target.getRight();
} else {
entity.pos.x = target.getLeft() - entity.dim.width;
}
// Set velocity to 0
entity.vel.x = 0;
// The collision is comming from the top or bottom
} else {
if (normalizedY < 0) {
entity.pos.y = target.getBottom();
} else {
entity.pos.y = target.getTop() - entity.dim.height;
}
// Set velocity to 0
entity.vel.y = 0;
}
},
Collision on the Y axis works with these shapes
Collision on the X axis slips with these shapes
我该怎么做才能解决这个打滑问题?在过去的 5 天里,我一直在努力解决这个问题,所以如果有人能帮助我朝正确的方向前进,我将不胜感激!
谢谢 :)
- 编辑: -
如果仅沿左侧或右侧的一个方向移动,也会发生滑动。
-- 编辑 2 工作代码:--请参阅下面我的回答以获取工作代码的示例!