Archived

This topic is now archived and is closed to further replies.

TheSisko

scrolling.....

Recommended Posts

I''m an extreme newbie to game programming. Now, I want to make a simple tile-based game. I read some things about it, but all of it was meant for C++. Myself, I use delphi, and I didn''t quite understand the c code... Are there any delphi/turbo pascal programmers here willing to explain to me the basics of scrolling?

Share this post


Link to post
Share on other sites
First of all, take a look at Amit''s Game Programming Site. He has links to many articles and tutorials on tile-based methods. A great resource for game programming theory.

You have a large map. Say it is 256x128 tiles in size. This is stored in memory. If each tile graphic is 32x32 pixels and you screen is 640x480 pixels, then you can display 20x15 tiles on screen at any one time.

Let''s say your map is stored in a two-dimensional array. Each tile is represented by a byte, giving us a maximum of 256 tiles. In a production environment, you would dynamically allocate the memory for this map, but we will use a static array for simplicity.
var
Map: array [0..255, 0..127] of Byte;
This map is loaded from file somehow, but that is not the purpose of this reply.

To draw the map on the screen, we need to read a section of the map and draw the corresponding tile at each location. I will assume that there is a DrawTile function that takes screen X and Y coordinates and a tile index. This function will draw the appropriate tile at the specified coordinates. To draw the map on screen, we need to draw 20 tiles across and 15 tiles down.
procedure DrawMap;
var
X, Y: Integer;
begin
for Y := 0 to 14 do
begin
for X := 0 to 19 do
begin
DrawTile(X * 32, Y * 32, Map[X, Y]);
end;
end;
end;
There is a problem with this in that it only draws the top-left corner of the map. We need X and Y offsets to draw any part of the map.
procedure DrawMap(OffX, OffY: Integer);
var
X, Y: Integer;
begin
for Y := 0 to 14 do
begin
for X := 0 to 19 do
begin
DrawTile(X * 32, Y * 32, Map[Off + X, OffY + Y]);
end;
end;
end;
Now we can draw any map of the map. By changing the offsets, we can do blocky scrolling. But maybe we want smooth scrolling? One way to do this is to change the offsets into a pixel offset instead of a tile offset.
procedure DrawMap(OffX, OffY: Integer);
var
X, Y: Integer;
TX, TY: Integer; // Tile offset
PX, PY: Integer; // Pixel offset
begin
TX := OffX div 32;
TY := OffY div 32;
PX := OffX mod 32;
PY := OffY mod 32;
for Y := 0 to 14 do
begin
for X := 0 to 19 do
begin
DrawTile(PX + X * 32, PY + Y * 32, Map[TX + X, TY + Y]);
end;
end;
end;
Much better, but there is a problem. When scrolling by less than a tile, we can see undrawn sections on the left and top. This is because when smooth scrolling, you must draw another row on the top and another column on the left to fill in the space.
procedure DrawMap(OffX, OffY: Integer);
var
X, Y: Integer;
TX, TY: Integer; // Tile offset
PX, PY: Integer; // Pixel offset
begin
TX := OffX div 32;
TY := OffY div 32;
PX := OffX mod 32;
PY := OffY mod 32;
for Y := -1 to 14 do // One more row on the top
begin
for X := -1 to 19 do // One more column on the left
begin
DrawTile(PX + X * 32, PY + Y * 32, Map[TX + X, TY + Y]);
end;
end;
end;
Be careful not use offsets that will cause your map indexes to go out of bounds. You can now use 32,32 (one tile size) as a minimum offset because both of the loops start at -1 now, resulting in map indexes of [0,0].

This method uses a brute force method and redraws the entire screen every frame. There are other methods that keep copies of the screen and copy it around to avoid having to redraw large sections of it. There are also various ways to optimize the above routine (hint: to multiply by 32, shift left by 5).

Hope that helps.

Steve ''Sly'' Williams  Monkey Wrangler  Krome Studios

Share this post


Link to post
Share on other sites
Whow, thank u sooooo much!
I already visited other sites, but they had sourcecode written in C++, and as I have only little experience with delphi, that wasn''t quite understandeable for me.

Share this post


Link to post
Share on other sites