0
\$\begingroup\$

briefly, this is the overall look and feel of my game: enter image description here I have a player and I have an enemy in my map. i tried to learn collision from SaladRaider Youtube channel. collision using chasing method works fine but because of adding Chase and Wander behaviour i implement MSDN Sample on my project instead of the previous simple chasing method. everything works correctly except collision detection for my enemy. when the enemy collides with wall, it just stop at there. this is the code for my collision: the Collision function :

    public bool Collision(Vector2 pos, Obj obj)
    {
        Rectangle newArea = new Rectangle(area.X, area.Y, area.Width, area.Height);
        newArea.X += (int)pos.X;
        newArea.Y += (int)pos.Y;

        foreach (Obj o in Items.objList)
        {
            if (o.GetType() == obj.GetType() && o.solid)
                if (o.area.Intersects(newArea))
                    return true;
        }
        return false;
    }

and my Checking collision function for wander behaviour:

    public void WanderPushTo(float pix, float dir)  //pix is speed, dir is direction
    {
        float newX = (float)Math.Cos(dir);
        float newY = (float)Math.Sin(dir);
        newX *= pix;
        newY *= pix;

        if (!Collision(new Vector2(newX, newY), new Wall(Vector2.Zero)))
        {
            float MYnewX = (float)Math.Cos(dir);
            float MYnewY = (float)Math.Sin(dir);
            enemyPosition.X += pix * (float)MYnewX;
            enemyPosition.Y += pix * (float)MYnewY;
        }
        else if (enemyState == enemyAiState.Wander)
        {
            float MYnewX = (float)Math.Cos(-dir);
            float MYnewY = (float)Math.Sin(-dir);
            enemyPosition.X += pix * (float)MYnewX;
            enemyPosition.Y += pix * (float)MYnewY;
        }
    }

as you see, i just tried to make the direction as negative when it has a collision with wall ( and the reason is when my enemy was collides with wall, it just stop at that place and doesn't move. i added that "else if" to solve the issue. now it just trace the wall instead of stopping at that position). but unfortunately it just solve my issue when i collide with wall from up and down. it doesn't work when i collide with wall from left and right. to solve this issue, i think i have to turn the pix as negative instead of dir when my enemy collides with wall from left or right. but i don't know how i can check whether my enemy collides from left or right. (fyi, on chasing method, it works without any issue, because the direction is always on the player. but in wander, the direction is random. that's why it doesn't work) do you have any suggestion how to check whether the enemy collides from left or right of the wall ? this is my Chase and Wander Update function:

        public void UpdateEnemy(Vector2 playerPosition)
    {
        // First we have to use the current state to decide what the thresholds are
        // for changing state, as described in the doc.
        float enemyChaseThreshold = enemyChaseDistance;
        float enemyCaughtThreshold = enemyCaughtDistance;


        if (enemyState == enemyAiState.Wander)
        {
            enemyChaseThreshold -= enemyHysteresis / 2;
        }
        else if (enemyState == enemyAiState.Chasing)
        {
            enemyChaseThreshold += enemyHysteresis / 2;
            enemyCaughtThreshold -= enemyHysteresis / 2;
        }
        else if (enemyState == enemyAiState.Caught)
        {
            enemyCaughtThreshold += enemyHysteresis / 2;
        }

        float distanceFromPlayer = Vector2.Distance(enemyPosition, playerPosition);
        if (distanceFromPlayer > enemyChaseThreshold)
        {
            enemyState = enemyAiState.Wander;
        }
        else if (distanceFromPlayer > enemyCaughtThreshold)
        {
            enemyState = enemyAiState.Chasing;
        }
        else
        {
            enemyState = enemyAiState.Caught;
        }

        // Third, once we know what state we're in, act on that state.
        float currentEnemySpeed;
        if (enemyState == enemyAiState.Chasing)
        {
            ViewDirection = enemyOrientation = TurnToFace(enemyPosition, playerPosition, enemyOrientation,
                enemyTurnSpeed);
            currentEnemySpeed = MaxEnemySpeed;
        }
        else if (enemyState == enemyAiState.Wander)
        {
            Wander(enemyPosition, ref tankWanderDirection, ref enemyOrientation,
                enemyTurnSpeed);
            currentEnemySpeed = .25f * MaxEnemySpeed;
        }
        else
        {
            currentEnemySpeed = 0.0f;
        }

        WanderPushTo(currentEnemySpeed, enemyOrientation);
    }

and my Wander function :

        private void Wander(Vector2 position, ref Vector2 wanderDirection,
                        ref float orientation, float turnSpeed)
    {


        wanderDirection.X +=
            MathHelper.Lerp(-.25f, .25f, (float)random.NextDouble());
        wanderDirection.Y +=
            MathHelper.Lerp(-.25f, .25f, (float)random.NextDouble());


        if (wanderDirection != Vector2.Zero)
        {
            wanderDirection.Normalize();
        }


        orientation = TurnToFace(position, position + wanderDirection, orientation,
            .15f * turnSpeed);



        float distanceFromScreenCenter = Vector2.Distance(Game1.screenCenter, position);
        float MaxDistanceFromScreenCenter =
            Math.Min(Game1.screenCenter.Y, Game1.screenCenter.X);

        float normalizedDistance =
            distanceFromScreenCenter / MaxDistanceFromScreenCenter;

        float turnToCenterSpeed = .7f * normalizedDistance * normalizedDistance *
            turnSpeed;

        orientation = TurnToFace(position, Game1.screenCenter, orientation,
            turnToCenterSpeed);

        ViewDirection = orientation;

    }
\$\endgroup\$
0
\$\begingroup\$

i've solved my problem. the answer is in a way that if Cos(dir) and Sin(dir) is positive, then we can apply collision detection from up and down, but if one of them is negative, then the can deduct the value from the actual position. this is the latest WanderPushTo() function:

    public void WanderPushTo(float pix, float dir)
    {
        float newX = (float)Math.Cos(dir);
        float newY = (float)Math.Sin(dir);
        newX *= pix;
        newY *= pix;

        if (!Collision(new Vector2(newX, newY), new Wall(Vector2.Zero)))
        {
            float MYnewX = (float)Math.Cos(dir);
            float MYnewY = (float)Math.Sin(dir);
            enemyPosition.X += pix * (float)MYnewX;
            enemyPosition.Y += pix * (float)MYnewY;
        }
        else if (enemyState == enemyAiState.Wander)
        {
            if ((float)Math.Cos(dir) >= 0 && (float)Math.Sin(dir) >= 0)
            {
                float MYnewX = (float)Math.Cos(-dir);
                float MYnewY = (float)Math.Sin(-dir);
                enemyPosition.X += pix * (float)MYnewX;
                enemyPosition.Y += pix * (float)MYnewY;
            }
            else
            {
                float MYnewX = (float)Math.Cos(-dir);
                float MYnewY = (float)Math.Sin(-dir);
                enemyPosition.X -= pix * (float)MYnewX;
                enemyPosition.Y -= pix * (float)MYnewY;
            }

        }
    }
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.