Scrolling in a 2D RTS game - How to?

Started by
17 comments, last by kzar 19 years, 2 months ago
Thanx!

But dudes, don't forget that I have to draw sprites on the tiles (Soldiers and such), that is another problem.
___________________________"Peg, is there a certain reason that cactus is standing in the place where my alarm clock should be?"
Advertisement
SDL does all the clipping for you. If you have a 32x32 tile and draw it at a destination rectangle of -20,-10,32,32 then it will clip the image for you (cannot place a clipper on a primary/flipped surface in directdraw). This makes it very simple to smooth scroll. Here is a working tilemap program in SDL that has smooth scrolling and some simple collision detection. If the player appears not to move then your computer is too fast! :) Just increase the sprites speed in move_sprite by increments of 50 until it works.

Hope that helps.

Evillive2
You simply do a Z-Sort for the soldiers on tiles. You draw all the tiles(bottom level), draw ground units second(second level), then aireal units(third level) if you have them. You can hardcode the tile rendering as the bottom level(I would imagine) because it's your background. As far as individual units, when you process their animations and get their current image, send an instance(or pointer) to a linked list. If they're to be drawn first, add them to the front. If they're to be drawn last, add them to the back. Then you simply iterate through and remove units from the list as you draw them.
Quote:Original post by evillive2
SDL does all the clipping for you. If you have a 32x32 tile and draw it at a destination rectangle of -20,-10,32,32 then it will clip the image for you (cannot place a clipper on a primary/flipped surface in directdraw). This makes it very simple to smooth scroll. Here is a working tilemap program in SDL that has smooth scrolling and some simple collision detection. If the player appears not to move then your computer is too fast! :) Just increase the sprites speed in move_sprite by increments of 50 until it works.

Hope that helps.


Love how you made it all in one file to make it easy to understand. love it. anyway I was just wondering on your web site, do you have the source files of the RPG map?
Thanhda TieDigital Shock, Technical Director & Business Relations15-75 Bayly Street West, Suite #173Ajax, Ontario, L1S 7K7Tel: 416.875.1634http://www.digitalshock.net
Quote:Original post by Thanhda
Quote:Original post by evillive2
SDL does all the clipping for you. If you have a 32x32 tile and draw it at a destination rectangle of -20,-10,32,32 then it will clip the image for you (cannot place a clipper on a primary/flipped surface in directdraw). This makes it very simple to smooth scroll. Here is a working tilemap program in SDL that has smooth scrolling and some simple collision detection. If the player appears not to move then your computer is too fast! :) Just increase the sprites speed in move_sprite by increments of 50 until it works.

Hope that helps.


Love how you made it all in one file to make it easy to understand. love it. anyway I was just wondering on your web site, do you have the source files of the RPG map?


Sorry, I think that went away with the last reformat of my hard drive. It was written in directx anyway and the initialization code in that was almost as long as the entire SDL demo anyway. The only useful bits in that would have been the map file stuff which was just parsing a few lines of text and tile index numbers into the tilemap array. I have since ditched my directdraw code for SDL for a few reasons:
1. The initialization of DirectX code is just a pain in the butt.
2. SDL is cross platform. Not usre when I will want to use this but it can never hurt.
3. I eventually want to move onto 2d in 3d via OpenGL when I get a better computer and can see the difference (3d is sloooooooow on my end).

I am glad that I tried DirectDraw before SDL because it makes me appreciate some things on both sides. While SDL is much simpler to get something on the screen, DirectDraw IMHO is actually a more powerful 2d graphics API because it is platform specific and doesn't have to "meet in the middle" to stay cross platform. On the other hand, SDL with OpenGL is much more powerful with todays video cards than any 2d API out there offering hardware acceleration for things such as blending, rotation and stretching which are dog slow in software and hardware acceleration is just not in the cards for 2d anymore.

At any rate, I am glad the demo helped a little. If you have any questions about it, just e-mail me or post here, I usually try to get back to people when I can :)
Evillive2
yeah, thats the main reason i wanted the source, because of the map files. but heh i'm sure i can find a way of doing it. (being a bit lazy =P). anyway yeah i feel ya, i started out with DX8.1 myself(such a pain in the ass with them getting rid of directdraw). but i too moved from DX to SDL to one day get good at OGL. also the fact that its cross platform. but yeah that code help quite a bit. Anyway i wanted to ask you if you know how to make images or fade in or out? or even play mpgs in sdl?

BTW, just wondering, have you build any games in SDL yet? something with more then just a tile base system.
Thanhda TieDigital Shock, Technical Director & Business Relations15-75 Bayly Street West, Suite #173Ajax, Ontario, L1S 7K7Tel: 416.875.1634http://www.digitalshock.net
Quote:Original post by evillive2
If you have any questions about it, just e-mail me or post here, I usually try to get back to people when I can :)


Hey, I have a question about your example. I was having problems with my attempt crashing when (i think) the map drawing function was trying to draw an extra tile to the right. It happened when I went right quite far. I looked at your example and the only real difference was the get_tile function which basicaly seemed to do this:

if ( tile_x >= MAPWIDTH )    tile_x = tile_x % MAPWIDTH;if ( tile_x >= MAPHEIGHT )    tile_x = tile_x % MAPHEIGHT;


So I tried adding that, and it has fixed it, the program no longer crashed. The thing is I don't understand why it works. I don't see how using the % thing helps because surely that gets the remainder from "tile_x / MAPWIDTH", and say if tile_x is 30 and MAPWIDTH is 30 then it would set it to 0?

Am I right in saying it draws a tile off the screen to the right and if its at the end, it tries to draw a tile that doesn't exist so your function just overwrites it with somthing to prevent it from crashing? If so why don't you just do "if ( tile_x >= MAPWIDTH ) tile_x = 0" or somthing similar?

Thanks
I used the mod (%) operator in order to simulate the continuous map. Try outputing the values that go into it an then come out of it to a log file or to the console and you might understand how it works a little better. Basicly the mod operator does 2 things for me here:

1) it acts as a bounds checker by constraining the result to a value in a certain range.
2) it also happens to give me the propper value of the tile I want to draw.

So the mod operator kills 2 birds with one stone here. However, on to why your version crashed. I am assuming you did not want the map to contiue to wrap around. The trick here is to never allow the camera to move less than 0 or greater than the map width in pixels MINUS the screen width in pixels. Otherwise you will go out of bounds on your tilemap array. You will also need to add a check in there for if the get_tile function returns NULL since in my version it was impossible for it to go out of bounds. Another option is to keep that code the way it is and just limit the camera bounds. That way if you do go too far it won't crash on you.
Evillive2
Quote:Original post by evillive2
I used the mod (%) operator in order to simulate the continuous map. Try outputing the values that go into it an then come out of it to a log file or to the console and you might understand how it works a little better. Basicly the mod operator does 2 things for me here:

1) it acts as a bounds checker by constraining the result to a value in a certain range.
2) it also happens to give me the propper value of the tile I want to draw.

So the mod operator kills 2 birds with one stone here. However, on to why your version crashed. I am assuming you did not want the map to contiue to wrap around. The trick here is to never allow the camera to move less than 0 or greater than the map width in pixels MINUS the screen width in pixels. Otherwise you will go out of bounds on your tilemap array. You will also need to add a check in there for if the get_tile function returns NULL since in my version it was impossible for it to go out of bounds. Another option is to keep that code the way it is and just limit the camera bounds. That way if you do go too far it won't crash on you.


Ahh I see , thanks for the reply. I am already using a limit for the camera like you said, but I think the problem is that I am drawing say 1 or 2 tiles extra incase the tile isn't totaly to the right hand side because of the offset and everything. It works fine normaly but at the edge maybe it tries to draw tiles which don't exist. I'l have to experiment anyway, thanks.

edit: Yep, just fixed it! The problem was I tried to draw a tile or two too much all the time. Thanks though, trying to fix the bug and your reply made me understand it a lot more.

edit2: I just relised that fix wasn't perfect. Withought the extra tile it ment that the little bit of offset wasn't being drawn. So now I have sorted it out by adding 2 to the number of tiles to draw, but to stop the crash if the tile is bigger than it possibly could be I just set it to the biggest possible value. Although I think what I set to is irrelevent as long as it is a real tile.

[Edited by - kzar on February 1, 2005 5:39:47 AM]

This topic is closed to new replies.

Advertisement