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

基于瓦片的碰撞;拐角碰撞问题

史景铄
2023-03-14

我在我的自上而下的游戏中实现了一个简单的基于瓷砖的碰撞系统,但是我在跨角移动方面遇到了问题。目前,我的程序采取了玩家的中心点,并在一个20px的正方形网格(交替的灰色背景)上做出一个瓷砖。它检查上、下、左、右贴图是否有冲突,如果找到冲突,它就进入下一个阶段。

下一个阶段是检查玩家在瓷砖内的位置。为此,我有一个名为getCenterDistanceFromCurrentTile()的函数(我知道有创意的名字)。这将返回从瓷砖的中心点到玩家的中心点的距离的向量2i(x和y)。然后我以以下方式使用它;

  • 如果左侧有一个墙砖,并且玩家的x距离<0(玩家在当前砖中心点的左侧),则玩家被移动到墙旁边的砖的x处。
  • 如果右侧有一堵墙,并且玩家的x距离>0(当前瓷砖中心点的右侧),则玩家将移动到该墙旁边的瓷砖的x处。
  • 对于Y轴,这将以相同的方式继续。

我的问题是对角线。我目前不检查对角线冲突,但它似乎我将不得不。我已经做了一个尝试去实现它,但是当他们打到一个角球的时候球员跳来跳去。我在一起使用上面的玩家x<0和玩家y<0的方法,结果没有奏效。我制作了一些图像来更好地解释我的问题。

这张图片显示了我的碰撞系统工作良好,左边有一个碰撞(由蓝色瓷砖显示),粉红色瓷砖被检查,但没有发现碰撞。绿色的瓷砖显示玩家当前的瓷砖,红色的方块显示玩家当前的位置。

这张图像清楚地表明了我的问题。没有粉色瓷砖与任何东西碰撞,因此玩家的x和y不需要检查。

我当前的冲突检查代码;

public boolean isWall(Vector2i loc)
{
    return this.isWall(loc.x, loc.y);
}

public boolean isWall(int x, int y)
{
    if (x < 0) return true;
    if (y < 0) return true;
    if (y > map[0].length-1) return true;
    if (x > map.length-1) return true;
    return map[x][y];
}

public void phys(Player plr) {
    Vector2i playerTile = plr.getTile();
    // Left
    if (isWall(playerTile.x-1, playerTile.y))
    {
        Vector2i distanceFromTile = plr.getCenterDistanceFromCurrentTile(true);
        if (distanceFromTile.x < 0)
        {
            plr.setX(playerTile.x*BLOCK_SIZE);
        }
    }
    // Right
    if (isWall(playerTile.x+1, playerTile.y))
    {
        Vector2i distanceFromTile = plr.getCenterDistanceFromCurrentTile(true);
        if (distanceFromTile.x > 0)
        {
            plr.setX(playerTile.x*BLOCK_SIZE);
        }
    }
    // Up
    if (isWall(playerTile.x, playerTile.y-1))
    {
        Vector2i distanceFromTile = plr.getCenterDistanceFromCurrentTile(true);
        if (distanceFromTile.y < 0)
        {
            plr.setY(playerTile.y*BLOCK_SIZE);
        }
    }
    // Down
    if (isWall(playerTile.x, playerTile.y+1))
    {
        Vector2i distanceFromTile = plr.getCenterDistanceFromCurrentTile(true);
        if (distanceFromTile.y > 0)
        {
            plr.setY(playerTile.y*BLOCK_SIZE);
        }
    }
}

共有1个答案

范书
2023-03-14

您的phys方法可以返回布尔值,这取决于玩家是否与任何墙壁发生碰撞。然后,您可以使用该函数的结果来决定是否移动到移动之前所在的空间中的前一个位置,或者如果没有碰撞,则继续移动。

这将需要你检查所有邻近的墙壁周围的播放器。这将在phys方法中引入一种更简洁的方法来迭代冲突检查。

这样的改进看起来是:

public boolean phys(Player plr)
{
    java.awt.Rectangle playerBounds = new java.awt.Rectangle(plr.x, plr.y, BLOCK_SIZE, BLOCK_SIZE);

    for (int y = 0; y < 3; y++)
    {
        for (int x = 0; x < 3; x++)
        {
            // Skip the tile the player is on assuming that he is not on a wall already
            if (x == 1 && y == 1) continue;

            java.awt.Rectangle bounds = new java.awt.Rectangle(/*tile at (x, y) xpos*/, /*tile at (x, y) ypos*/, BLOCK_SIZE, BLOCK_SIZE);

            if (bounds.intersects(playerBounds))
            {
                return true;
            }
        }
    }

    // Did not collide
    return false;
}
 类似资料:
  • 我有一些关于碰撞角度的问题。我正在尝试为一个游戏编写物理代码,我不想使用任何第三方库,实际上我想自己编写每一个东西。我知道如何检测两个球体之间的碰撞,但我不知道如何找到两个球体之间的碰撞/斥力角。我试过扭转物体的方向,但没有成功。如果你把我链接到一个有趣的.pdf文件教物理编程,那将是非常好的。

  • 所以我在为我的平台游戏编写攻击方法时,我注意到我的游戏中的碰撞行为很奇怪,当我向敌人发起攻击(我的游戏中的火球)时没有损坏的记录,我添加了一个打印声明来检查他们是否失去任何生命值和没有记录,但是当我按住攻击方法(这是空格键)时,敌人上记录了多个攻击。 玩家角色是蓝色的,敌人是绿色的。 控制台显示敌人的生命值下降,但仅当空格键被按住时。 同样,当我走进敌人的精灵时,我点击一次空格键,我也能以这种方式

  • 我正在做一个突破克隆,在球与桨的碰撞中遇到了一些小麻烦。我用一个矩形表示球和桨,当它们相交时,表示球速度的Y向量为负数(如下所示)。这一切都很好。问题是当球拍向右移动时,我希望它将球稍微向右移动(与正常反射相反),我希望在相反方向发生相同的情况,即球拍向左移动。我不知道该怎么做,我已经找遍了。任何帮助都将不胜感激。谢谢 编辑:基本上我想根据球拍移动的方向稍微改变球从球拍上反弹的角度。如果桨叶不移动

  • 你是否看到过车祸?是否跟什么物体相撞过?就像车的相撞一样,刚体对象也可以互相碰撞,当它们互相接触的时候,就认为发生了碰撞。当碰撞发生时,会触发一系列事件,它可以被完全忽略。 碰撞筛选 碰撞筛选允许你启用或者阻止形状之间碰撞的发生,引擎支持使用类型,组位掩码来进行碰撞筛选。 Cocos2d-x 有 32 个支持的碰撞类型,对于每个形状都可以指定其所属的类型。还可以指定有哪些类型可以与这个形状进行碰撞

  • 我正在尝试做一个平台游戏,其中没有斜坡。我正在尝试将碰撞检测降下来,但是我在pygame中找不到一种方法来获得哪一边与另一个Sprite发生了碰撞。有没有人能给我一个好的方法来做到这一点,那不是太庞大,但也能很好地工作在我的情况? 下面是我的玩家类: 我已经将它添加到我的player类中,每次播放器更新时我都运行它,并且它工作...差一点。 在平台顶部的碰撞起作用,在侧面的碰撞几乎总是起作用,除非

  • 我已经寻找并找到了单个碰撞的答案,但我正在寻找一种检测多种类型的碰撞的方法。我正在制作一个游戏,其中有3个我想要的碰撞。用户飞机与敌方子弹相撞,用户子弹与敌机相撞(我已经工作过),敌方子弹与用户子弹相撞。我已经设置并更正了所有类别BitMask和contactTestBitMask。这是我的委托方法。