Search code examples
c#multidimensional-arrayxnacollisionscaling

Downscaling player coords so they fit in 2d array for collision


I'll get right into it I have created a map using a list of textures and a 2D array, I have drawn the player and the movement and now I am trying to use my player coords to access a location in the array to check if it has a specific tile and if it does to make my player go back to his previously location giving a sort of collision.

However the issue I have is when I convert my player coords to the array, it either goes out of bounds or is too high for the actual array I somehow need to downscale my coords so that they are accurate to the array.

Here is how I have drawn my tiles

    int tileWidth = 60;
    int tileHeight = 60;

    List<Texture2D> tileTextures = new List<Texture2D>();

    public int[,] Map = new int[,]
        {
            {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
            {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
            {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
            {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
            {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
            {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
            {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
        };

    public void Draw(SpriteBatch spriteBatch)
    {
        int tileMapWidth = Map.GetLength(1);
        int tileMapHeight = Map.GetLength(0);

        for (int x = 0; x < tileMapWidth; x++)
        {
            for (int y = 0; y < tileMapHeight; y++)
            {
                int textureIndex = Map[y, x];
                Texture2D texture = tileTextures[textureIndex];

                spriteBatch.Draw(
                    texture,
                    source = new Rectangle(x *myTile.Width,
                        y * myTile.Height,
                        tileWidth,
                        tileHeight),
                    Color.White);
            }
        }
    }

Here is my player movement

    public void input(GameTime gameTime)
    {
        KeyboardState ks = Keyboard.GetState();
        Vector2 motion = Vector2.Zero;

        if (ks.IsKeyDown(Keys.W))
            motion.Y--;
        if (ks.IsKeyDown(Keys.S))
            motion.Y++;
        if (ks.IsKeyDown(Keys.D))
        {
            currentAnim = rightWalk;
            Animate(gameTime);
            motion.X++;
        }
        if (ks.IsKeyDown(Keys.A))
        {
            currentAnim = leftWalk;
            Animate(gameTime);
            motion.X--;
        }            

        if (motion != Vector2.Zero)
            motion.Normalize();

        position += motion * speed;
    }

And finally my player Update

    public void Update(GameTime gameTime)
    {
        prevPosition = position;
        input(gameTime);
        if(CollidesWithWall((int)position.X, (int)position.Y))
        {
            position = prevPosition;
        }
    }

and my CollidingWithWall function

    public bool CollidesWithWall(int x, int y)
    {
        if (x < 0 || x > (15) -1) return true;
        if (y < 0 || y > (7) -1) return true;
        if (tiles.Map[x, y] == 1) return true;
        else return false;
    }

Solution

  • You seem to try to access your 2D array by player position. Your tiles are 60x60px, so if your player is at coord: x=30; y=40 for instance, it should be in the first tile [0,0], since they are both < 60.

    Here you try to ask your array the indices [30,40], which is out of bound, but the correct tile number is your position / tileSize.

    So,

    public bool CollidesWithWall(int x, int y)
    {
        if (x < 0 || x > (15) -1) return true;
        if (y < 0 || y > (7) -1) return true;
        if (tiles.Map[x, y] == 1) return true;
        else return false;
    }
    

    becomes :

    public bool CollidesWithWall(int x, int y)
    {
        if (x < 0 || x > (15) -1) return true;
        if (y < 0 || y > (7) -1) return true;
        if (tiles.Map[x / tiles.tileWidth, y / tiles.tileHeight] == 1) return true;
        else return false;
    }