perkiset

Well here it is – the infamous Missile Command OO lesson.

I regret that I cannot find the syllabus that I did for this, but the code should be pretty readable by anyone with a basic OO knowledge, even though it is in Object Pascal.

At the core of the app, there is an object list containing a live object of every element that is currently “in play” in the game ie., there’s an object for each attacking line, each defending line, each explosion, jets etc. The main loop here is called by a timer, and every time it is called it looks at each one of the elements and allows them a single action with the “pulse” function. This is an example of polymorphism and encapsulation all in one – the main routine has no idea what object it just pulled off the stack, nor what the pulse() function does for <that> object. That’s why all classes descend from the TBaseClass which contains the abstract methods that all the game pieces eventually override with real instructions.

Here is the most pertinent part of the main routine:

{
    Allow all the other items in the list to process. If we dont see any alive
    cities we kill the app.
    Later note - the cities never die - update this later
}

i := 0;
KeepGameGoing := False;
while i < ElementList.Count do
begin
// Note that this is the entire crux of the game operation. The game
// framework does not need to know what <kind> of object TempObject
// is, but since it decends from the base class, we can call the "Pulse"
// member procedure, which has been overridden in each object case to
// actuate different functional code.
tempObject := TGameObject(ElementList<>);
if tempObject.Pulse then
begin
{ TCities pulse True it they are alive }
{ All we need is one City pulse to keep the game alive... }
if tempObject is TCity then
KeepGameGoing := True;
Inc(i);
continue;
end else begin
if not (tempObject is TCity) then
begin                                                     
if tempObject is TAttackJet then
JetIsShowing := False;
TrashList.Add(tempObject);
ElementList.Delete(i);
end;
end;
end;

if not KeepGameGoing then
KillApp;


Here is an example of the hierarchy:

TGameObject
TLineBase
TDefender
TAttacker
TMirv
[/pre]

TGameObject = class(TObject)
private
procedure SetState(theState : TInitParm);
protected
myState : TInitParm;
public
constructor Create(theparm : TInitParm);
destructor Destroy; override;
// An abstract is a function that we want to reference in
// future decendents, but has no functional code in this class.
// Calling this kind of "pure virtual" function will result in
// an error if you call it without overriding it - you can however
// create children that do not override it if the intention is to
// never call that function. Care should be taken with that kind of
// coding though...
function Pulse : Boolean; virtual; abstract;
procedure ForceDone; virtual;
property ObjState : TInitParm read myState write SetState;
end;

TLineBase = class(TGameObject)
protected
Speed : Integer;      { Speed the Line Draws at }
YIsBase : Boolean;        { Y steps by one T/F }
HDirection : Integer;
VDirection : Integer;
Slope : Real;          { Mod of division }
SlopeInc : Real;        { Full division amount }
CurrentX : Integer;    { Current X position }
CurrentY : Integer;    { Current Y Position }
CheckProgress : Boolean; { Does this line check the color in front of it? }
ColorEnhance : Integer;
BlowAtDestination : Boolean;
public
constructor Create(theparm : TInitParm);
function Pulse : Boolean ; override;
procedure ForceDone; override;
end;

TDefender = class(TLineBase)
private
XAlt : Boolean;
XAltCounter : Integer;
public
constructor Create(theparm : TInitParm);
function Pulse : Boolean ; override;
end;

TAttacker = class(TLineBase)
public
constructor Create(theparm : TInitParm);
function Pulse : Boolean; override;
end;

TMirv = class(TAttacker)
private
SpreadTimer : Integer;
procedure SpreadOut;
public
constructor Create(theparm : TInitParm);
function Pulse : Boolean; override;
end;


Attached is the the source for the entire project, which was written originally in Delphi 5 but I believe it will compile in any Delphi or Kylix variant. Also attached is the compiled EXE which which I have only tested on XP, but I believe I wrote this while on NT3.51 so it should be reasonably back-and-forward compatible. I never added scoring so it goes on forever. You use the mouse to target and the A S and D keys to launch from the 3 bases. You can hold down one of the launch keys while mousing and get some pretty cool spreads. Use buttons 1-9 to set the leve you want to play at - it defaults to 1, 3 is fun. At level 8 and 9 it gets pretty insane.

And here is a snapshot of it running on one of my old Windows

mac

 hines:



Have fun!

perkiset

Bonus: I am a MAME fan. Find the MAME version for (your OS), get it running and then:

Here are the actual ROMs for the M!$$le c0mm@nd game (named munged on purpose). Create a directory called missile in your MAME ROMs directory, then unpack the attached tar.gz into it and you're good to go.

Have fun!

/p

jammaster82

sweet!!!  Takes me back to Hooters Girls with kegs and
buckets of wings!

we should have centOS running tomorrow, we installed
it today but space brained it and installed postgresql instead
of LAMP and all that jazz... ::doh!:: So rework in the am..

Would love to try to get this going on centOS..  apparently its
the most closely compatible to RH 9? 100%binary comp. supposedly.

Apparently i have scratched the copy of kylix i own and am
still waiting to hear from borland for a backup..

perkiset

Might be able to help you out with that mate... lemmee take a look and get back to you.


Perkiset's Place Home   Politics @ Perkiset's