1

I am having some problems with collision detection, 2 have 2 types of objects aside from the player it self. Tiles and what I Call MapObjects.

The tiles are all 16x16, where the MapObjects can be any since, but is my problem case are they as well 16x16.

When my player runs apon the mapobjects or tiles dose it get very jaggy. The player is unable to move right, and will get warped forward when moving left.

I have found the problem, and that is my collision detection will move the player left/right if colliding the object from the side, and up/down if collision from up/down.

Now imagen that my player is sating on 2 tiles, at 10,12 and 11,12 and the player is mostly standing on the 11,12 tile. The collision detection will first run on then 10,12 tile, it calculates the collision depth, and finds that is is a collision from the side, and therefore more the object to the right. After will it do collision detection with 11,12 here will it move the character up. So the player will not fall down, but are unable to move right. And when moving left will the same problem make the player warp forward.

This problem have been bugging me for a few days now, and I just can't find a solution!

Here is my code that dose the collision detection.

 public void ApplyObjectCollision(IPhysicsObject obj, List<IComponent> mapObjects, TileMap map)
        {
            PhysicsVaraibales physicsVars = GetPhysicsVariables();
            Rectangle bounds = ((IComponent)obj).GetBound();
            int leftTile = (int)Math.Floor((float)bounds.Left / map.GetTileSize());
            int rightTile = (int)Math.Ceiling(((float)bounds.Right / map.GetTileSize())) - 1;
            int topTile = (int)Math.Floor((float)bounds.Top / map.GetTileSize());
            int bottomTile = (int)Math.Ceiling(((float)bounds.Bottom / map.GetTileSize())) - 1;

            // Reset flag to search for ground collision.
            obj.IsOnGround = false;

            // For each potentially colliding tile,
            for (int y = topTile; y <= bottomTile; ++y)
            {
                for (int x = leftTile; x <= rightTile; ++x)
                {
                    IComponent tile = map.Get(x, y);
                    if (tile != null)
                    {
                        bounds = HandelCollision(obj, tile, bounds, physicsVars);
                    }
                }
            }

            // Handel collision for all Moving objects
            foreach (IComponent mo in mapObjects)
            {
                if (mo == obj)
                    continue;

                if (mo.GetBound().Intersects(((IComponent)obj).GetBound()))
                {
                    bounds = HandelCollision(obj, mo, bounds, physicsVars);
                }
            }
        }
        private Rectangle HandelCollision(IPhysicsObject obj, IComponent objb, Rectangle bounds, PhysicsVaraibales physicsVars)
        {
            // If this tile is collidable,
            SpriteCollision collision = ((IComponent)objb).GetCollisionType();

            if (collision != SpriteCollision.Passable)
            {
                // Determine collision depth (with direction) and magnitude.
                Rectangle tileBounds = ((IComponent)objb).GetBound();
                Vector2 depth = bounds.GetIntersectionDepth(tileBounds);
                if (depth != Vector2.Zero)
                {
                    float absDepthX = Math.Abs(depth.X);
                    float absDepthY = Math.Abs(depth.Y);

                    // Resolve the collision along the shallow axis.
                    if (absDepthY <= absDepthX || collision == SpriteCollision.Platform)
                    {
                        // If we crossed the top of a tile, we are on the ground.
                        if (obj.PreviousBound.Bottom <= tileBounds.Top)
                            obj.IsOnGround = true;

                        // Ignore platforms, unless we are on the ground.
                        if (collision == SpriteCollision.Impassable || obj.IsOnGround)
                        {
                            // Resolve the collision along the Y axis.
                            ((IComponent)obj).Position = new Vector2(((IComponent)obj).Position.X, ((IComponent)obj).Position.Y + depth.Y);

                            // If we hit something about us, remove all velosity upwards
                            if (depth.Y > 0 && obj.IsJumping)
                            {
                                obj.Velocity = new Vector2(obj.Velocity.X, 0);
                                obj.JumpTime = physicsVars.MaxJumpTime;
                            }

                            // Perform further collisions with the new bounds.
                            return ((IComponent)obj).GetBound();
                        }
                    }
                    else if (collision == SpriteCollision.Impassable) // Ignore platforms.
                    {
                        // Resolve the collision along the X axis.
                        ((IComponent)obj).Position = new Vector2(((IComponent)obj).Position.X + depth.X, ((IComponent)obj).Position.Y);

                        // Perform further collisions with the new bounds.
                        return ((IComponent)obj).GetBound();
                    }
                }
            }
            return bounds;
        }
Kara
  • 6,115
  • 16
  • 50
  • 57
Androme
  • 2,399
  • 4
  • 43
  • 82
  • have a look at this article http://stackoverflow.com/questions/345838/ball-to-ball-collision-detection-and-handling – John Woo Mar 11 '12 at 06:42

0 Answers0