先进的碰撞检测?

嗨,我目前正在制作类似于塞尔达传说的RPG。 我的游戏中有一个特点,当玩家用剑攻击敌人时,敌人被击退n个单位。 我有一个碰撞检测,有时按预期工作,有时候敌人穿过墙壁并卡在另一边,然后有时候敌人可以直接穿过墙壁。 如果可能的话,让敌人在与墙相撞时向玩家移动将是我相信这个问题的一种可能的解决方案,但我不知道如何实现这一点。 这是我目前的碰撞代码:

// Enemy Collides with Wall
        counter1 = 0;
        for (iter4 = enemyArray.begin(); iter4 != enemyArray.end(); iter4++)
        {
            counter2 = 0;
            for (iter15 = wallArray.begin(); iter15 != wallArray.end(); iter15++)
            {
                if (enemyArray[counter1].rect.getGlobalBounds().intersects(wallArray[counter2].rect.getGlobalBounds()))
                {
                    enemyArray[counter1].isCollided = true;
                        //Hit Wall
                    if ((enemyArray[counter1].direction == 1 || enemyArray[counter1].rect.getPosition().y >= wallArray[counter2].rect.getPosition().y)) //up
                        {
                            enemyArray[counter1].canMoveUp = false;
                            enemyArray[counter1].canMoveLeft = false;
                            enemyArray[counter1].canMoveRight = false;
                            enemyArray[counter1].rect.move(0, 7);
                        }
                    else if ((enemyArray[counter1].direction == 2 || enemyArray[counter1].rect.getPosition().y <= wallArray[counter2].rect.getPosition().y)) //Down
                        {
                            enemyArray[counter1].canMoveDown = false;
                            enemyArray[counter1].canMoveRight = false;
                            enemyArray[counter1].canMoveLeft = false;
                            enemyArray[counter1].rect.move(0, -7);
                        }
                    else if ((enemyArray[counter1].direction == 3 || enemyArray[counter1].rect.getPosition().x >= wallArray[counter2].rect.getPosition().x)) //Left
                        {
                            enemyArray[counter1].canMoveLeft = false;
                            enemyArray[counter1].canMoveUp = false;
                            enemyArray[counter1].canMoveDown = false;
                            enemyArray[counter1].rect.move(7, 0);
                        }
                    else if ((enemyArray[counter1].direction == 4 || enemyArray[counter1].rect.getPosition().x <= wallArray[counter2].rect.getPosition().x)) //Right
                        {
                            enemyArray[counter1].canMoveRight = false;
                            enemyArray[counter1].canMoveUp = false;
                            enemyArray[counter1].canMoveDown = false;
                            enemyArray[counter1].rect.move(-7, 0);
                        }
                }
                counter2++;
            }
            counter1++;
        }



//Knock Back enemy away from sword && sword2
        counterKnockBack++;
        counter2 = 0;
        for (iter4 = enemyArray.begin(); iter4 != enemyArray.end(); iter4++)
        {
                    if (enemyArray[counter2].knockback == true)
                    {
                        if (enemyArray[counter2].isCollided == false)
                        {
                            if ((Player1.rect.getPosition().y > enemyArray[counter2].rect.getPosition().y))
                            {
                                enemyArray[counter2].rect.move(0, -3);  //up
                            }
                            else if ((Player1.rect.getPosition().y < enemyArray[counter2].rect.getPosition().y))
                            {
                                enemyArray[counter2].rect.move(0, 3);    //down
                            }
                            if ((Player1.rect.getPosition().x > enemyArray[counter2].rect.getPosition().x))
                            {
                                enemyArray[counter2].rect.move(-3, 0);   //left
                            }
                            else if ((Player1.rect.getPosition().x < enemyArray[counter2].rect.getPosition().x))
                            {
                                enemyArray[counter2].rect.move(3, 0);    //right
                            }
                            if (counterKnockBack >= 20)
                            {
                                enemyArray[counter2].knockback = false;
                            }
                        }
                    }
            counter2++;
        }

        //turn off collided counter
        counterCollided++;
        counter2 = 0;
        for (iter4 = enemyArray.begin(); iter4 != enemyArray.end(); iter4++)
        {
            if (enemyArray[counter2].isCollided == true)
            {
                if (counterCollided >= 30)
                    enemyArray[counter2].isCollided = false;
            }
            counter2++;
        }

我不知道为什么敌人有时能够在没有被击倒的情况下直接穿过墙壁。 那么我该如何解决这个问题呢?


如果不完全阅读代码,我已经可以告诉你,你的碰撞检测代码是错误的。 主要是因为你直接移动你的对象,可能没有检查你的rect::move函数中的冲突。

rect::move函数可能会将对象移动穿过墙壁,而不会触发任何碰撞响应代码。 考虑以下情况:

第一帧:

enemyArray[counterX].rect.move(3, 0);

第二帧:

敌方目标移动到墙后,不会触发碰撞检测代码。

我的建议是(尽管显而易见的是:读一些书):为每个敌人存储它的前一个位置,并检查敌人和墙壁的矩形之间的碰撞,但是在墙壁和两个敌人位置之间的矩形之间。 类似的东西:

当然,这只是碰撞检测代码容易出错的可能场景之一。

链接地址: http://www.djcxy.com/p/95573.html

上一篇: advanced Collision detection?

下一篇: AABB Collision response(Push back colliding objects)