Home | Gaming | Programming | Play Online | Contact | Keyword Query
Games++ Games & Game Programming

GAMES++
Games++ Home
Games++ Gaming
Games++ Programming
Beta Testing Games
Free Online Games
Hints & Cheats

BROWSER UTILITIES
E-mail This Page
Add to Favorites

SITE SEARCH

Web Games++

AFFILIATES
Cheat Codes
Trickster Wiki
Game Ratings
Gameboy Cheats
PlayStation Cheats
BlackBerry Games
Photoshop Tutorials
Illustrator Tutorials
ImageReady Tutorials

ADVERTISEMENT

Aliens, Objects and Things

Techtutor: Part 2

Part 1 | Part 2 | Part 3 | Part 4 | Part 5

Introduction

Aliens, now here's a challenge. Every alien/enemy or object can have its own AI code, so I'm not explaining how to make them move, or animate, I will just explain procedures or functions to create them and use them.

For a small, but not complete example, look at source code at bottom of this page In this text I mainly talk about aliens, but objects and bonus things should be seen as static aliens (or maybe moving, but at least they can use the same kind of code).

OOPs?

I program my aliens by using Object Oriented Programming. This is something I'm not going to explain here since it's not that easy to understand, or to explain. Just buy a good book about OOP and read it carefully. Some people might think that OOP can not really be used for games but that's where they are wrong. OOP let's you create a base-alien object, and then you can simply add new aliens by creating objects based on the "base-alien". The "base-alien" should only have things like drawing it, collision-detections, initialisation for bullets, player-collision checking and a few other things. Since most alien-types will act different, you can easily create a new object-type for a certain alien. That object will then incorporate the movement, AI, animation and other SPECIFIC things about that alien type. Let's use an example.

Most people favourite game is QUAKE, Quake has a lot of different monsters, but they don't all "act" the same way. Let's see what we could do as a BASE-ALIEN object, and then I'll gave an example.

Collision Detection

All aliens, will need to be stopped when walking against a wall. Now you're game could have "ghost" aliens which are able to walk thru a wall, in that case you'll just write 1 extra collision routine specific for the "ghost" type aliens. But all other aliens can simply use the Base_Alien collision detections

Searching

All aliens will have to "SEE" if the player is in their sight. This procedure is the same for all aliens, so it can be put inside the Base_Alien. Just take a look at the enemies in Quake. If you sneak from behind every type will just be walking a certain path. This is the Base_Alien's routine which can be called from all alien-types.

Falling, Jumping, Diving

Most aliens will fall if there's no ground below them. So the "Gravity" procedures should be put in the Base_Alien. Note, however, that not all aliens will "walk" some might be flying in which case you won't have to call the procedure. There are a lot more procedures which can be put into the Base_Alien, but it depands on you're game. As you might have noticed the Base_Alien contains a lot of procedures that have to do with "game-physics" (ie. falling, looking, colliding ) that's exactly what should be in the Base_Alien! the physic-laws of you're game-environment.

What's left for the other objects?

Well the alien-specific object will include things like:

  • Shooting
  • Animating (but this could be done in the Base_Alien as well)
  • Thinking (only if you use multiple AI's) and a lot of other things which you need for only a few aliens.

{=-=-= Example =-=-=}
TYPE   Pactor = ^Tactor;   { this is the Base_Alien code }
       Tactor = object
         Xposition,
         Yposition    : integer;          { Xposition and Yposition       }
         Xstart,Ystart: integer;          { X+Y start positions           }
         Xspeed,
         Yspeed       : real;              { Xspeed and Yspeed             }
         xdir,ydir    : shortint;          { direction of movement         }
         AI           : byte;              { AI state                      }
         energy       : byte;              { energy of the alien           }
         ID           : byte;              { alien number                  }
         killed       : boolean;           { if actor is out of loop       }
         I_frame,
         f_Frame,                          { Animation frame data          }
         a_Frame,
         c_frame,
         t_frame,
         s_Frame     : byte;
         n_frame     : shortint;
         cycle       : boolean;

        CONSTRUCTOR INIT(xp,yp:integer);       { initialisation of alien  }
         PROCEDURE sub_init;           Virtual; { for some extra init     }
         PROCEDURE animate;            Virtual; { animate the images      }
         FUNCTION see_if_hit:boolean;  Virtual; { see if hit by bullet    }
         FUNCTION PLAYER_HIT:boolean;  Virtual; { see if hitting the player}
         PROCEDURE putit;              Virtual;  { draw the alien          }
         PROCEDURE movement;           Virtual;  { moving the alien        }
         PROCEDURE acting;             Virtual;  { the AI procedure        }
         DESTRUCTOR DONE;                       { For erasing alien        }
      END;

   {=-=-= Extra objects could look like this: =-=-=-=}
    TYPE  Psoldier = ^Tsoldier;   { A ground-walker (ie. soldier) }
          Tsoldier = object(TACTOR)    { is based on the Base_Actor    }
           PROCEDURE SUB_INIT; Virtual; { For specific initialisations }
           PROCEDURE Acting; VIRTUAL;   { For the AI of the soldiers   }
          END;
    
{=-=-= End of Example =-=-=}

How to Set It Up

Just like bullets, you could allso use a linked-list for the aliens but I usually just use an array of pointers. You'll first need a procedure which will create a new alien by specifying which alien-type you need. This could look something like this:

{=-=-= Example =-=-=-=}
FUNCTION AddActor(ai:byte;xp,yp:integer):Pactor;
BEGIN
 Addactor:=NIL;
 case ai of
    1 : addActor:=new(PGroundWalker,init(xp,yp)); { first alien type }
    2 : addActor:=new(PFlying,init(xp,yp));       { second alien type }
    { ... }
 end;
END;
{=-=-= End of Example =-=-=-=}

To process the aliens, you'll simply make a procedure that will go thru the list, and call the "main_acting" procedure of the alientype.

{=-=-= Example =-=-=-=}
PROCEDURE DoActors;
VAR i       : word;
BEGIN
 if actor_a=0 then exit;        { no actors to process                   }    
 i:=1;                          { start with first actor                 }
 while i < actor_a+1 do begin
   with act[i]^ do begin
        if not KILLED then begin        { if alien still lives,          }
           Acting;      { make it act (moving, shooting, etc...)         }
           PutIt;       { and draw it.                                   }
        end;
   end;
   inc(i);              { go to next actor in the array                  }
 end;
END;
{=-=-= End of Example =-=-=-=}

The "Main_Acting" procedure will handle the things like:

  • Movement, usually a procedure in the Base_alien object
  • Collision checking on walls, player(s), and other aliens, and the alien-specific procedures and AI.

Examples?

As I said at the beginning of this text, I won't go into procedure details for creating AI routines, there are other tutors and documents for that.. if you want to see some good AI routines, just take a look at Quake-C source codes, maybe you learn a few nice tricks from that...

I hope you learned something, and keep coding!

Next Tech topic: HighScores

{*******************************Source Code*********************************}
{

        TechTutor2
        Alien code, a simple (not working) example.

        Coding by P.Bestebroer
        FreeWare

        This source will not work on it's own, it just shows how to
        do alien-code into you're game...
        The source code was ripped from one of my game-projects, but
        because of this little tech-info I extruded variables which where
        needed in my game, but are not allways used.

        Contacting:

         HTTP://people.zeelandnet.nl/rpb/
        EMAIL:just4fun@zeelandnet.nl

}
PROGRAM Tech02;

USES CRT,OBJECTS;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
{
        First create the BASE_ALIEN variables
}
TYPE   Pactor = ^Tactor;   { this is the Base_Alien code }
       Tactor = object
         Xposition,
         Yposition    : integer;          { Xposition and Yposition       }
         Xstart,Ystart: integer;          { X+Y start positions           }
         Xspeed,
         Yspeed       : real;              { Xspeed and Yspeed             }
         xdir,ydir    : shortint;          { direction of movement         }
         AI           : byte;              { AI state                      }
         energy       : byte;              { energy of the alien           }
         ID           : byte;              { alien number                  }
         killed       : boolean;           { if actor is out of loop       }
         I_frame,
         f_Frame,                          { Animation frame data          }
         a_Frame,
         c_frame,
         t_frame,
         s_Frame     : byte;
         n_frame     : shortint;
         cycle       : boolean;

         CONSTRUCTOR INIT(xp,yp:integer);       { initialisation of alien    }
           PROCEDURE sub_init;           Virtual;  { for some extra init     }
           PROCEDURE animate;            Virtual;  { animate the images      }
           FUNCTION see_if_hit:boolean;  Virtual;  { see if hit by bullet    }
           FUNCTION PLAYER_HIT:boolean;  Virtual;  { see if hitting the player}
           PROCEDURE putit;              Virtual;  { draw the alien          }
           PROCEDURE movement;           Virtual;  { moving the alien        }
           PROCEDURE acting;             Virtual;  { the AI procedure        }
         DESTRUCTOR DONE;                       { For erasing alien          }
      END;
{=-=-=-=-=   Now create the Specific_Alien variables  =-=-=-=-=}
TYPE  PGroundWalker = ^TGroundWalker;   { A ground-walker (ie. soldier) }
      TGroundWalker = object(TACTOR)    { is based on the Base_Actor    }
           PROCEDURE SUB_INIT; Virtual; { For extra variables initialisation }
           PROCEDURE Acting; VIRTUAL;   { For the AI of the Ground-Walkers }
      END;

      PFlying = ^TFlying;               { A flying enemie }
      TFlying = object(TACTOR)          { is based on the Base_Actor   }
           PROCEDURE SUB_INIT; Virtual; { for extra variables initialisation }
           PROCEDURE Acting; VIRTUAL;   { for the AI of the Ground-Walkers }
         end;


VAR  act       : array[0..255] of Pactor;       { array of the actors        }
     actor_a   : byte;                          { amount of actors in game   }
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
{
        These are the procedures which could be used....
}
CONSTRUCTOR TACTOR.Init(xp,yp:integer); { to initialise an alien }
BEGIN
  {
     Set the position variables,
     the energy, the default values (ie. Killed=False)
  }
END;

PROCEDURE TACTOR.SUB_INIT;     { this is replaced by the specific_alien code }
BEGIN
 ABSTRACT;
END;

PROCEDURE TACTOR.ANIMATE;      { For the image-animations }
BEGIN
  {
      Animate the alien walking, flying, shooting, etc...
  }
END;

FUNCTION TACTOR.PLAYER_HIT:boolean; { see if hitting the player }
BEGIN
  {
      Check on collision between the player and the alien
  }
END;

FUNCTION TACTOR.SEE_IF_HIT:boolean; { See if hit by a bullet }
BEGIN
 {
      Walk thru the bullets, and check on collision with the alien..
      if hit set the KILLED flag to TRUE
 }
END;

PROCEDURE TACTOR.PUTIT; { Draw the alien on screen }
BEGIN
 {
     Draw the current frame-image of the alien on screen
 }
END;

PROCEDURE TACTOR.MOVEMENT; { This is for the moving of the specific_aliens }
BEGIN
  ABSTRACT
END;


PROCEDURE TACTOR.ACTING; { This will handle the AI of the specific_alien }
BEGIN
 ABSTRACT;
END;


DESTRUCTOR TACTOR.DONE;  { For erasing the alien from memory }
BEGIN
END;


{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
{             The custom-home-made-do-it-yourself enemy code                 }
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
PROCEDURE TGroundWalker.SUB_INIT;
BEGIN
  {
    Put the specific initialisation for the GroundWalking enemy
    in this little procedure...
  }
END;

PROCEDURE TGroundWalker.Acting;
BEGIN
 {
   Put all code for movement, collision detection and other things in this
   procedure...
   This is the "core" of the GroundWalking enemy, or call it his
   Artificial Intelligence routines
 }
END;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
PROCEDURE TFlying.SUB_INIT;
BEGIN
  {
    Put the specific initialisation for the Flying enemy
    in this little procedure...
  }
END;

PROCEDURE TFlying.Acting;
BEGIN
 {
   Put all code for movement, collision detection and other things in this
   procedure...
   This is the "core" of the Flying enemy, or call it his
   Artificial Intelligence routines
 }
END;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
{
        This code will intialise all the different aliens

        Expects : AI Number of the alien and other init variables
        Returns : a Pointer to the new TACTOR type

}
FUNCTION AddActor(ai:byte;xp,yp:integer):Pactor;
BEGIN
 Addactor:=NIL;
 case ai of
    1 : addActor:=new(PGroundWalker,init(xp,yp)); { first alien type }
    2 : addActor:=new(PFlying,init(xp,yp));       { second alien type }
    { ... }
 end;
END;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
{

        Process the actor_list

        Expects: Nothing
        Returns: Nothing

}
PROCEDURE DoActors;
VAR i       : word;
BEGIN
 if actor_a=0 then exit;        { no actors to process                       }
 i:=1;                          { start with first actor                     }
 while i156 do ;
  textcolor(7); textbackground(0); clrscr;
  writeln('TechTutor #2');
  writeln('written by P.Bestebroer, Just4Fun Productions');
  writeln('');
  writeln('This examples contains procedures for some great aliens/objects and things');
  writeln;
  writeln('Just like the previous tutor, this example needs some extra work aswell');
  writeln('Although the examples work, they wont display anything on the screen.');
  writeln('There are also no real "acting/movement" procedures because that is');
  writeln('upto you to implement (the easiest and most fun job!)');
  writeln;
  writeln('You should use a great VGA unit (SuperFX engine for example ;) and ');
  writeln('implement the things like drawing the objects');
  writeln;
  writeln('Watch out for the other techtutors...');
  writeln;
  writeln('Press a key');

  writeln;
  writeln;
  writeln;
  writeln('----------------------------------');
  writeln('Contacting: just4fun@zeelandnet.nl');
  writeln('http://people.zeelandnet.nl/rpb   ');
  writeln('----------------------------------');
  repeat until port[$60]<>156;

END.
Copyright © 1998-2007, Games++ All rights reserved. | Privacy Policy