简体   繁体   English

2D游戏:如果FPS低于20,则碰撞检测失败

[英]2D Game: Collision Detection fails if FPS below 20

So I just changed my game update function to update alle movements depending on the difference between the actual FPS and the fixed game FPS. 因此,我只是更改了游戏更新功能,以根据实际FPS与固定游戏FPS之间的差异来更新Alle动作。

For example I set my game to a fixed 60 FPS. 例如,我将游戏设置为固定的60 FPS。 If the actual FPS is 20 I calculate the difference like that: 如果实际的FPS为20我将按照以下方式计算差异:

((20 * 100) / 60) / 100 which would result in 0.333 So the difference of 1 game loop would be 1 - 0.333 = 0.677 ((20 * 100) / 60) / 100将得出0.333因此1游戏循环的差为1 - 0.333 = 0.677

Thus all game movements wouldn't be updated based on a normal game loop: 因此,不会根据正常游戏循环来更新所有游戏动作:

x += speedX * 1 but width an increased value: x += speedX * 1.677 x += speedX * 1但宽度增加了一个值: x += speedX * 1.677

So now my game runs at the same speed on every system, just with less pictures, but thats not the problem. 因此,现在我的游戏在每个系统上以相同的速度运行,只需要较少的图片,但这不是问题。

I'm not entirely sure if that causes the collisoin detection to fail, but I guess as the game speed gets increased to match the current fps, the collision detection isn't able to track all events anymore because positions get skipped. 我不确定这是否会导致碰撞检测失败,但是我猜想随着游戏速度的提高以匹配当前的fps,碰撞检测将无法再跟踪所有事件,因为位置会被跳过。 It will only check for collision around the player. 它只会检查玩家周围是否有碰撞。

How do I manage this problem ? 我该如何解决这个问题?

Edit: 编辑:

Here is an example of the collision detection: 这是冲突检测的示例:

var xi = this._game.level.getField(this.x);
var yi = this._game.level.getField(this.y);

var left = this._game.level.levelData["col"][(xi-1) + "," + yi] ? (xi-1) * 32 : null;
var right = this._game.level.levelData["col"][(xi+1) + "," + yi] ? (xi+1) * 32 : null;
var top = this._game.level.levelData["col"][xi + "," + (yi-1)] ? (yi-1) * 32 : null;
var bottom = this._game.level.levelData["col"][xi + "," + (yi+1)] ? (yi+1) * 32 : null;

// Will hit ground ?
if (this.y + this.height >= bottom && bottom != null) {
    this.ground = true;
    if (!this.jumping) this.y = bottom - this.height;
}

// Left
if (this.x <= left + 32 && left != null) {
    this.x = left + 32;
}

// Right
if (this.x + this.width >= right && right != null) {
    this.x = right - this.width;
}

this is the player. this是球员。 and left/right are the collision tile positions on the grid. left/right是网格上的碰撞图块位置。 Each tile is 32x32 and the player is 25x25. 每个图块为32x32,播放器为25x25。

Here is the full game: [removed] 这是完整的游戏:[已删除]

Edit: The problem is actually somewhere else since bottom is not null. 编辑:问题实际上是在其他地方,因为bottom不为null。 When I put the player at bottom - (this.height + 1) instead of bottom - this.height (1 pixel higher), he doesn't allways fall through. 当我将播放器放在bottom - (this.height + 1)而不是bottom - this.height (高1像素)时,他不会一直掉下去。

Im on my phone right now so I can't check out your sample. 我现在正在手机上,所以我无法检查您的样品。 So if I am reading your collision detection stuff right, then you update the players position and then check for a collision. 因此,如果我正确地阅读了您的碰撞检测材料,则可以更新玩家位置,然后检查碰撞。 This, if the frame rate is low enough or the object is moving fast enough, means that an object can "phase" right through a barrier. 如果帧频足够低或物体移动得足够快,则意味着物体可以“穿过障碍物”。 Being entirely on one side of it before the frame update and being entirely on the opposite side of it after the frame update. 在帧更新之前完全位于其一侧,而在帧更新之后完全位于其另一侧。

There are a couple ways to address this problem, the most direct is to not only test where the object is now , but where it's been as well while it moved. 有两种方法可以解决此问题,最直接的方法是不仅测试对象现在所在的位置,还测试对象在移动时的位置。 Implement a collision detection algorithm that detects all the zones that a player or object has to pass through to get from a to b and base your collision on that. 实现碰撞检测算法,该算法检测玩家或对象从a到b所必须经过的所有区域,并基于此进行碰撞。

Also checkout gamedev.stackexchange.com. 还要签出gamedev.stackexchange.com。 It's usually a good place to ask game specific questions. 通常,这是一个问游戏特定问题的好地方。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM