1. Missile Command
The main set of improvements focus on creating dynamic code.
Objectives
● dynamic object management with lists
● C-style polymorphism
● screen to world, world to screen coordinate
Introduction
These are the notes that go along with the presentation.
Missile command turns out to be a relatively simple game to recreate the fun.
Approach
Build up. Tearing down or modifying existing code is hard and error prone. Decisions and tradeoffs
are often hidden and will be lost when you modify code. Copy and paste sets of functionality. Always
keep your game compiling and running.
Copy the working file, start with the game controller class. Copy all the classes. Rip out the insides of
the functions -- add a comment that signals what you have torn out since you will need to recode it.
Pointers
Pointers are fast. One owner.
Doubly Linked Circular Lists
Lists provide a good way to manage dynamic game objects. Many operations involve running through
each of the game objects and a more complex data structure would not help.
The list that I use has 3 fields, a next, previous, and type. The next points to the next node, the
previous points to the previous node, and the type identifies the node type.
C-Style Polymorphism
Use the type in the list node to identify the node type and then use a static cast to cast the node to the
type.
Setup the class structure with the common list node first. This allows you to link through the nodes as
simple nodes, determine the type, and then static cast to the complex type.
The other heavily used type of polymorphism is the matrix type. The mat12 starts with the X, Y, and Z
coordinates. Then the 3x3 rotation matrix follows.
Class Definitions
For the first iteration, define classes with all the fields public.
2. The first field in the class is a node for ou
// JFL 04 Oct 08
class Input : public qe {
public:
LLNode lnk; // must be first in structure
chr name[16]; // name
Input(chr *name); // constructor
int fillPlayerInpRec(PlayerInpRec *pir,int playerNum);
}; // class Input
Constants and sizeof()
It is a bad idea to embed naked constants in your code. When defining structures, follow the DRY
principle.
Nesting Depth
Construct functions to improve understanding by avoiding unnecessary nesting.
Flow Of Control
Construct your functions such that flow of control moves down.
Bit Flags
Use bitwise operators to define, set, test, and clear bits.
Use Character Constants for Quick Ids
There are three gun bases. The left, center, and right. Use the character constants 'L' 'C' 'R'. This
approach is good for simple sets of ids, but breaks down when you have more ids.
XYZ as Array
The order of XYZ is always X then Y then Z.
Use One Localized Control System
For example, the dispatch system sets a flag when it is finished. Multiple sections of code may read
this flag, but only one should clear it.
Expiration Times
Guarantee that game objects expire.
Always Be Simplifying
Continually clean your code. Remove unneeded functions and variables. Copy functions you would
like to keep into dead.c. It is easy to add code. It is especially hard for other programmers to
understand dead code.
3. Be wary of writing code or setting up systems you will need in the future. Procrastination pays.
Protect You Code
Write flexible code that can handle null pointers.
Ray v Plane
The ray versus plane intersection test is useful.
float a,b,t,dirRay[3],xyzRay[3],nrmPlane[3],kPlane,xyzCol[3];
// ray v plane
a = VecDot(dirRay,nrmPlane);
if((a>-EPSILON)&&(a<EPSILON))
goto BAIL; // dir in same dir as plane normal, no col
b = VecDot(xyzRay,nrmPlane);
t = (kPlane-b)/a; // distance to collision
VecAddScaled(xyzCol,xyzRay,dirRay,t);