0
\$\begingroup\$

So,I kind of figured out how to detect the collisions when the chracter hits a certain tilelayer(such as a wall).Right now it just just the tiles which should have collision and prints out "collision" on the game screen(As shown in the video below). But now I have two problems

  1. The collision is not being detected in the correct place in the bottom and left walls(as shown in the video below,the collision is not detected as soon as the player touches the wall but a little while later)
  2. How do I actually implement the collsions(as in stopping the player when he collides)?

The Video https://youtu.be/0E1UXms4AXQ

Here's the code below

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using MonoGame.Extended;

using MonoGame.Extended.Tiled;
using MonoGame.Extended.Tiled.Renderers;
using MonoGame.Extended.ViewportAdapters;


namespace Dungeon
{
    public class Game1 : Game
    {
        private GraphicsDeviceManager _graphics;
        private SpriteBatch _spriteBatch;
        private TiledMap map;
        private TiledMapRenderer mapRenderer;
        private OrthographicCamera cam;
        private Texture2D player;
        private Vector2 playerPos;
        private InputManager manager;
        private SpriteEffects effect;
        private TiledMapTileLayer mapLayer;
        private SpriteFont font;
        private string s;
        public Game1()
        {
            _graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            IsMouseVisible = true;
        }

        protected override void Initialize()
        {
            effect = SpriteEffects.FlipHorizontally;
            // TODO: Add your initialization logic here
            s = " ";
            manager = new InputManager();
            playerPos = new Vector2(100,100);
            mapRenderer = new TiledMapRenderer(GraphicsDevice);
            var viewportAdapter = new BoxingViewportAdapter(Window,GraphicsDevice,800,400);
            cam = new OrthographicCamera(viewportAdapter);
            base.Initialize();
        }

        protected override void LoadContent()
        {
            _spriteBatch = new SpriteBatch(GraphicsDevice);
            map = Content.Load<TiledMap>("Dungeon");
            mapRenderer.LoadMap(map);
            player = Content.Load<Texture2D>("player");
            mapLayer = map.GetLayer<TiledMapTileLayer>("walls");
            font = Content.Load<SpriteFont>("Debug");
            // TODO: use this.Content to load your game content here
        }

        protected override void Update(GameTime gameTime)
        {
            
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
                Exit();
            mapRenderer.Update(gameTime);
            // TODO: Add your update logic here
            KeyboardState state = Keyboard.GetState();
            if(state.IsKeyDown(Keys.A)||state.IsKeyDown(Keys.Left))
            {
                effect = SpriteEffects.FlipHorizontally;
                
            }
            else if(state.IsKeyDown(Keys.D)||state.IsKeyDown(Keys.Right))
            {
                effect = SpriteEffects.None;
                
            }
            float move = 2;
           
                playerPos =manager.moveVertical(playerPos,move);
            playerPos = manager.moveHorizontal(playerPos,move);
            ushort tx = (ushort)(playerPos.X / map.TileWidth);
            ushort ty = (ushort)(playerPos.Y / map.TileHeight);
            TiledMapTile? tile;
            if (mapLayer.TryGetTile(tx, ty, out tile))
            {
                if(!tile.Value.IsBlank)
                {
                    s = "collision";
                }
                else
                {
                    s = "none";
                }
            }
                base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);
            mapRenderer.Draw();
            var transformMatrix = cam.GetViewMatrix();

            _spriteBatch.Begin(transformMatrix:transformMatrix);
            _spriteBatch.DrawString(font,s,new Vector2(0,0),Color.White);
            _spriteBatch.Draw(player,new Rectangle((int)playerPos.X, (int)playerPos.Y,16,16),null,Color.White, 0f, new Vector2(16,16),effect,1);
            _spriteBatch.End();
            // TODO: Add your drawing code here

            base.Draw(gameTime);
        }
    }
}``` 


\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

After some searching I finally figured out the 2nd problem all I needed to do was make a Vector2 variable and store the intial position of the player(before updating it) into it When collision was detected the player position is set to the initial value

            var pos = playerPos;
            playerPos =manager.moveVertical(playerPos,move);
            playerPos = manager.moveHorizontal(playerPos,move);
            ushort tx = (ushort)(playerPos.X / map.TileWidth);
            ushort ty = (ushort)(playerPos.Y / map.TileHeight);
            TiledMapTile? tile;
            if (mapLayer.TryGetTile(tx, ty, out tile))
            {
                if(!tile.Value.IsBlank)
                {
                    s = "collision";
                    playerPos = pos;
                }
                else
                {
                    s = "none";
                }
            }

Which leaves us with the first problem only.

\$\endgroup\$
2
  • \$\begingroup\$ It seems like your code could use some formatting. If you're using Visual Studio, try a key combo from this post \$\endgroup\$ Sep 4, 2020 at 9:43
  • 1
    \$\begingroup\$ Yes it needed some I was just lazy to do it manually.😅 Thanks for the link \$\endgroup\$ Sep 4, 2020 at 11:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .