advanced Collision detection?

Hi i'm currently making an RPG similar to Legend of Zelda. I have a feature in my game where when Player attacks enemy with his sword, the enemy is knocked back n units. i have a collision detection that sometimes works as intended, and other times the enemy goes through the wall and gets stuck on the other side, and then other times the enemy can simply walk right through the wall. If possible, making the enemy move toward player upon collision with wall would be one possible solution to this problem I believe, but I do not know how to implement this. Here is my current collision code:

// 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++;
        }

I have no idea why the enemy is able to sometimes simply walk right through the wall without being knocked back. So how can I fix this, any ideas?


Without reading the code completely I can already tell you that your collision detection code is wrong. Mostly because you are moving your objects directly, probably without checking for collisions within your rect::move function.

It is possible that the rect::move function will move objects through the walls without triggering any collision reaction code. Consider the following scenario:

First frame:

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

Second frame:

The enemy object is moved behind the wall and will not trigger the collision detection code.

My advise is (despite the obvious one: read some books): for each enemy store its previous location and check for collision not between the enemy and the wall's rectangle but between wall and a rectangle between two enemy positions. Something like that:

This is of course only one of the possible scenarios when your collision detection code would be error-prone.

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

上一篇: Visual Studio 2010项目不编译

下一篇: 先进的碰撞检测?