1 Replies - 1204 Views - Last Post: 01 January 2017 - 10:46 AM

#1 AnonymousUser1508  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 18
  • Joined: 29-April 16

Collision for tile only works correctly for top and left xna

Posted 29 December 2016 - 05:32 PM

This might be really simple but it is giving me a lot grief and I wondered if you guys would be able to shed some light on it. Basically I have a tile map which draws tiles at 64 * 64 and that works very well and they are drawn in a 2D array like this in the game1 class.

    TileMap tileMap = new TileMap(new int[,]
        {
            { 2,2,2,2,2,2,2,2,2,2 },
            { 2,2,2,2,2,2,2,2,2,2 },
            { 0,0,0,0,0,0,4,4,4,4 },
            { 0,0,0,0,0,0,1,1,4,4 },
            { 1,1,1,1,1,1,1,1,1,1,},
            { 1,1,1,1,1,1,1,1,1,1,}
        });


Now comes the problem. Basically I want to determine which side the player has hit the tile from. However, with the algorithm below the collision only works correctly for the bottom and left side. if the player hits the tile from the top it will state it was hit from the bottom. if the player hits from the right it will specify the left side was hit. if the player hits from the top or right it will show that collision has happened but state it happened on the bottom or left of it.
It will output that the top of the tile has been hit but only when the player is completely in the tile like this
[1]: https://i.stack.imgur.com/nt8L2.png

Pretty much the same thing happens when it displays the right side is hit(player moves more to the left slightly than image above)
[2]: https://i.stack.imgur.com/IvAu6.png



**TileMap**

            int left = (int)Math.Floor((float)player.playerBounds.Left / TILE_WIDTH);
            int top = (int)Math.Floor((float)player.playerBounds.Top / TILE_HEIGHT);
            int right = (int)Math.Ceiling((float)player.playerBounds.Right / TILE_WIDTH) - 1;
            int bottom = (int)Math.Ceiling((float)player.playerBounds.Bottom / TILE_HEIGHT) - 1;

            Rectangle tileBounds = new Rectangle((int)tilePosX, (int)tilePosY, TILE_WIDTH, TILE_HEIGHT);
            Rectangle playerBounds = player.playerBounds;

            float WidthOfRects = 0.5f * (playerBounds.Width + tileBounds.Width);
            float heightOfRects = 0.5f * (playerBounds.Height + tileBounds.Height);

            int centerX = (playerBounds.Left + playerBounds.Width / 2) - (tileBounds.Left + tileBounds.Width / 2);
            int centerY = (playerBounds.Top + playerBounds.Height / 2) - (tileBounds.Top + tileBounds.Height / 2);

            for (int y = top; y <= bottom; ++y)
            {
                for (int x = left; x <= right; ++x)
                {
                    
                    if (mapCell[y, x].TileID == 1)
                    {
                        
                        if (Math.Abs(centerX) <= WidthOfRects && Math.Abs(centerY) <= heightOfRects)
                        {
                            double wy = WidthOfRects * centerY;
                            double hx = heightOfRects * centerX;
                            if (wy > hx)
                            {
                                if (wy > -hx)
                                {
                                    Console.WriteLine("bottom");
                                    //newPos.Y = tileCollision.Bottom;
                                }
                                else
                                {
                                    Console.WriteLine("right");
                                    //newPos.X = tileCollision.Right;
                                    
                                }
                            }
                            if (wy > -hx)
                            {
                                Console.WriteLine("left ");
                                //newPos.X = tileCollision.Left - playerBounds.Width;
                            }
                            else
                            {
                                Console.WriteLine("top");
                                //newPos.Y = tileCollision.Top - playerBounds.Height;
                            }
                        }
                        // player.Position = newPos;
                    }
                }
            }

**Map Cell**

    public class MapCell
    {
        
        public int TileID { get; set; }

        public MapCell(int tileID) 
        {
            TileID = tileID;
        }


the player bounds is in the **player class** update method which inherits from the sprite class.

 public override void Update(GameTime gameTime)
        {
            playerBounds = new Rectangle((int)Position.X, (int)Position.Y, 50, 50);
        }


The position is inheriting from the **sprite class**

 protected Vector2 position;
        public Vector2 Position
        {
            get { return position; }
            set { position = value; }
        }


Any help would be greatly appreciated.

Thank you.

Is This A Good Question/Topic? 0
  • +

Replies To: Collision for tile only works correctly for top and left xna

#2 dev_  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 20
  • Joined: 25-February 14

Re: Collision for tile only works correctly for top and left xna

Posted 01 January 2017 - 10:46 AM

You have public definition inside protected fdu

Thats why your set is red.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1