The Stickman Game Engine:
A Win32 API 2-D Game Engine
By: Nick Cash






Description
of Major Features:
- Bitmap
Support:
Bitmaps
comprise all of the images in the game. They are simple to create and simple to
work with. Problems creating
this
feature including
getting them to load as a resource, which proved difficult since the function
wouldn't work. Also, the
Win32
function
TransparentBlt() turned out to act funky on some Windows machines, so it had to
be replaced by a equivalent
function using BitBlt().
- Sprite
Support:
Sprite's are
one of the most powerful features of the engine. They can be anything from a
projectile to a player
character.
A "sprite" is
basically an independent object that moves on the screen. It includes one of the
more complex structures, as
it
hold's everything from
pointer's to the sprites bitmap, velocity, position, name, and animation
information.
- Sound
Support:
The engine
support's two types of sound: MIDI and WAV. MIDI files are small and sound kind
of funny, while WAV's are
like decompressed MP3's and tend to be very large. Since the Win32 API doesn't
support WAV mixing on an easy
level,
I opted to use the
DirectX API's DirectSound capabilities. It allows me to allocate and play sounds
as I wish. It also gives
me
volume control and a few other features. Overall the DX API is bulky and ugly,
like everything Microsoft produces,
but
is useful and fairly
efficient at its tasks. Possible improvements on this could include streaming
audio, as allocating a 20MB
song drain's the memory pretty quick.
- Dynamic
Background Support:
One night my
mentor and I were talking and we decided that if the stars in the background
twinkled it would be really cool.
So, I
set out to program it. With the current set up, you can define any of three
types of backgrounds: IMAGE, COLOR, and
STARRY. IMAGE uses a specified bitmap, color uses a specified RGB value, and
STARRY will create between 1 and 100
twinkling stars. The system, with this set up, could easily be expanded to
incorporate more dynamic backgrounds, such
as
rotating planets or other types of
animation.
- Level
Scripting:
Perhaps the most
annoying but needed feature is level scripting. This allows you to
write a series of commands
(the "script")
for the game to
read, which will then be interpreted and used to create the level. This has a
great advantage over hard coding
level's
since you can then create levels externally and load them rather easily. With
this comes several level
management
features as
well. The main two are population management and
objects.
Population
management tracks the number of a certain sprite on a
level and will adjust the number accordingly. If there
are
fewer then the specified level then
it will add till it meets the requirement, if its in between the minimum and
maximum it will
add at random
follow this
algorithm/conditional:
if ( random_number( population[MIN], population[MAX] ) == population[CURRENT]
)
add_sprite();
Also, if there are more
sprites then the maximum number specified then it will remove until it hits the
max.
Objects are anything
that is draw in the level bitmap. Since level's are drawn as one image, it is
needed to define each object,
which is
definitely a pain. There are several types of objects that the game engine
supports. This list is as follows:
Solid,
Kill, Clim, Exit, Click, Move,
Launch, None. It is these objects that make up the levels, and probably the
things that matter
most. Any platform you
stand on, and solid moving object, and pad that launches you high into the air.
These are all objects.
- Log
Support:
A great and useful feature of any
game engine is logging. The ability to spot and find an error and record it is a
great time saver
for the programmer. The
engine employs two functions. Write_log() was written early on and isn't very
advanced. It employs
the messy and annoying
file interface of the Win32 API. It works, but you have to add all variables to
strings before hand.
This later prompted me to
write the game log function, which was shortened to glog(). This function will
take any number of
parameters and will log the
string accordingly. This is a time saver and a useful feature, as you then save
yourself anywhere
from 2-5 lines of code. It
also appears to be more efficient.
- String
Handling:
For scripted levels you need functions
to parse the string blocks. There are various functions that deal with string
handling.
Read_word() will grab the first
space terminated word it finds. Str_rep() will replace a given string with
another given string.
Other's remove
certain codes from a string, such as \n and spaces. Lastly, a function that
dates back a long ways, is one that
checks to see if
a string contains anything other then numerical digits. Very useful if you need
a number, not "a" or some other
character of the
alphabet.
- SMAUG's 32-bit
structure
Borrowed from SMAUG, this system
allows one integer to hold up to 32 values (0 - 31). This may not seem useful at
first,
but you can't return multiple things
sometimes, so its easy to designate bit values for them and return them all as
an int and
analyze the number
linearly.