Reputation: 1488
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
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
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
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