Jump to content
  • Advertisement
Sign in to follow this  
Twiggy

Scrolling in a 2D RTS game - How to?

This topic is 5011 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Guys, I've been wondering. I'm creating a 2d rts game, and i have all the basic stuff: I have all the tiles i need and the map array ready and all that, but I've been wondering.. How do I program scrolling? I mean, the idea I had (For example, when I'm scrolling right: ) was to 'chop' a 'pixel-size line' of the next tile to be drawn while moving all the drawn map a pixel to the left, and then draw the next 'line' until I finally draw all that tile, and so on and on. The thing is that I don't really know how to 'chop' a picture I have in memory. Can someone please help me on how to do that? Or if you have a better idea for scrolling, I'll thank you even more. I'm using SDL, btw. Oh yeah, and one small thing - I want to enter a 'quote' of a piece of code here in the forum, how do I do that (prolly [thing] and [/thing], but don't know what is that 'thing'). Thanx :) [Edited by - Twiggy on January 4, 2005 7:24:35 AM]

Share this post


Link to post
Share on other sites
Advertisement
Are you using the 2D SDL API or OpenGL through SDL?

If you are using the 2D SDL api: Basically what i did a long time ago using directDraw

Create a ClipBlit function that takes in: Image - Surface, DestRect - Rectangle, SourceRect - Rectangle.

Ok now i'm assuming you are blitting onto the backbuffer. Get the Rectangle associated with the backbuffer and test the DestRectangle against it as such:


//check if the destination rectangle is going off the top of the screen
if (DestRect.y < BackRect.y)
{
float difference = BackRect.y - DestRect.y;
DestRect.y += difference;
SourceRect.y += difference;
}


The code will adjust the destination and source rectangles so that only the visible parts are copied from the source surface and the destionation rectnagle is fully on the screen. Check it out on paper and work out the tests for the other three sides of the screen.

they are [.code.] and [./code.] tags, remove the dots.

Share this post


Link to post
Share on other sites
In addition to what Ilici said, if you use tiles you basically do the same (e.g. figure out which is the first visible tile and render the portion of the map from there). For smooth (pixel-wise) scrolling a little more effort is required, but it's the same principle.
BTW you can also use [.source] [./source.] tags (without the dots again) to post syntax-highlighted code.

HTH,
Pat.

Share this post


Link to post
Share on other sites
Thank you very much, but I did not understand. I am not such an experienced proggrammer, and a very unexperienced SDL progger.

Darookie, what did you mean by...
Quote:
figure out which is the first visible tile and render the portion of the map from there

And Ilici, the thing I needed to know was not how to know how many pixels to draw, but was how to take the portion of the tile i need and draw it.

I basically need instructions on how the system works.

Thanx again.

Share this post


Link to post
Share on other sites
So you use tiles, right? Then you surely have an array of some sort that tells you where tiles are located on the map.
Say you have a map of 64x64 tiles and each tile is 32x32 pixels in size.
Your whole map is therefore 64*32 x 64*32 = 2048x2048 pixels in size and this doesn't fit on your average screen.

Now let's say your output window is 640x480 pixels in size. This leaves you with a max of 640/32 x 480/32 = 20x15 visible tiles.

If you set your initial upper-left tile to be tile (0,0) in your map, you just draw the first 20 tiles for each of the first 15 rows of you map.
Now if you scroll tile-by-tile (which I'd recommend to start with), you just change this first upper-left tile you draw:



const int MAP_SIZE_X = 64;
const int MAP_SIZE_Y = 64;

// let's suppose this array holds the Ids of your tiles in the map
int tileMap[MAP_SIZE_Y][MAP_SIZE_X];

// these constants hold the number of visible tiles of the map
const int visibileTilesX = WINDOW_WIDTH / TILE_SIZE_X;
const int visibileTilesY = WINDOW_WIDTH / TILE_SIZE_X;

// these are your start positions for simple tile-by-tile scrolling
int startTileX = 0;
int startTileY = 0;

void drawTile(int tileNumber, int screenX, int screenY) {
// blit tile image here
}

void drawMap() {

// tile screen position in pixels
int screenY = 0;

for (int mapY = startTileY; mapY < visibleTilesY; ++mapY) {

// tile screen position in pixels
int screenX = 0;

for (int mapY = startTileX; mapX < visibleTilesY; ++mapY) {

drawTile(map[mapY][mapX], screenX, screenY);

// set position to next tile
screenX += TILE_SIZE_X;
}

// set position to next row on screen
screenY += TILE_SIZE_Y;
}
}

// scroll the map by the given amount of tiles
void scrollMap(int tilesX, int tilesY) {

// update start positions
startTileX += tilesX;
startTileY += tilesY;

// make sure you don't get out of the map boundaries
if (startTileX < 0)
startTileX = 0;

else if (startTileX > MAP_SIZE_X - visibleTilesX)
startTileX = MAP_SIZE_X - visibleTilesX;

if (startTileY < 0)
startTileY = 0;

else if (startTileY > MAP_SIZE_Y - visibleTilesY)
startTileY = MAP_SIZE_Y - visibleTilesY;
}



Hope that helps,
Pat.

Share this post


Link to post
Share on other sites
It's not too difficult if you keep your wits about you. Once you've made it scroll a whole tile at a time at first, add a second pair of coordinates to keep track of the position of the top left corner of the viewscreen in the top left tile, and when you draw the tiles shift the whole lot up and to the left by that amount.

Share this post


Link to post
Share on other sites
Basically, you change startX and startY to where the upperleft corner of the screen is on your map. So, you can move these around to where you want them.

My method of clipping tiles was simply to draw one row off screen, sort of as a buffer. It keeps the tile in memory and displays part of it if the screen doesn't show a whole tile.


int startCol = (startX/tileSize) - 1;
int endCol = (screenWidth/tileSize) + 1;
int startRow = (startY/tileSize) - 1;
int endRow = (screenHeight/tileSize) + 1;

for(int i = startCol; i <= endCol; i++)
{
for(int j = startRow; j <= endRow; j++)
{
drawImage(startX + (i * tileSize), startY + (j * tileSize), tileMap[j].getImage());
}
}

//cleanup code here





NOTE: This isn't actual working code. Just typed it up as a demonstration of the row/col buffer. Probably doesn't even work. If so, let me know.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!