0
\$\begingroup\$

I made a simple collision detection prototype.Here's the code for the Player class's collision handler:

public void handleCollision(GameObject OtherObject)
    {   
        if(this.CollidesWith(OtherObject))
        {
            if(OtherObject is Stage)
            {
                float rightEdgeDistance = OtherObject.BoundRect.X - (Position.X + this.BoundRect.Width);
                float leftEdgeDistance = OtherObject.BoundRect.X + OtherObject.BoundRect.Width - Position.X;

                float TopEdgeDistance = OtherObject.BoundRect.Y - (Position.Y + this.BoundRect.Height);
                float BottomEdgeDistance = OtherObject.BoundRect.Y + OtherObject.BoundRect.Height - Position.Y;


                float Left_Right_SmallerDistance = Math.Min(Math.Abs(rightEdgeDistance), Math.Abs(leftEdgeDistance));
                float Top_Bottom_SmallerDistance = Math.Min(Math.Abs(TopEdgeDistance), Math.Abs(BottomEdgeDistance));

                float smallerDistance = Math.Min(Math.Abs(Left_Right_SmallerDistance), Math.Abs(Top_Bottom_SmallerDistance));

                if (smallerDistance == Math.Abs(leftEdgeDistance))
                {
                    Position.X = OtherObject.BoundRect.X + OtherObject.BoundRect.Width;
                    Velocity.X = 0;
                }
                else if (smallerDistance == Math.Abs(rightEdgeDistance))
                {
                    Position.X = OtherObject.BoundRect.X - this.BoundRect.Width;
                    Velocity.X = 0;
                }
                else if (smallerDistance == Math.Abs(BottomEdgeDistance))
                {
                    Position.Y = OtherObject.BoundRect.Y + OtherObject.BoundRect.Height;
                    Velocity.Y = 0;
                }
                else if (smallerDistance == Math.Abs(TopEdgeDistance))
                {
                    Position.Y = OtherObject.BoundRect.Y - this.BoundRect.Height;
                    Velocity.Y = 0;
                }
            }
        }

and here's my Player class's Input Handler method I made:

public void inputHandler(GameTime gameTime,GameObject OtherObject)
    {
        Velocity = Vector2.Zero;

        if (Keyboard.GetState().IsKeyDown(Keys.W))
            Velocity.Y -= moveSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
        if (Keyboard.GetState().IsKeyDown(Keys.S))
            Velocity.Y += moveSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
        if (Keyboard.GetState().IsKeyDown(Keys.A))
            Velocity.X -= moveSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
        if (Keyboard.GetState().IsKeyDown(Keys.D))
            Velocity.X += moveSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;


        handleCollision(OtherObject);
        Position += Velocity;
    }

Also here's my Update method In the Main Game Class.

protected override void Update(GameTime gameTime)
    {
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            this.Exit();

        for (int i = 0; i < 3; i++)
            player.Update(gameTime, stage[i]);
        powerUp.Update(gameTime,player);
        base.Update(gameTime);
    }

It works, but when I use array it becomes buggy for some elements of the arrays as in the character can still move a bit inside of the rectangle when I press the key to go down and it will stay outside of the top of the rectangle only if I let go of the key and vice versa.

The rectangles are an array of 3. If I were to move and test the 3rd box. It will work perfectly.But if test the 2nd, it will sink in a bit and the 1st a bit more than the 2nd. I use for loop for the update and draw the array elements. I see that the pattern is, the 1st is the first one to be checked in the Main Update method is will suffer the worst collision handling, while the last one will always be perfect. I tried other ways to handle the collision but to no avail. Why is that? And how can I counter this? Help please!

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

You call the player's Update() function 3 times per Main.Update(), where you probably want to call it only once.

Calling it 3 times will presumably attempt to move the player 3 times per frame, only doing a collision test with a single object for each of these three movements, so that each subsequent Update() can move through the previous obstacles in the loop.

Instead, you should run all your collision tests between the player and the obstacles first, then move the player only once at the end with the resulting velocity.

\$\endgroup\$
  • \$\begingroup\$ ok,I get what you are saying. I'll try 1st. thank you so much. :) \$\endgroup\$ – Adi Faidz Jan 10 '15 at 19:41
  • \$\begingroup\$ hi, I have changed the array to a list and added a parameter of List<Stage> to the Update method in class Player. But it says that "Inconsistent accessibility: parameter type 'System.Collections.Generic.List<Platformer.Stage>' is less accessible than method 'Platformer.Player.Update(Microsoft.Xna.Framework.GameTime, System.Collections.Generic.List<Platformer.Stage>)" I understand that the method cannot access stage but I tried adding public to the list at main but to no avail. \$\endgroup\$ – Adi Faidz Jan 10 '15 at 20:02
  • \$\begingroup\$ ok nvm im stupid haha, i forgot to change the class to public. Thx! :) \$\endgroup\$ – Adi Faidz Jan 10 '15 at 20:23

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