Character Image FilesTo move characters around, I usually suggest a minimum of 12 frames. There are four cardinal directions, and in each direction, there should be one frame of the character standing still (facing that direction), one of him in mid-stride with left foot forward, and one with the right foot forward. That's what I'm using in Terran, and in each character image file, the frames are arranged in a vertical line like you see below. Notice that the leftmost character (frame #0) is facing south, frame #3 faces north, frame #6 faces east, and frame #9 faces west. Now do you see why I assigned the FACE_ constants the values that I did? To find out which frame to use for a character standing still, you just use the move.nFace variable. To get the frame with his right foot forward, you use move.nFace +1. And to get the frame with his left foot forward, you just use move.nFace +2. Convenient, hey? :) This character, by the way, is one of my current main character graphics from Terran. It'll probably change before the final game comes out. But my point in bringing this up is that all the graphics included for the demo that come with this article are pulled directly from my game; they are there for you to experiment with until you can come up with your own stuff, but when you do end up making a game and distributing it, please don't use my art, since it may appear in Terran as well. I know there's someone out there saying, "But Blayde, your art is so terrible, why would anyone want to steal it?" Well... you're probably right, but still, I thought I'd mention it. Anyway, matters of copyright aside, this is a convenient way to set up your image files and I recommend you use it, or something like it. Vertical lines work just as well as horizontal ones do; it's just a matter of preference. For my game and for our demo, each character fits inside a 32x64 box, so each character image should be 384x64, and you can easily locate a RECT rcChar = {0, nFrame << 5, 64, (nFrame << 5) + 32}; The Handling the CameraRemember back in article #8 when we set up the camera to define what part of the map was being drawn in each frame? Well, now we have to change it just a little. Last time, we set the camera so that it shifted in the appopriate direction anytime the user pressed the arrow keys. But in an actual game, chances are that you're not controlling the camera directly with the arrow keys; rather, you are controlling the character, and the camera follows the character. The simple method we used in that demo would be fine if the character was always going to be centered on the screen, but generally that is not the case. What happens when the character approaches the very edge of a map? If we centered the camera on him, then there would be an area of the screen with nothing displayed on it, and we don't want that. I'm sure you know what I mean; you've probably played a game that has the character centered on the screen, except when he gets near the edge of a map, at which point the camera remains still and the character moves towards the edge of the screen as well. That way, the whole screen is always occupied by the current map. So how do we implement this? Actually, it's quite easy. Instead of changing the camera every time the arrow keys are pressed, we'll calculate the camera coordinates during every frame, based on where the character is positioned in the world. Since our screen is 640 pixels wide and our character is 32 pixels wide, we can center the camera horizontally by locating the camera (640 - 32) / 2 = 304 pixels to the left of the character. Similarly, the screen is 480 pixels tall and our character is 64 pixels tall, so the camera should be placed (480 - 64) / 2 = 208 pixels above the character to center it vertically. Then to make sure the camera stops when the character gets near the edge of the screen, all we have to do is make sure the camera's coordinates don't drop below (0, 0), or go above the maximum allowable camera coordinates as defined in the // center camera on main character mapdata.xCamera = (player.move.xTile<<5) + player.move.xOffset - 304; mapdata.yCamera = (player.move.yTile<<5) + player.move.yOffset - 240; // clip camera to map boundaries if (mapdata.xCamera < 0) mapdata.xCamera = 0; if (mapdata.yCamera < 0) mapdata.yCamera = 0; if (mapdata.xCamera > mapdata.xMaxCamera) mapdata.xCamera = mapdata.xMaxCamera; if (mapdata.yCamera > mapdata.yMaxCamera) mapdata.yCamera = mapdata.yMaxCamera; It's worth mentioning here that this code should probably be included somewhere other than the map rendering function, because you may not always want to use it. For instance, in game story scenes, you'll almost certainly want to control the camera using a script instead of simply setting it to follow the character. If you think back to the logic diagram I showed you for Terran in article #7, this camera-control code is only used while the World Map game state is active. Story scenes, on the other hand, occur under the Scripts Only state, and so whatever scripts happen to be running at the time can do what they like with the camera. |