首页 文章

Java矩形碰撞交叉点(并不总是有效)

提问于
浏览
0

我目前正在为一个RPG风格的游戏开发一个瓷砖碰撞系统,除了与矩形交叉点的一些不一致之外,它主要工作 .

protected void tileCollision() 
{  
    AnimatedSprite player = findPlayer();
    for(int i = 0; i < _sprites.size(); i++) 
    {
        AnimatedSprite spr = _sprites.get(i);
        for(int j = 0; j < tileWithinRange.length; j++) 
        {
            Tile tile = tileWithinRange[j];
            if(tile != null) 
            {       
                if(tile.getBounds().intersects(player.getBounds())) 
                {
                    player.setCollided(true);
                    tileCollision(player, tile, -1, -1);
                } else 
                {
                    player.setCollided(false);
                }
            }
        }
    }   
}

当我在启动游戏时第一次与瓷砖碰撞时,它总是返回true,但是如果我沿着一列瓷砖移动,我开始得到错误的返回,然后一段时间后我才会得到错误的返回 .

Here is an image of the player intersecting with a tile

这里有一个明显的交集,但在这种情况下,变量碰撞返回false .

交叉口并不总是注册会出现什么问题?`

2 回答

  • 0

    这里的信息太少,无法真正了解发生了什么,但这里的东西看起来很可疑:

    if(tile.getBounds().intersects(player.getBounds())) 
         {
            player.setCollided(true);
            tileCollision(player, tile, -1, -1);
         } else 
         {
            player.setCollided(false);
         }
    

    由于你在一个循环中对着玩家检查多个图块,如果玩家与第一个图块发生碰撞怎么办,但是即使他与前一个图块相撞也没有调用 player.setCollided(false); ,用一个 false 覆盖 true 碰撞状态 . 这可能解释了你在一段时间之后只获得错误返回的行为(可能是因为你检查磁贴的顺序使得你继续用虚假状态覆盖真实状态) .

    我不确定是否有这种副作用是可取的,但至少有一点令人困惑的是,首先打开这种碰撞状态,然后在同一循环中用off覆盖 . 如果这是不合需要的行为,那么如果发生碰撞,或许你所需要的就会突破循环 . 或许你想要的更像是这样的东西:

    player.setCollided(false);
        for(int j = 0; j < tileWithinRange.length; j++) 
        {
            Tile tile = tileWithinRange[j];
            if(tile != null && tile.getBounds().intersects(player.getBounds())) 
            {
                player.setCollided(true);
                tileCollision(player, tile, -1, -1);
            }
        }
    }
    

    或者你的边界/交叉点功能真的发生了故障 - 用这么少的代码/信息来判断它们太难了(我们不知道这些是如何实现的) .

    能够隔离代码并学习如何构建测试用例以独立测试单个函数是很好的 . 你希望通过一个消除过程消除嫌疑人,并通过测试程序让你弄清楚,“好的,这部分在每种情况下都能完美运行,让我们继续下一步 . ”否则它就会成为一个猜测游戏,试图弄清楚出了什么问题 . 在开发过程中浪费时间/ 生产环境 力的最简单方法之一是首先编写一堆代码,然后尝试缩小事后的错误,而不是测试每个小宝贝 . 在你发现错误后,错误会变得更加昂贵,你在调查中必须经历的嫌疑人越多 .

  • 0

    我最终将方法重写为一个布尔值,使其在碰撞时返回true,否则返回false . 这是新代码 .

    public boolean tileCollision() {
        AnimatedSprite player = findPlayer();
        for(int j = 0; j < tileWithinRange.length; j++) {
            Tile tile = tileWithinRange[j];  
            if(tile != null) {
                if(tile.getTileBounds().intersects(player.getBounds()) ) {
                    return true;
                }
            }
        }
        return false;
    }
    

相关问题