Tricks of the Windows Game Programming Gurus:Putting It All Together: You God Game!

All ITKnowledge Source Code Search Tips Advanced Search |

| Tricks of the Windows Game Programming Gurus by Andre LaMothe Sams, Macmillan Computer Publishing ISBN: 0672313618 Pub Date: 09/27/99

Search this book:

Previous | Table of Contents | Next

### The HUDS

The HUDS (Heads-Up Displays) for Outpost consist of two main components: a scanner and some tactical information, including fuel, velocity, shields, ammo, number of ships left, and score. This is shown in Figure 14.16. It’s all rendered in a nice alien green—I love green. The tactical information is simply GDI-rendered text, but the scanner is DirectX-rendered via lines, bitmaps, and pixels.

Figure 14.16 The HUDs.

Take a look at the scanner code:

    void Draw_Scanner(void)

    {

    // this function draws the scanner

    int index,sx,sy; // looping and position

    // lock back surface

    DDraw_Lock_Back_Surface();

    // draw all the rocks

    for (index=0; index < MAX_ROCKS; index++)

        {

        // draw rock blips

        if (rocks[index].state==ROCK_STATE_ON)

            {

            sx = ((rocks[index].varsI[INDEX_WORLD_X] -

                   UNIVERSE_MIN_X) >> 7) +

                  (SCREEN_WIDTH/2) -

                  ((UNIVERSE_MAX_X - UNIVERSE_MIN_X) >> 8);

            sy = ((rocks[index].varsI[INDEX_WORLD_Y] -

                  UNIVERSE_MIN_Y) >> 7) + 32;

            Draw_Pixel(sx,sy,8,back_buffer, back_lpitch);

            } // end if

        } // end for index

    // draw all the gunships

    for (index=0; index < MAX_GUNSHIPS; index++)

        {

        // draw gunship blips

        if (gunships[index].state==GUNSHIP_STATE_ALIVE)

            {

            sx = ((gunships[index].varsI[INDEX_WORLD_X] -

                 UNIVERSE_MIN_X) >> 7) +

                   (SCREEN_WIDTH/2) - ((UNIVERSE_MAX_X -

                   UNIVERSE_MIN_X) >> 8);

            sy = ((gunships[index].varsI[INDEX_WORLD_Y] -

                 UNIVERSE_MIN_Y) >> 7) + 32;

            Draw_Pixel(sx,sy,14,back_buffer, back_lpitch);

            Draw_Pixel(sx+1,sy,14,back_buffer, back_lpitch);

            } // end if

        } // end for index

    // draw all the mines

    for (index=0; index < MAX_MINES; index++)

        {

        // draw gunship blips

        if (mines[index].state==MINE_STATE_ALIVE)

            {

            sx = ((mines[index].varsI[INDEX_WORLD_X] -

                 UNIVERSE_MIN_X) >> 7) +

                   (SCREEN_WIDTH/2) - ((UNIVERSE_MAX_X -

                   UNIVERSE_MIN_X) >> 8);

    sy = ((mines[index].varsI[INDEX_WORLD_Y] -

                  UNIVERSE_MIN_Y) >> 7) + 32;

            Draw_Pixel(sx,sy,12,back_buffer, back_lpitch);

            Draw_Pixel(sx,sy+1,12,back_buffer, back_lpitch);

            } // end if

        } // end for index

    // unlock the secondary surface

    DDraw_Unlock_Back_Surface();

    // draw all the stations

    for (index=0; index < MAX_STATIONS; index++)

        {

        // draw station blips

        if (stations[index].state==STATION_STATE_ALIVE)

            {

            sx = ((stations[index].varsI[INDEX_WORLD_X] -

                 UNIVERSE_MIN_X) >> 7) +

                   (SCREEN_WIDTH/2) - ((UNIVERSE_MAX_X -

                   UNIVERSE_MIN_X) >> 8);

            sy = ((stations[index].varsI[INDEX_WORLD_Y] -

                 UNIVERSE_MIN_Y) >> 7) + 32;

            // test for state

            if (stations[index].anim_state == STATION_SHIELDS_ANIM_ON)

                {

                           stationsmall.curr_frame = 0;

                           stationsmall.x = sx - 3;

                           stationsmall.y = sy - 3;

                           Draw_BOB(&stationsmall,lpddsback);

                } // end if

            else

                {

                             stationsmall.curr_frame = 1;

                       stationsmall.x = sx - 3;

                            stationsmall.y = sy - 3;

                           Draw_BOB(&stationsmall,lpddsback);

                } // end if

            } // end if

        } // end for index

    // unlock the secondary surface

    DDraw_Lock_Back_Surface();

    // draw player as white blip

    sx = ((int(player_x) - UNIVERSE_MIN_X) >> 7) + (SCREEN_WIDTH/2) -

         ((UNIVERSE_MAX_X - UNIVERSE_MIN_X) >> 8);

    sy = ((int(player_y) - UNIVERSE_MIN_Y) >> 7) + 32;

    int col = rand()%256;

    Draw_Pixel(sx,sy,col,back_buffer, back_lpitch);

    Draw_Pixel(sx+1,sy,col,back_buffer, back_lpitch);

    Draw_Pixel(sx,sy+1,col,back_buffer, back_lpitch);

    Draw_Pixel(sx+1,sy+1,col,back_buffer, back_lpitch);

    // unlock the secondary surface

    DDraw_Unlock_Back_Surface();

    // now draw the art around the edges

    hud.x          = 320-64;

    hud.y          = 32-4;

    hud.curr_frame = 0;

    Draw_BOB(&hud,lpddsback);

    hud.x          = 320+64-16;

    hud.y          = 32-4;

    hud.curr_frame = 1;

    Draw_BOB(&hud,lpddsback);

    hud.x          = 320-64;

    hud.y          = 32+128-20;

    hud.curr_frame = 2;

    Draw_BOB(&hud,lpddsback);

    hud.x          = 320+64-16;

    hud.y          = 32+128-20;

    hud.curr_frame = 3;

    Draw_BOB(&hud,lpddsback);

    } // end Draw_Scanner

I wanted you to see a typical scanner function because they tend to be a little messy. Basically, a scanner represents the position of various objects in a game, usually scaled and centered. The problem is making a huge space into a small space and drawing image elements that look realistic. Thus, the scanner imagery usually consists of a number of heterogeneous image elements.

Also, when you’re viewing a scanner, you want to be able to quickly pick out important data such as where you are, the positions of the enemies, and so on, so color and shape is very important. In the end, I decided to use one or more pixels to represent enemies, single gray pixels to represent asteroids, and actual bitmaps to represent the outposts. The player’s ship is represented by a glowing blob.

Finally, the scanner itself is supposed to be some kind of holographic imaging system. I wanted it to look cool, so I drew some nice bitmaps for the corners of it.

As for the workings of the scanner algorithm, take a look at the code. It does nothing more than divide the position of each object by some constant so the results fit into the window of the scanner.

### The Particle System

The particle system for Outpost is exactly like the one from Chapter 13, “Playing God: Basic Physics Modeling.” Particles can be created with various velocities and colors, and there are functions to create sets of particles with specific properties to mimic explosions and so forth. The important thing is not how particles work (because you already know), but how I used them.

Particles are used for a lot of things in Outpost. I want all the enemies to leave vapor trails when damaged. I want the player to leave plasma behind when flying around. And when something is damaged or blown up, I want a lot of particles to be part of the explosion in addition to the bitmap-animated explosions.

The cool thing about particles is that they’re so cheap and add so much to the visual excitement of a game. Not to mention that vapor trails and particles can be used as game elements themselves for tracking, or for other interpretations: food, footprints, whatever.

Previous | Table of Contents | Next

Copyright © Macmillan Computer Publishing, Inc.

Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.