Collision Detection only working in corners

I want the character of my game to not be able to trespass obstacle tiles. With my current code I am able to prevent him from leaving the map limits as you can see in the image below

Otherwise, when I try to prevent him from trespassing this lake, there are some points where I can trespass. Is there something wrong with my code?

  public class Character : Unit 
    {
        protected _Keyboard keyboard;
        protected string name;
        protected string description;
        protected bool shield;
        protected double currentTime;
        protected float cooldown;
        protected bool readyToShoot;
        protected string projectileType;


        public Character(string _path, Vector2 _position, Vector2 _dimensions, int _ownerId, List<Projectile> _projectiles) : base(_path, _position, _dimensions, _ownerId)
        {
            keyboard = new _Keyboard();
            shield = false;
            readyToShoot = true;
        }

        public Character(Character other)
        {
            keyboard = other.keyboard;
            name = other.name;
            description = other.description;
            shield = other.shield;
            currentTime = other.currentTime;
            cooldown = other.cooldown;
            readyToShoot = other.readyToShoot;
            isDead = other.isDead;
            speed = other.speed;
            attackArea = other.attackArea;
            damage = other.damage;
            ownerId = other.ownerId;
            range = other.range;
            rotation = other.rotation;
            position = other.position;
            dimensions = other.dimensions;
            model = other.model;
            mouseControl = other.mouseControl;
            healthMax = other.healthMax;
            currentHealth = healthMax;
            projectileType = other.projectileType;

    }

        public string GetName()
        {
            return name;
        }

        public string GetDescription()
        {
            return description;
        }

        public void SetShieldStatus(bool _status)
        {
            shield = _status;
        }
        public bool HasShield()
        {
            return shield;
        }

        public virtual void Update(Vector2 _offset,PassObject _scroll,MapManager map, List<Projectile> _projectiles)
        {
            if (currentTime + cooldown < Globals.gameTime.TotalGameTime.TotalSeconds)
            {
                readyToShoot = true;
            }

            Move(_scroll,map);
            Shoot(_projectiles,_offset);
        }

       
        private void Move(PassObject _scroll,MapManager map)
        {
            bool checkScroll = false;
            int mapTileX, mapTileY, tileType;

            keyboard.Update();
            if (keyboard.GetPress("A"))
            {
                mapTileX = (int)((position.X - speed) / map.GetTiles().GetTilesWidht());
                mapTileY = (int)(position.Y / map.GetTiles().GetTilesHeight());
                
                tileType = map.GetTileType(mapTileY, mapTileX);

                if (map.GetTiles().GetTile(tileType).UnitCross())
                {
                    SetPosition(new Vector2(position.X - speed, position.Y));
                    checkScroll = true;
                }

            }
            if (keyboard.GetPress("D"))
            {
                mapTileX = (int)((position.X + speed) / map.GetTiles().GetTilesWidht()) + 1;
                mapTileY = (int)(position.Y / map.GetTiles().GetTilesHeight());
               
                tileType = map.GetTileType(mapTileY, mapTileX);

                if (map.GetTiles().GetTile(tileType).UnitCross())
                {
                    SetPosition(new Vector2(position.X + speed, position.Y));
                    checkScroll = true;
                }

            }
            if (keyboard.GetPress("W"))
            {
                mapTileX = (int)position.X / map.GetTiles().GetTilesWidht();
                mapTileY = (int)(position.Y - speed) / map.GetTiles().GetTilesHeight();
                
                tileType = map.GetTileType(mapTileY, mapTileX);

                if (map.GetTiles().GetTile(tileType).UnitCross())
                {
                    SetPosition(new Vector2(GetPosition().X, GetPosition().Y - speed));  //Y is inverted, this means that 0 is on top .So if the player wants to go up Y has do decrease 
                    checkScroll = true;
                }

            }

            if (keyboard.GetPress("S"))
            {
                mapTileX = (int)position.X / map.GetTiles().GetTilesWidht();
                mapTileY = (int)(position.Y + speed) / map.GetTiles().GetTilesHeight() + 1;
                
                
                tileType = map.GetTileType(mapTileY, mapTileX);

                if (map.GetTiles().GetTile(tileType).UnitCross())
                {
                    SetPosition(new Vector2(GetPosition().X, GetPosition().Y + speed));   //Again, Y is inverted
                    checkScroll = true;
                }

            }

            if (checkScroll)
            {
                _scroll(GetPosition());
            }

            keyboard.UpdateOld();
        }

        private void Shoot(List<Projectile> _projectiles,Vector2 _offset)
        {
            mouseControl.Update();
            if (mouseControl.LeftClick())

                if (readyToShoot)
                {
                    Projectile tempProjectile = null;

                    if (projectileType.Equals("Arrow"))
                    {
                        tempProjectile = new Arrow(new Vector2(GetPosition().X, GetPosition().Y), this, new Vector2(mouseControl.newMousePos.X, mouseControl.newMousePos.Y) - _offset);
                    }
                    else if (projectileType.Equals("IceShard"))
                    {
                        tempProjectile = new IceShard(new Vector2(GetPosition().X, GetPosition().Y), this, new Vector2(mouseControl.newMousePos.X, mouseControl.newMousePos.Y) - _offset);
                    }
                    else if (projectileType.Equals("Fireball"))
                    {
                        tempProjectile = new Fireball(new Vector2(GetPosition().X, GetPosition().Y), this, new Vector2(mouseControl.newMousePos.X, mouseControl.newMousePos.Y) - _offset);
                    }

                    _projectiles.Add(tempProjectile);
                    currentTime = Globals.gameTime.TotalGameTime.TotalSeconds;
                    readyToShoot = false;
                }

            SetRotation(RotateTowards(GetPosition(), new Vector2(mouseControl.newMousePos.X, mouseControl.newMousePos.Y) - _offset));
            mouseControl.UpdateOld();
        }



        public override void Draw(Vector2 _offset)
        {
            base.Draw(_offset);
        }

    }
public class MapManager
    {
        private TileManager tiles;
        private int[,] map;
        private const int mapWidth = 60;
        private const int mapHeight = 60;


        public MapManager()
        {
            this.map = new int[mapHeight, mapWidth];
            this.tiles = new TileManager();

            FillMap();

        }

        public TileManager GetTiles()
        {
            return tiles;
        }

        public int [,] GetMap()
        {
            return map;
        }

        public int GetTileType(int _x ,int _y)
        {
            return map[_x, _y];
        }
             
        private void FillMap()
        {
            for (int i = 0; i < mapWidth; i++)
            {
                map[0, i] = 2;
                map[mapHeight - 1, i] = 2;
            }

            for (int i = 0; i < mapHeight; i++)
            {
                map[i, 0] = 2;
                map[i, mapWidth - 1] = 2;
            }


            /* for (int i = 1; i < mapWidth - 1; i++)
             {
                 map[i, i] = 1;

             }*/

            map[22, 13] = 6;
            map[22, 14] = 7;
            map[22, 15] = 8;
            map[23, 13] = 9;
            map[23, 14] = 2;
            map[23, 15] = 10;
            map[24, 13] = 3;
            map[24, 14] = 4;
            map[24, 15] = 5;
            
        }

        public void Draw(Vector2 _offset)
        {
            Rectangle position = new Rectangle(0, 0, this.tiles.GetTilesWidht(), this.tiles.GetTilesHeight());

            for (int row = 0; row < mapHeight; row++)
            {

                for (int col = 0; col < mapWidth; col++)
                {


                    tiles.GetTile(map[row, col]).Draw(_offset, position);
                    position.X += tiles.GetTilesWidht();
                }
                position.X = 0;
                position.Y += tiles.GetTilesHeight();

            }
        }
    }
 public class TileManager
    {
        private Tile[] arrayTile;
        private int tilesWidht;
        private int tilesHeight;

        public TileManager()
        {
            arrayTile = new Tile[11];
            tilesWidht = 64;
            tilesHeight = 64;

            arrayTile[0] = new Tile("2D\\MapTiles\\DirtTile", true,true,tilesWidht,tilesHeight);
            arrayTile[1] = new Tile("2D\\MapTiles\\GrassTile", true,true, tilesWidht, tilesHeight);
            arrayTile[2] = new Tile("2D\\MapTiles\\WaterTile", false,false, tilesWidht, tilesHeight);
            arrayTile[3] = new Tile("2D\\MapTiles\\WaterDownLeftTile", false,false, tilesWidht, tilesHeight);
            arrayTile[4] = new Tile("2D\\MapTiles\\WaterDownMidTile", false,false, tilesWidht, tilesHeight);
            arrayTile[5] = new Tile("2D\\MapTiles\\WaterDownRightTile", false,false, tilesWidht, tilesHeight);
            arrayTile[6] = new Tile("2D\\MapTiles\\WaterTopLeftTile", false,false, tilesWidht, tilesHeight);
            arrayTile[7] = new Tile("2D\\MapTiles\\WaterTopMidTile", false,false, tilesWidht, tilesHeight);
            arrayTile[8] = new Tile("2D\\MapTiles\\WaterTopRightTile", false,false, tilesWidht, tilesHeight);
            arrayTile[9] = new Tile("2D\\MapTiles\\WaterMidLeftTile", false,false, tilesWidht, tilesHeight);
            arrayTile[10] = new Tile("2D\\MapTiles\\WaterMidRightTile", false,false, tilesWidht, tilesHeight);

        }
        public int GetTilesWidht()
        {
            return tilesWidht;
        }

        public int GetTilesHeight()
        {
            return tilesHeight;
        }

        public Tile GetTile(int _position)
        {
            return arrayTile[_position];
        }
    }
 public class Tile :Basic2D 
    {
        private bool crossableUnit;
        private bool crossableProjectile;

        public Tile(string _path, bool _crossableUnit, bool _crossableProjectile, int _width,int _height) :base (_path, Vector2.Zero, new Vector2(_width,_height))
        {
            this.crossableUnit = _crossableUnit;
            crossableProjectile = _crossableProjectile;

        }

        public bool UnitCross()
        {
            return this.crossableUnit;
        } 

        public bool ProjectileCross()
        {
            return crossableProjectile;
        }

        public override void Draw(Vector2 _offset, Rectangle _position)
        {
            base.Draw(_offset, _position);
        }
    }

In a game I wrote before, it was Tile Based. What I did is I kept track of the tile I was currently on and my character had a state of either Moving or Not Moving. If I’m moving, I prevented them from going a different direction until the unit had moved from Tile A to Tile B.

Looking at your movement code you are allowing them to move even if they are not 100% in a given Tile, so when you check the tile in the direction they are moving, you could be looking at the wrong tile.

I would also recommend that you get the Title and use that rather than calling multiple methods.

i.e. Change this:

to something like this:

Looks like you are representing your characters position as a single point in space in the code but rendering it as texture that is a lot bigger than that. Since the origin of a texture in the top left, the texture is going to “move over” blocked area’s till it hits the single pixel in the top left.

This is why you character is stopped by the ocean (?) in the top picture, it’s to the left of the character so hits the top left pixel immediately. Where the lake, to the bottom right, does not.

Couple of different ways of fixing it:

  1. Instead of just checking the top right, check each of the four corners of the characters texture when he attempts to move. Least effort, least flexible.
  2. Represent you character and tiles as rectangles instead of points and then test for intersections when you move. More effort but probably going to be needed for other reasons later.