Isometric Engine Help

Started by
17 comments, last by BalooBear 22 years, 6 months ago
Ok, I want to program a Civisation / Alpha Centauri type game and have all the designs (in UML) and have read all the tutorials on Isometric programming on this site but there is just one problem. Not one of the tutorials takes the beginner (not to programming but just to isometric game programming) from setting up a direct 3d window to drawing the tiles to the screen in code form. Ideally in cut and paste style not so I can use it for myself (as I want to learn) but so I can see the whole picture. My question is, is there any isometric engine tutorials with complete examples or failing that a good engine with the source code? Thanks in advance, Baloo
Advertisement
Weeeeeeell.

There''s FreeCraft. It uses SDL, rather than DirectX, but should be good for the parts of your game that don''t need to worry about DirectX.

Joseph "Ironblayde" Farrel made a Game Programming Genesis series of articles here on gamedev that talk about DirectX in general and specifically about tile-based games. The story begins to unfold at http://www.gamedev.net/reference/programming/features/gpgenesis1

Martin Estevao has a Tiling in DirectX pair of articles. They start at http://www.gamedev.net/reference/programming/features/tiling1/

I tried looking under Real Time Strategy in sourceforge. Sadly, there aren''t many examples that are past the design stage, and many of them seem to obviously not be RTS games.

If you find you need some illuminating theory (and you will), I suggest Auran''s manual for their Tactics engine (as used in Dark Reign). It, and a description of the AI system the engine uses, reside at http://www.auran.com/games/darkreign/drengine.htm. Although, if you''re after a Alpha Centauri type of game, you''ll need far more sophisticated AI than Tactics. In fairness, you want far more sophisticated AI regardless, Tactics is pretty dumb.


Uuuuuulrika-ka-ka-ka-ka-ka
CoV
Thanks alot for your speedy response. Going to check out the links now.
Double Post Duhh!

Edited by - BalooBear on October 19, 2001 6:30:14 AM
Actually, a lot of gamedev''s isometric tutorials include good source. Look back at those tutorials and download the source. If you have basic knowlege of directx and c++ you should be able to learn from just studying those.
--Lowell N. Mannerslowell@makevideogames.comMakeVideoGames.com
Ok, thanks for all your help, got an engine up and running based on one of the tutorials. Now I''m wondering if I can animate 3ds or similar models on a tile. As the game is a civilisation/alpha centauri turn based game I dont need anything fancy but I would like to animate the units i.e troops playing with thier guns when selected e.t.c. I know its possible but how hard is it?

Baloo
Umm double post again whats happening?

Edited by - BalooBear on October 22, 2001 8:07:34 AM
<OFFTOPIC>

Chances are your browser is submitting the page twice, for some reason. I''ve not idea why it would do that, so I can''t be any help.

</OFFTOPIC>

Uuuuuulrika-ka-ka-ka-ka-ka
CoV
Hmm. Animation. There are two things you might want to animate, and its possible to animate them in almost exactly the same way.

You can animate tiles. For this we''re talking about animating the tiles themselves, and not a ''unit'' placed upon the tile. For example, you could add a ripple effect to a sea tile, or you could put a waving flag onto a city. You shouldn''t overdo animated tiles, because one of the uses of animation is to draw your attention to something - so you should probably only animate something that the user can interact with.

As an aside, if you can have units underwater, it might be nice to have them ripple along with the water itself. This would look good, and tell you visually that the unit is underwater. There are some tutorials here on gamedev about water effects.

The way to animate a tile is really quite simple, once you''ve drawn the frames. Lets imagine that your tile''s image is 64 pixels high, and 32 across. You''re holding a bitmap for masking, and the pixmap itself. This could be held as the following type:


/* The size of one frame is 2304 bytes. */
typedef struct {
bool bitmap[64][32];
char pixmap[64][32];
} TILE_IMAGE;


Firstly, we need a way to hold the tile frames. The brute force method is to define the TILE_IMAGE type as:


/* The size of one frame is 2304 bytes. */
typedef struct {
bool bitmap[64][32];
char pixmap[64][32];
} TILE_IMAGE[MAX_FRAMES];


Where MAX_FRAMES is the maximum number of frames a tile can have, 16, for example. But this is obviously wasteful, even a tile with only one frame would have to have space allocated for extra frames, and it''s quite possible that a tile''s bitmask will be constant - it may be a building with blinkenlights, for example - so duplicating it is again wasteful.


/* The size of one unique frame is 2312 bytes
* The size of one duplicate frame is 8 bytes. */
typedef struct {
bool *(bitmap[64][32]);
char *(pixmap[64][32]);
} TILE_IMAGE[MAX_FRAMES];


In this structure, we use pointers to maps. Identical frames would point to the same map. Duplicate frames are over 2k smaller, but each tile takes up at least 128 bytes (MAX_FRAMES*8), even if it had no frames. For one tiles, that''s okay, but your game may have hundreds.


/* The size of one unique frame is 2320 bytes
* The size of one duplicate frame is 16 bytes. */
typedef struct {
char frame_count;
struct TILE_FRAME {
bool *(bitmap[64][32]);
char *(pixmap[64][32]);
} frame[frame_count];
} TILE_IMAGE;


In this example, the arrays of images are allocated dynamically. A tile with only one frame is 2321 bytes in size (2320 for the frame, and one for the frame count). That''s an extra 17 bytes per tile, which is considerably better than 128.

In reality, you can''t just cycle through each frame. You may want the tile to stay on a particular frame for a long time, and another for only a short time. You might also want the tile to only enter a particular frame if you explicitly tell it to. (A power plant would probably look different when turned off). You need to tell it how long to wait on a particular frame, and which frame to go to next.


typedef struct {
char frame_count;
struct TILE_FRAME {
bool *(bitmap[64][32]);
char *(pixmap[64][32]);
char wait_time;
char next_frame;
} frame[frame_count];
} TILE_IMAGE;


So here we have the next version. Each frame has a wait_time, and a next_frame. For the power plant mentioned earlier, you might have frames 0-5 for its ''on'' state, and 6-10 for its ''off'' state. Frame 5''s next_frame would be 0, and frame 10''s next_frame would be 6. Another part of the program would be responsible for ensuring that the plant moves to a new frame when it comes online, or goes offline. If you wanted to be complex about it, you might have frames for ''on'', ''going offline'', ''off'' and ''going online''.

In practice, this isn''t what I do. With this system, you have to keep a track not only of each tile''s image, but also what frame in that image it is using, and how long until we need to move to the next frame. That''s a lot of data to be holding on each tile. What I do is this:


typedef struct {
bool *(bitmap[64][32]);
char *(pixmap[64][32]);
char next_image;
} TILE_IMAGE;
TILE_IMAGE *tileImages;


Now, all we need to know about each tile is which element in the tileImages array to use. In this system, you can''t control how long each frame is - all tiles change frames at the same time. For control over frame duration, I use sprites. Although this makes tiles less flexible, it makes the map a lot smaller in memory. (Each of my map-tiles is two bytes - one for the graphic to use, and the other is used to speed up checks on what units are in the tile. This limits me to 256 tile frames, altogether, but since I''d draw cities and improvements as units, it''s not an unreasonable limit).

There are two ways of drawing animated tiles that spring immediately to mind. The first involves creating multiple surfaces for the background. Lets imagine that the rule is that each animation can only be four frames long. Render the background four times, one for each frame, and also render the units and any foreground stuff into another surface. Each time the background frame changes, blit the foreground surface onto the current background surface and then flip the combined surface to the display. I''m currently investigation using overlay surfaces, a kind of automatic blit, to speed the whole process. An overlay is automatically blitted onto a surface its attached to when that surface is displayed. This means you can overlay the foreground over the background, then when you flip the background, the foreground will be blitted over the top at the same time. The second method of drawing the tiles is simply to redraw the surfaces each time. If there are too many frames for you to reasonably keep them all in memory at the same time, this may be your only option. Of course, when the view scrolls, you will need to redraw the newly exposed parts of the surfaces.

Animating Sprites.

You can animate sprites in much the same way as animating tiles.


typedef struct {
bool *bitmap;
char *pixmap;
char width;
char height;
char next_image;
char wait_time;
} SPRITE_IMAGE;
SPRITE_IMAGE *spriteImages;


The only extra data here is the width and height of the sprite, and the time to wait in this frame. The bitmap and pixmaps are no longer of constant size.

The information about the sprite itself has fields that indicate what image to use, and how long is left before we need to move to the next frame.

You can''t draw an animated foreground quite as quickly as you can draw an animated background, simply because each sprite changes frame at a different time, and may have hundreds of frames to go through. Best is to do a zbuffered blit onto the foreground when the sprite is changed. If you don''t want to use zbuffering, you''ll need to make sure that you redraw any sprites and/or tiles that are meant to obscure the one you just redrew.

Contextual Animation

That''s what I''m calling gun-fiddling behaviour since I don''t know of an official name for it.

Basically, you want a unit (or tile) to display an animation in response to something that happened to it (or just at random). The solution is quite simple. For example, to have your unit fiddle its gun when you select it, first create a series of frames with the gun-fiddling animation, then, when you select the unit, put it in the first of those frames. You can also have the unit fiddle its gun at random: lets say you''ve got a method on your units that is called each game ''tick'', you can randomly select to move to the gun-fiddling animation, or stay where you are. Many games have units do something when they''re bored - in Settlers the guys wave, grin, or exercise with a skipping rope when they haven''t done something for a while. In many FPS, the bad guys will fidget at random, which is a nice feature.

Now, 3D models. One of my favourite games is Total Annihiliationm, it uses 3D models, but a tiled map. The models are simple, but they can be very well animated, which makes them far more believable then many nice-looking but badly-animated units in other games. Firstly, animating a 3D model is fundamentally no different from animating a sprite - it''s still based on frames. Naturally, drawing a 3D model is completely different.

I can see two ways of animating of a 3D model. I''ve never done either, so they are probably inefficient. There are other forums and articles that can tell you far more than I about animating 3D characters.

The first is a brute force method which is basically an exact analog of sprite-based animation. For each frame, you define shape of the model, and its mapping coordinates so that the texture doesn''t slide over the model as it moves (assuming you''re texturing the model)). Now, when you draw the unit, you simply draw the current model.

The second involves skeletons and kinematics. It is more complex, but allows for more a richer range of expression on the part of the unit. I know nothing about this kind of system except that it exists, so I can''t say anything about its implementation.

The way I understand it, the first method is the most memory efficient if you have a lot of visually identical units (as is usually the case in an RTS), and is always processor efficient. The second method is more flexible, but is probably overkill for an Alpha Centauri clone.

Uuuuuulrika-ka-ka-ka-ka-ka
CoV
Thanks Mayrel, you have been a great help. Hope I can ask you some more questions as and when they pop up. Whats your background? Are you a hobby programmer or professional? Any project you working on at the moment? Currently I''m an Embedded Software Engineer with an ambition of being a games programmer. Maybe someday it will happen, this is definatley a step in the right direction.

Baloo

This topic is closed to new replies.

Advertisement