A documentary on the effort to produce an original arcade-style game for the Tandy Color Computer platform.

Monday, January 16, 2012

Player Movement

I haven't said much about Fahrfall's actual progress lately. Real life makes plenty of demands on my time during the week, so there wasn't a lot of real progress to report up until the weekend. Now the weekend is over -- so how are things going?

When last we left Fahrfall, I had just demonstrated my ability to read the joysticks. Making a player object move on the screen seemed like the next logical step.

Something Sketchy

I had originally intended to start with a very simple player object -- a square or something, probably all one color. That would have let me progress with the game logic without having to decide on the artwork in advance. But something motivated me to sketch-out some variations of a player icon late last week. So rather than toying with a generic object, I decided to skip ahead with one of my sketched figures!

The easiest technique for drawing an object on the screen would be to simply block copy a source image to a specified target location. Two nested loops would control the operation, copying one byte at a time for a certain number of bytes. Use of a "magic" value (probably zero) for a data byte could even enable sections of an image to be transparent. This technique probably suffices in many situations. But the transparency checking imposes a non-zero cycle cost that is repeated every time the player object is drawn.

At present, I am using a different technique. I have a custom routine for drawing the player object. That routine loads a color used in the object, then uses a combination of 8- and 16-bit writes to fill-in the parts of the object which are that color. All of the colors are done in turn, and transparent sections simply are not written. This technique allows for transparency without requiring a number of conditional checks at runtime. Unfortunately, I haven't calculated the cycles used this way -- so, I don't know if this technique is actually better than the block copy! I should verify that at some point..

The drawing routine is paired with an erase routine. The erase routine is a bit simpler, since it only needs to use one color (i.e. black). Whenever the player object moves, the erase routine blacks-out the player object at its old position. Note that the combination of the fixed black background and the background scrolls being regularly redrawn allows for the erase routine to avoid having to actually restore any background bits.

With a draw routine and an erase routine in hand and the ability to read the joystick, everything is in place for player movement. For a simple demonstration of this, the player is drawn on the screen at a starting position. During each frame period, the joystick is read and a new position is calculated for the player, one byte to the left or right or one line up or down. During the vertical blank period, the player is erased at its old position and redrawn at its new position.

As noted in the video, there is a problem this technique. The 2-pixel per byte display format makes it impossible to move one pixel at a time on the horizontal axis. The solution is relatively simple: a second pair of draw/erase routines is added with the object displayed one pixel to the right. The horizontal movement routine alternates between even and odd draw/erase pairs in between every left/right byte change. This results in smoother horizontal movement, and avoids leaving the player object "stranded" one pixel away from the edge of the screen.

Sound Collision!

The collision detection routines shown above are minimalistic. They are really just enough to keep the player on the screen, but are obviously insufficient for the premise of Fahrfall. In the next update, I'll talk a bit about how Fahrfall detects collisions between the player object and the platforms.