User
User

Reputation: 1488

Side scrolling a tile map, Map getting messed up

I succesfully generate my tile map and it works but when i want to scroll it the top line of tiles is moving and all the tiles is dragged of screen.. Its hard to explain,

Imagine this is the tiles: X

XXXXXXXXXXXXXXXXXXXXXXXXXX //Here it starts to remove tile by tile when camera is moving.

XXXXXXXXXXXXXXXXXXXXXXXXXX //Causing all the other tiles to move up line my line.

XXXXXXXXXXXXXXXXXXXXXXXXXX

XXXXXXXXXXXXXXXXXXXXXXXXXX

Take a look at my code:

public void Draw(SpriteBatch spriteBatch)
{
    currentLevel = level1;
    //Its here i need the value from Player class!
    int currentX = cameraX; //The current x cordiate to draw the tile too
    int currentY = 0; //The current y cordiate to draw the tile too
    for (int i = 0; i < currentLevel.Length; i++)
    {
        /*
         * A switch statement to see if the current level1[i] is either a grass, sky or stone tile
         */
        switch(currentLevel[i])
        {
            case 1:
                //Draw a sky tile
                spriteBatch.Draw(tileSheet, new Rectangle(currentX, currentY, 32, 32), skyTile, Color.White);
                break;

            case 2:
                //Draw a grass tile
                spriteBatch.Draw(tileSheet, new Rectangle(currentX, currentY, 32, 32), grassTile, Color.White);
                break;

            case 3:
                //Draw a stone tile
                spriteBatch.Draw(tileSheet, new Rectangle(currentX, currentY, 32, 32), stoneTile, Color.White);
                break;
        }

        //Add 32 to the current cordinate so we don't draw to the same spot all the time
        currentX = currentX + 32; 
        if (currentX >= 896) //If we hit the width of the map we want:
        {
            //Start drawing from X cordinate zero
            cameraX = 0;
            currentX = cameraX;
            //And Y cordinate + 32
            currentY = currentY + 32;
            //This will make so we draw one line and when we hit a full line on the map then we draw next line and soo on.
        }
    }
}

The CameraX variable is a getter from the Player class.. Which is decremented while holding the left button on the keyboard.

Here is the tile map that i draw from array(1 = sky, 2 = grass, 3 = stone:

int[] level1 = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
                         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
                         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
                         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
                         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
                         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
                         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
                         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 3,
                         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 1, 1, 3,
                         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
                         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
                         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
                         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
                         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
                         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, 3};

Any ideas?

Upvotes: 2

Views: 1240

Answers (3)

BlueMonkMN
BlueMonkMN

Reputation: 25601

It looks like you are always drawing all the tiles in your entire map (i starts at 0 and loops through every tile). However, you are not always drawing the same number of tiles on each row. If CameraX is 0, then you will draw 28 tiles per row because you will move to the next row after 32*28 (896) pixels. But if CameraX is 480, then you will only draw 13 ((896-480)/32) tiles on each row, and the rest of the first row's tiles will draw on the second row (because you are still trying to draw all tiles). I think you should loop through each row and column that you want to draw, and calculate the tile index from those instead of looping through every tile in the map and calculating the position independently.

EDIT Here's some example code for calculating a tile index in a 1-dimensional array given a column and row index assuming you know the number of columns. (Or you could just switch to using a 2-d array):

i = row * columnCount + column;

Upvotes: 4

dowhilefor
dowhilefor

Reputation: 11051

I don't really understand your code, but i advice you to use a 2 dimensional array or access the one dimensional array in a proper way like array[ Y * ARRAY_Width + X]. Besides that, why do you start your loop over the whole Level. Whats inside the camera is important, otherwise you will iterate over alot of tiles which arent visible anyway.

Start at your camera X an Y, calculate how many horizontal and vertical tiles you draw inside your camera viewport: These should be the only tiles you need to iterate. Also it seems like you are moving the tiles. You want to move the camera, not your tiles. SpriteBatch.Begin has an overload to set a Matrix containing your camera movement. If you don't now how to work with Matrix, just call

Matrix view = Matrix.CreateTranslate(new Vector3( myCam.X, myCam.Y, 0));

and pass that as the view matrix into the BeginSprite method.

These changes will make your code much easier.

Hope that helps.

Upvotes: 1

George Duckett
George Duckett

Reputation: 32418

I believe your problem is that when you get to the end of a line you set the CameraX to 0.

You don't want to move the camera at the end of each line, you just want to reset the x drawing position (as you do in the next line).

So, remove cameraX = 0;

I'm not 100% sure that would cause the issue you describe, but it's definitely not right, as you say the player controls cameraX, so it shouldn't be changed in your draw function.

Upvotes: 1

Related Questions