Sunday, November 08, 2015

Scrolling terrain map with wrap around

I started to work on a clone of the classic game Lunar Lander (see my GitHub repo). The reason I work on games is not that I want to be a game programmer but because there are lots of challenges that help becoming a better software developer and it is more fun coding games, i.e. it is more probable that I will keep my motivation and have a working prototype in the end.

In my clone, the lander's horizontal (x) position on the screen will remain constant and when the lander moves in the x direction, the lunar terrain will scroll to the left or right. I need a scrolling terrain map that wraps around and this problem is what I want to talk about in this blog.

My terrain map will be a list of x and y points. The x difference (dx) between the points will be variable. Only a certain portion of the map will be drawn on the screen at any given time. Think of it like a camera panning to the left or right where the camera x coordinate is the same as the lander's.

You could make the map so large that the user won't be able to hit the ends of the map in a reasonable time. But what I want is to have a small amount of points that wrap around, i.e. when the right side ends, it appears on the left side of the screen (and vice versa).

The algorithm is as follows (when the lander moves to the left by landerDx amount):
  • Increase the x values of all map points by the landerDx
  • if the rightmost map point x coordinate is smaller than the rightmost coordinate shown on screen
    • remove the rightmost point from list
    • create a new point which has the same y value as the removed rightmost point. The x coordinate of this new point will be (leftmost point).x - dx. Since the x distance between the points are variable we have to have a separate list to determine dx for that particular point pair. Note: In the beginning, since you know all x coordinates, you can generate the dx list by subtracting the x values of consequent points. However, dx between rightmost and left most points is undetermined. You have to separately set it to a value and add that value to the end of dx list. I usually choose that value as the average x distance between all points.
  •  Draw all map points. Only the points that fit the screen coordinates will be visible.
We can visualize the algorithm as shown below. In each figure, the top plot shows the whole map while the bottom plot shows the portion that will be drawn on screen by shifting the x coordinates by landerDx (in this example landerDx = 0.5):

No comments: