当前位置: 首页 > 知识库问答 >
问题:

Java - 像素完美碰撞 - 玩家和墙壁之间的差距

尉迟韬
2023-03-14

我目前正在开发一个自上而下的射击游戏,在碰撞方面有一些问题。我的世界是瓷砖做的(64x64)。瓦片和实体是矩形。玩家以例如2.74的速度移动(为了更平滑的移动,不以像素为单位)。但是当涉及到玩家(一个实体)和墙之间的碰撞时,我有一些问题。为了检查是否有碰撞,我用我的球员的当前位置和他的移动速度来计算他的下一个位置和是否有碰撞。但我会检查途中的每个像素,所以即使移动速度非常快,我也无法跳过障碍。假设玩家当前的位置是X:200 Y:200,他在X方向移动了2.74像素。我的游戏现在检查在X:201 Y:200,X:202 Y:200或X:202.74 Y:200是否有任何碰撞,如果没有将玩家移动到那个位置。如果我现在试着在x方向移动玩家,在0.26像素远的地方有一面墙,玩家不会移动,留下一个微小的间隙。我试图计算球员和墙之间的距离,并将这个量加到球员的位置上,但为此我需要知道球员撞到了墙的哪一边。我也希望玩家能够上下移动,当他碰到的墙在他面前时,反之亦然。

这是我的碰撞方法(Java):

public static boolean collision(float ex, float ey, int width, int height) { // ex, ey would be the next position of the player
    if (ex < 0 || ex + width > worldWidth || ey < 0 || ey + height > worldHeight) return true; // checks if this position is in the world
    int firstTileX = (int) (ex / Tile.TILE_SIZE); // calculates tiles he could possible collide width
    int firstTileY = (int) (ey / Tile.TILE_SIZE);
    int lastTileX = (int) ((ex + width - 1) / Tile.TILE_SIZE);
    int lastTileY = (int) ((ey + height - 1) / Tile.TILE_SIZE);
    for (int y = firstTileY; y <= lastTileY; y++) {
        if (y < 0) continue; // checks for out of bounds 
        if (y >= worldTileHeight) break;
        for (int x = firstTileX; x <= lastTileX; x++) {
            if (x < 0) continue;
            if (x >= worldTileWidth) break;
            if (tiles[y][x].solid) return true; // if the tile is solid -> collision found
        }
    }
    return false; // no collision found
}

我的运动方法是:

public void move(float xa, float ya) {
    float nx, ny;
    while (xa != 0 || ya != 0) {
        nx = x;
        ny = y;
        if (xa != 0) {
            if (Math.abs(xa) > 1) { // if the x-speed is greater than 1
                nx = x + MathUtil.abs(xa); // returns -1 for negative numbers and 1 for positiv
                xa -= MathUtil.abs(xa);
            } else { // less than 1
                nx = x + xa;
                xa = 0;
            }
        }
        if (ya != 0) { // same here
            if (Math.abs(ya) > 1) {
                ny = y + MathUtil.abs(ya);
                ya -= MathUtil.abs(ya);
            } else {
                ny = y + ya;
                ya = 0;
            }
        }
        if (!Level.collision(nx, ny, width, height)) setPosition(nx, ny); // checks if there is an collision and sets the new position if not
        else if (!Level.collision(nx, y, width, height)) x = nx; // if there was a collision check if the player can walk in x direction
        else if (!Level.collision(x, ny, width, height)) y = ny; // or in y direction
    }
}

我的问题与CoderMusgrove在他的帖子(像素完美碰撞和双打)中的问题几乎相同:

摘要

我有一个问题,如果一个实体的速度大于它要进入的图块的距离,它会在自己和图块之间留下至少一个像素,我真的不喜欢这样。我可以使用什么样的算法来找到实体和图块之间的最小差异?

如果您需要任何其他信息,我将很乐意添加它。

谢谢你的帮助!

共有1个答案

梁明辉
2023-03-14

通过更改您的解释,可以轻松解决。

为了细粒度速度的目的,您保留了一个分数位置。忽略分数是为了冲突检测和显示(如果您要进行子像素渲染,请在子像素渲染精度级别上进行冲突)。

int screenX = (int) Math.round(objX);
int screenY = (int) Math.round(objY);
// rendering and collision detection based on rounded position
 类似资料:
  • 我知道已经有一些关于墙壁碰撞的问题了,但是这些答案中的技术都没有帮助我。我正在做一个没有重力的自上而下的探索游戏。运动很好,但是一旦我制造了墙壁和碰撞,它就开始出现故障并传送。我已经包含了(并大大减少了)我认为问题所在的两个功能,在底部我包含了整个代码。 根据pygame精灵墙碰撞的建议,我分割了x和y墙碰撞代码。墙壁碰撞代码基于https://github.com/marcusmoller/py

  • 问题内容: 我找到了像素完美碰撞检查的代码,并在我的代码中使用了它: 它运行完美,从来没有任何问题。直到我使用以下代码将图像设置为Config_Alpha_8为止(由于ram问题): 为什么什么都不会发生,它确实被CollisioDetected装入了,我已经检查了日志!但是它不会检测到冲突。有人可以使用config_alpha_8提供工作功能来检查位图的像素完美冲突吗? 问题答案: 在具有ALP

  • 问题内容: 好的,我正在研究Android上的游戏。我需要实现像素完美碰撞检测。我已经在每个图像周围设置了边界框,每个边界框都进行了转换以匹配图像的当前旋转。一切都很好。我还将每个位图的像素数据存储在数组中。有人可以帮我找出检测像素是否重叠的最有效方法吗?在此先感谢您的帮助! 问题答案: 基本思想是为每个对象创建一个位掩码,您可以在每个像素中指示该对象是否实际存在。然后,比较两个对象的位掩码的每个

  • 我已经尝试解决了平滑的玩家-墙壁碰撞的问题,这样玩家可以沿着墙壁滑动。 我尝试了以下内容: 但是如果玩家碰到了墙,他不会滑动...他只是停下来了。(我对W,A,S,D也是分开做的。) 只有当我将玩家位置设置回他正在触摸的墙壁位置时,它才有效。如下: 但是它不起作用,因为对于与另一面墙相连的墙,玩家会接触更多的边,玩家会跳到角落...所以它只适用于一面墙... 我的问题是:如何以另一种方式使玩家与墙

  • 我试图在Cocos2d-x中移植像素完美冲突检测,原始版本是为Cocos2D制作的,可以在这里找到:http://www.cocos2d-iphone.org/forums/topic/pixel-perfect-collision-detection-using-color-blending/ 这是我的Cocos2d-x版本代码 如果我将“pp”参数发送为false,则我的代码工作正常。也就是说

  • 所以我目前正在尝试做一个几乎像迷宫一样的游戏。问题是墙壁碰撞,一旦角色撞到墙上,我就不能再把他弄出来了,不管碰撞后我试图带他去哪个方向,他都会被“卡住”。我想的一个解决方案是,每当角色撞到墙上时,“支持他”,这样就不会再检测到碰撞。然而,当我这样做的时候,他以一种奇怪的方式穿墙。这是我的代码,所以你们可以知道我在做什么: 这段代码的很大一部分实际上是从另一个问同样问题的人那里得到的。即使按照另一个