Bug when drawing a map (example) in another file?

I want to make a separate file for my map, like i have a separate file for my player. It works well for my player but when i do it with my map, for some reason i don’t know, my player can’t move when it starts. Here’s what i have in my map.cs file:

namespace towerDef
{
    class Mapa
    {
        private int tileX;
        private int tileY;
        private int x;
        private int y;

        public Mapa(int pTileX, int pTileY, int pX, int pY)
        {
            tileX = pTileX;
            tileY = pTileY;
            x = pX;
            y = pY;
        }

        public void draw(SpriteBatch spriteBatch, Texture2D backGroundFloor)
        {
            spriteBatch.Begin();
                for (int position = 0; position <= 2560; position += 32)
                {
                    for (int positionY = 0; positionY <= 1440; positionY += 32)
                    {
                        spriteBatch.Draw(backGroundFloor, new Rectangle(position, positionY, 32, 32), Color.White);
                    }
                }
            spriteBatch.End();
        }
    }
}

And in my Game1.cs here’s my draw:

protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
mapa.draw(_spriteBatch, backGroundFloor); //map draw
_spriteBatch.Begin(this.camera);

    player.anim.Draw(_spriteBatch); //player draw
    _spriteBatch.End();

    base.Draw(gameTime);
}

My player file:

       public void Update(GameTime gameTime)
    {
        float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
        KeyboardState kState = Keyboard.GetState();

        isMoving = false;

        if (kState.IsKeyDown(Keys.Right))
        {
            direction = Dir.Right;
            position.X += speed * dt;
            isMoving = true;
        }

        if (kState.IsKeyDown(Keys.Left))
        {
            direction = Dir.Left;
            position.X -= speed * dt;
            isMoving = true;
        }

        if (kState.IsKeyDown(Keys.Up))
        {
            direction = Dir.Up;
            position.Y -= speed * dt;
            isMoving = true;
        }

        if (kState.IsKeyDown(Keys.Down))
        {
            direction = Dir.Down;
            position.Y += speed * dt;
            isMoving = true;
        }

        if (kState.IsKeyDown(Keys.Right) && kState.IsKeyDown(Keys.LeftShift))
        {
            direction = Dir.RightRun;
            position.X += speedRun * dt;
            isMoving = true;
        }

        if (kState.IsKeyDown(Keys.Left) && kState.IsKeyDown(Keys.LeftShift))
        {
            direction = Dir.LeftRun;
            position.X -= speedRun * dt;
            isMoving = true;
        }

        if (kState.IsKeyDown(Keys.Up) && kState.IsKeyDown(Keys.LeftShift))
        {
            direction = Dir.UpRun;
            position.Y -= speedRun * dt;
            isMoving = true;
        }

        if (kState.IsKeyDown(Keys.Down) && kState.IsKeyDown(Keys.LeftShift))
        {
            direction = Dir.DownRun;
            position.Y += speedRun * dt;
            isMoving = true;
        }


        anim = animationsPlayer[(int)direction];
        anim.Position = new Vector2(position.X - 16, position.Y -16);
        kStateOld = kState;

        if (isMoving)
        {
            anim.Update(gameTime);
        }

        else
        {
            anim.setFrame(2);
        }
    }

We’re going to need to see the Update method in Game1. Are you updating your player instance?

1 Like

Yes, here it is:

 protected override void Update(GameTime gameTime)
    {
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
            Exit();

        player.Update(gameTime);

        this.camera.Position = player.Position;
        this.camera.Update(gameTime);

        base.Update(gameTime);
    }

This only happens when i draw the map in another file like this. It works fine if i do it like this:

        protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);
        _spriteBatch.Begin(this.camera);


                  for(int position = 0; position <= 2560; position += 32)
                    {
                        for(int positionY = 0; positionY <=1440; positionY += 32)
                        {
                            _spriteBatch.Draw(backGroundFloor, new Rectangle(position, positionY, 32, 32), Color.White);
                        }
                    }

        player.anim.Draw(_spriteBatch);
        _spriteBatch.End();

That’s because in the working code you posted, you’re reusing the same spriteBatch you use to draw the player, the one that had a camera field passed into its Begin() call, without ending and beginning the spriteBatch, whereas in the Mapa class, you call Begin again, but this time with no camera field passed in. The result is that the map is always drawn starting from the upper-left corner of the screen, and the player doesn’t appear to be moving, even though the player’s position values actually were being changed.

You shouldn’t need to call spriteBatch.Begin in the map’s draw method. Just begin the spriteBatch, draw the map, draw the player, and then end the spriteBatch.

To reiterate, in order to get the same behavior with the Mapa class, you’ll need to move the mapa.draw(_spriteBatch, backGroundFloor); call to be after the _spriteBatch.Begin(this.camera); line, and then delete the spriteBatch Begin and End lines in the Mapa draw method.

In Game1:

protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Color.CornflowerBlue);

    _spriteBatch.Begin(this.camera);

    mapa.draw(_spriteBatch, backGroundFloor); //map draw
    player.anim.Draw(_spriteBatch); //player draw

    _spriteBatch.End();

    base.Draw(gameTime);
}

In Mapa:

        public void draw(SpriteBatch spriteBatch, Texture2D backGroundFloor)
        {
            for (int position = 0; position <= 2560; position += 32)
            {
                for (int positionY = 0; positionY <= 1440; positionY += 32)
                {
                    spriteBatch.Draw(backGroundFloor, new Rectangle(position, positionY, 32, 32), Color.White);
                }
            }
        }
1 Like

Lol this seems like such an stupid thing, i actually did it before and i’ve got an error, idk what i did probably messed something in my code… it works now. Sorry for the silly question and thank you so much for your attention, i really appreciate it!

You’re welcome!

1 Like

Also you don’t need to prefix your variables been passed into your constructor with p. You can use the same variable name as what is in your class, but use this DOT To reference the class variable.

Eg.
This.tileX = tileX;

1 Like

I prefer the this. method, myself, but it ultimately is a style preference. Some people might like just typing the prefix and getting a quick list of parameters to use in the Intellisense popup.

Thank you for your tip! I really appreciate it

Yea this is where I land. I first learned this style with m_ in C++ coding but have since switched over to just using _ for class members instead. Just a style preference, and at this point in my career I’m so over style discussions between two literate and educated developers who are both capable of understanding different styles. Keep it consistent within a file, move the heck on.

/vent :stuck_out_tongue:

2 Likes