IntroductionSo you've got the beginnings of a tile engine. You've got your world scrolling across the screen in 16-bit color, complete with animations and anything else you decided to add on your own... but it's a pretty lonely place so far, isn't it? Today we're going to fix that problem by going over an easy way to implement the game's main character, along with some NPCs to keep him company. I'll show you how to get your world scrolling around the character so he stays in the middle of the screen, how to configure NPCs, and how to work them into the function you already have for drawing the map. When all is said and done, we'll have a nice start on an RPG (or other tile-based game) that is easily expanded upon. As usual, I'll have a complete code example for you to play with. Throughout this article I'll be referring back to the basic tile engine we developed back in article #8, so if you haven't read it, and you haven't created a tile engine of your own before, go back and look over article #8 so you can follow along. Aside from that, all you need is a working knowledge of DirectDraw, the all-powerful Visual C++ (or one of those other ones), and some artwork to use. Ready to breathe a little life into your game world? Let's go! Keeping Track of CharactersAs usual, before we can go about getting something to move around on screen the way we want it to, we have to come up with a logical way to represent it in memory. Naturally, player characters and NPCs (non-player characters) are going to be represented somewhat differently. For instance, NPCs will need some flags or even a script assigned to them that describes how they move and act, whereas player characters do not, because they will be controlled by whoever's playing your game. Similarly, unless you're making your NPCs very complicated, they won't need a lot of the details that go into your player characters. For instance, non-combative NPCs don't need a number of hit points, a list of available spells, or a value for dexterity in a fight. This leads to a little bit of a problem: what happens when we want to start moving NPCs and player characters around? Are we going to have to write one set of functions for player characters, and another set for NPCs? Obviously we don't want to do that. You C++ people should be thinking about a typedef struct CHARMOVE_type { int xTile, yTile; // character's current location int xOffset, yOffset; // offset from tile location in pixels int xMove, yMove; // number of tiles character is currently moving int nFace; // direction character is facing; takes FACE_ constants } CHARMOVE, FAR* LPCHARMOVE; #define FACE_SOUTH 0 #define FACE_NORTH 3 #define FACE_EAST 6 #define FACE_WEST 9 All right, so what is all this stuff?
From here we might want to get started on structures for the whole player characters and NPCs, but I'm going to largely leave that out for now because all we'll really be dealing with is movement. The player structure would normally have all sorts of things in it like what level the character is on, what items he's carrying, what spells he can cast, and all kinds of other things. The NPC structure should have flags that determine how NPCs will be controlled. For now, I'm just going to leave those out and we'll use some kind of default values. Once we learn how to manipulate that, I'll show you what you can do to individualize your NPCs a bit. But for now, we'll just use these rather pointless structures: typedef struct PLAYER_type { CHARMOVE move; } PLAYER, FAR* LPPLAYER; typedef struct NPC_type { CHARMOVE move; } NPC, FAR* LPNPC; Now that we've got two structures serving no purpose other than to differentiate between a player and non-player character, let's go on to seeing just how we get them moving around in our game. |