Title: Sprites Computer Games Software Engineering
1SpritesComputer Games Software Engineering
- Last week we covered the basics of using eVC
and the third party games library GapiDraw to
create simple graphics applications for Pocket PC
devices. - This week we will start looking at some actual
games-like applications. - All the applications that you will develop for
this module will be 2D (unless you are very smart
indeed). - You can use 2D graphics to implement a large
number of games genres. These include
action/adventure games, card games and gambling,
strategy games, sports games and even first
person shooters (FPS).
2SpritesComputer Games Software Engineering
- Sprites are quite often the most important aspect
of a 2D game. The term sprite however is very
general. - A sprite is usually an animated, moving,
graphical icon which represents some part of the
game for instance both PacMan and the ghosts
that chase him are sprites. - Sprites typically have a number of attributes
that belong to them for instance they have a
position on the screen (or in the game world), a
graphical image or bitmap that the user sees, a
status (alive, dead, happy, sad etc.) etc. - It often makes sense to model sprites as a class
or a structure in your games since they have so
many attributes and often every sprite has
similar attributes.
3C/C Structures (structs)Computer Games
Software Engineering
- In addition to simple data types (int, char,
double, ...) C allows composite data types
which combine more than one data element. - Arrays store elements of the same type, which are
accessed by subscript, eg, pupili. - Structs (also called sometimes called records, or
even, incorrectly, classes) group elements which
don't need to all be the same type, and are
accessed by field (member) name, eg, pupil.name.
struct Pupil DWORD age LPSTR name
4Sprite representationComputer Games Software
Engineering
- For example, in Tutorial-3 you will create
sprites which have the following structure- - Hence each sprite will have a position, a
heading, a step size and an image (bitmap)
associated with it.
struct Sprite DWORD X_Pos // current x
position DWORD Y_Pos // current y position
DWORD last_direction // direction sprite is
heading DWORD X_Disp // distance in x sprite
moves in each step DWORD Y_Disp // distance
in x sprite moves in each step CGapiSurface
bitmap // sprites bitmap
5Using sprite structures Computer Games Software
Engineering
- Obviously all your sprite attributes are not
created automatically and have to be added at
appropriate points in an application. - In Tutorial-3 you will create an application that
features a background and a single, static,
sprite. - You will then add extra code so that the sprite
begins to move around the screen on its own. In
conjunction with this you will begin to use
resources (external data files) in your
applications.
6GapiDraw surfaces sprites Computer Games
Software Engineering
- Remember that last week we talked about GapiDraw
surface objects. - A CGapiSurface is a memory area to which you can
draw images and primitives (rectangles, lines,
text etc). - Each of your sprites will have one or more
surfaces associated with it. Usually you simply
fill this surface with a bitmap or image this
is what the user then sees in your game. Using
CGapiSurfaces for your sprites enables us to use
all of the GapiDraw graphics functionality to do
clever things later on like collision detection. - One reason for having more than one surface
associated with a sprite is if you want your
sprite to appear differently from time to time.
7Static and dynamic sprites Computer Games
Software Engineering
- You might want your sprite to appear differently
from time to time - for instance if it is
sleeping, sick or if it is actually dead (it
might even go invisible). - Alternatively, your sprite might have special
(enhanced or reduced) powers for a while. The
ghosts in PacMan are a great example of this. - For each of these examples you would use a
different surface containing a different graphic.
These examples though are probably still examples
of static sprites. - A dynamic sprite, on the other-hand, is a sprite
whose appearance is continuously animated
perhaps its colour continuously changes, or its
facial expression changes, or it looks as though
it is walking or driving etc.
8Image files and resourcesComputer Games Software
Engineering
- At the end of Tutorial-2 you were asked to create
a program that loads a background image from the
current working directory (i.e. the root
directory of the PDA). - This is awkward in that you have to make sure
that the image file is present in the correct
location. - Usually, and from Tutorial-3 onwards, you should
use resources for sprite bitmaps and the screen
background image. A resource is a data file which
is bound into the executable of your application
during the link phase. - Once resources have been bound up into your
project all you need to upload to the PDA (or
distribute to friends, or hand-in as your
coursework) is one (large) executable.
9Using resources in eVCComputer Games Software
Engineering
- To add resources to a eVC project firstly you
need to create a Resource Script (yet another
eVC configuration file) and add it to your
project. - Choose File-gtNew and pick Resource Script.
Enter the name of your project (e.g.
SimpleSprite) as the name for the script and
click OK. This process will have created a
SimpleSprite.rc file (which it automatically
opens in eVC) and a resource.h file in your
project folder. - You never have to bother much with the .rc file
so you should immediately close it (File-gtClose)
whilst you should include the resource.h file in
your main implementation file (e.g.
SimpleSprite.cpp). Once you start adding
resources eVC will automatically update your
resource configuration files.
10Using the GapiDraw iconComputer Games Software
Engineering
- eVC recognises a number of standard resource
types including icons (.ico) and bitmap files
(.bmp) though, in theory, you can use any type
of file you like as a resource. - Usually you should store all your resource files
in a sub-directory of your project called res
(short for resources!). - The should usually make each GapiDraw application
you create use the standard GapiDraw icon for
when it appears in the File Explorer. - To add the GapiDraw icon as a resource to your
project simply select Insert-gtResource (or hit
Cntl-R) and then click on Import. Navigate to a
copy of the icon (copied into your res directory
for instance) and select it.
11Using the GapiDraw iconComputer Games Software
Engineering
- The icon is then automatically loaded into eVCs
inbuilt bitmap editor and displayed on the
screen. For now you should just select
File-gtClose and press Yes to save changes so that
the icon is saved as a new resource. - It will then appear in the ResourceView pane at
the left hand side of eVC as an Icon resource
named IDI_ICON1. - This means that in your C code you can now
start referring to a resource called IDI_ICON1
if you look in the WinMain() function of the code
then this is exactly what happens -
config.dwWindowIcon IDI_ICON1
12Sprite bitmaps as resourcesComputer Games
Software Engineering
- I have provided some sample Space-Invader type
sprite bitmap image files (.bmp) in the res
folder for Tutorial-3 you should make an
effort though to start creating sprite bitmaps
of your own design. - To add an external bitmap file as a resource
simply select Insert-gtResource (or hit Cntl-R)
and click on Import . Then, in the dialog box
that appears change the Files of Type setting to
All Files (.) (rather than just icons). - Then double click on a bitmap file and the
contents of that file will then load into the
inbuilt eVC bitmap editor.
13Using Sprites in your codeComputer Games
Software Engineering
- If you dont want to edit the bitmap, you should
just select File-gtClose and press Yes to save
changes so that the icon is saved as a new
resource. - It will then appear in the ResourceView pane at
the left hand side of eVC as a Bitmap resource
named IDB_BITMAP1. You can then start referring
to this resource by name in your application. - Remember that we will use structures for storing
the attributes of each sprite instance, or
object. - Most of the initialisation of a sprite structure
can be done in the InitInstance member function
of your CGapiApplication derived application.
However, the allocation of surface content has to
be done in the CreateSurfaces function.
14Declaring the spriteComputer Games Software
Engineering
Define a structure called Sprite and declare an
instance of it in the main header file
15Initializing the spriteComputer Games Software
Engineering
Set the correct resource for the sprite in
CreateSurfaces
16Drawing the spriteComputer Games Software
Engineering
- The sprite is drawn to the backbuffer in the
ProcessNextFrame function. This is then flipped
to the physical display when this is
automatically updated. - The drawing (or blitting) of the sprite is done
using the GapiDraw CGapiSurfaceBltFast
function. - Blit, or blt, is short for bit block transfer.
17BlittingComputer Games Software Engineering
- Blitting simply implies that you are copying a
block of memory from one location to another. - This almost always refers in fact to copying
images from one source to another (though it can
be used for non graphical applications). - In games it is assumed that a blitting operation
will quickly draw a solid or transparent image to
the screen or backbuffer. GapiDraw has a few
different blitting operations usually you will
always use the BltFast one as it is hardware
accelerated and runs very quickly. - Blitting operations in fact are usually always
hardware accelerated and typically allow games
developers to do clever things with stretching as
well as transparency.
18CGapiSurfaceBltFastComputer Games Software
Engineering
19CGapiSurfaceBltFastComputer Games Software
Engineering
20Background imagesComputer Games Software
Engineering
- If you simply draw a sprite and nothing else in
the ProcessNextFrame() function then, by default,
your application has a black background. - You should get into the habit of using a
background image resource. This can be a bitmap,
a GIF or etc. The default format used by GapiDraw
however seems to be PNG images so we will stick
with that. - To use a PNG image as a resource Select
Insert-gtResource and click on Import. Then, once
again, make sure that you browse for files of all
type and double click on the file. - eVC does not recognise PNG images therefore it
asks you type in a new name for this resource
type. Type in PNG and press OK.
21Background imagesComputer Games Software
Engineering
- eVC will try to load a PNG resource up into an
editor because it is an image, the editor will
show a screen of nonsense data dont worry
about this simply select File-gtClose. A new
Resource folder will appear in the ResourceView
pane containing the PNG image labelled with an ID
of IDR_PNG1. - You then need to add a new member variable to
your CMyApplication class to define a background
surface. Do this in the header file so that the
attributes end up as
22Background imagesComputer Games Software
Engineering
- To load up your background image add the
following style of code to the CreateSurfaces
function- - Then add something like the following to draw
your background at the beginning of each
ProcessNextFrame - Note the difference between the way you are
FastBlting the sprite and the background. The
GDBLTFAST_KEYSRC parameter tells GapiDraw to use
transparency when drawing the sprite.
23Transparent backgroundsComputer Games Software
Engineering
- If you dont use the GDBLTFAST_KEYSRC flag (and
instead use NULL try it and see) then the black
background of the sprite would show up as big box
around the space invader not normally what you
want! - You can set the particular colour that is to be
transparent in a surface in the
CreateSurfaces() function by using the GapiDraw
method CGapiSurfaceSetColorKey(). - By default this is set to RGB(0,0,0) or black
so it can work by default if the background of
the sprite is black.
24Alpha BlendingComputer Games Software Engineering
- Using a color key allows us to specify pixels
that are completely transparent. Most graphics
systems also allow programmers to do gradual
transparency using alpha blending (or
alpha-blitting as well). - In computer graphics, an image uses 4 channels to
define its colour. Three of these are the primary
colour channels - red, green and blue. The
fourth, known as the alpha channel, conveys
information about the images transparency. It
specifies how foreground colours should be merged
with those in the background when overlaid on top
of each other. - Alpha takes any value from 0 to 1. When set to 0,
the foreground is completely transparent. When it
is set to 1, it becomes opaque and totally
obscures the background. Any intermediate value
creates a mixture of the two images.
25Moving spritesComputer Games Software Engineering
- Obviously an application with a single unmoving
sprite isnt going to set the gaming world
alight. - There are lots of ways of, and reasons for,
making your sprite move or to make it animated. - The first thing well look at is moving the
sprite around the screen in an autonomous
fashion. This kind of behaviour is required a
great deal in games often there might be
predators that are confined to a particular area
of the game but can roam randomly throughout that
area for instance. - Making a sprite move randomly however is not as
easy as it sounds. If each and every frame you
simply picked a new random direction for your
sprite then it would simple stutter about in more
or less the same place for most of the time.
26Randomly moving spritesComputer Games Software
Engineering
- Typically a sprite will have a velocity which
is a combination of heading and speed which
allows a sprite to move relatively smoothly in
the same direction until it encounters an
obstruction, or another sprite etc. - To keep things simple in our applications, our
sprites will have heading and a fixed step size
(i.e. the distance they can move in X and Y at
each update). - We will store a sprites heading as a number
from 0 to 7. - A sprite can move up (or North, or direction 0)
, up and right (or North-East, or direction 1),
right (or East, or direction 2) etc.
27Randomly moving spritesComputer Games Software
Engineering
- You can assign a sprite an initial random
direction and set it off moving updating its
position every time the screen is refreshed so
that it keeps moving in the same direction. - Obviously we dont usually want the sprite to
disappear off the edge of the screen so you
should check when this is about to happen and
then change the sprites direction. - At this point you could change the Sprites
direction randomly or you could set it moving
back in the opposite direction from where it
came. - The second option sounds quite nice but what
tends to happen is that the sprite just bounces
backwards and forwards between two edges of the
screen, so, for today, we will look at random
direction changes.
28Sprite coordinatesComputer Games Software
Engineering
- As well as deciding on what direction to send
your sprite you also need to be able to detect
when it is about to go off the side of the
screen. - Some games use the concept of tiles where a
sprite occupies a rectangular spot in the game
area similar to a chess or draughts piece. - Stopping the sprite going off the screen in that
case is a relatively simple matter of making sure
a move wont make your sprite occupy an invalid
tile. - We will continually check to make sure that the
sprite position doesnt go over the bounds of the
physical screen.
29Sprite coordinatesComputer Games Software
Engineering
- Your sprite bitmaps location (stored in its
member variables as X_Pos and Y_Pos) actually
record the upper left hand corner of the sprite
bitmap surface. - Note as well that if any part of the sprite
bitmap surface lies off the screen surface then
none of the sprite will be drawn. - At each sprite update a game should, after
calculating the next new position of the sprite,
check whether (i) the X value is less than 0,
(ii) the Y value is less than 0, (iii) the X
value is greater than the width of the screen
minus the width of the sprite, and (iv) the Y
value is greater than the height of the screen
minus the height of the sprite. - If any of these conditions is true, the sprite
has effectively hit the edge of the screen and
must change direction.
30Sprites as moving objectsComputer Games Software
Engineering
- When writing new code to alter the behaviour of a
sprite you should write it bearing in mind that
you might have multiple sprites running in the
same application and whose behaviour you might
want to alter in the same way. - Therefore it makes sense to write a new member
function to which you can pass any sprite from
ProcessNextFrame(). - This new behaviour member function should
calculate the new position of the sprite and send
this information back to the ProcessNextFrame()
function so that it can redraw the sprite at the
new location. - We will follow this convention as well when, next
week, we will create code to allow a sprite to be
user-directed.
31A randomly moving spriteComputer Games Software
Engineering
- In Tutorial-3 a new member function,
MoveSpriteRandomly, is defined which calculates a
new position for the sprite is based on its
current direction. - If this new position lies outside the drawable
screen area then the sprite is held stationary
for that frame and a new, different, direction is
randomly generated. - The call to the MoveSpriteRandomly() function
from the ProcessNextFrame() function passes a
long list of parameters as listed in the function
declaration in the header file-
32Call-by-reference in CComputer Games Software
Engineering
- You should notice that some of these parameters
have an ampersand () in front of them. - C, like Java, by default passes all parameters
to functions using what is termed call-by-value
i.e. the function only receives the value of the
parameter and cannot change the contents of the
variable from where that value came. - In our example we want the MoveSpriteRandomly()
function to change not only the X and Y position
of our sprite but also potentially its direction
as well. Hence these three parameters are passed
using what is termed call-by-reference in C -
this is done simply by placing the ampersand in
front of these parameters when the function is
declared and defined.
33A randomly moving spriteComputer Games Software
Engineering
- The call to MoveSpriteRandomly() is done before
the sprite is blitted by the ProcessNextFrame()
function- - Note that we simply pass the variables to it
which we want changing as we would normally in
this case the variables are actually stored as
part of our Sprite structure. - The MoveSpriteRandomly() function itself uses a
switch statement to calculate the next location
of the sprite based on its direction and current
location. Then it checks whether the move is
possible. If not it cancels any move and
generates a new random direction instead.
34MoveSpriteRandomlyComputer Games Software
Engineering
35MoveSpriteRandomly (cont)Computer Games Software
Engineering
36Further ReadingComputer Games Software
Engineering
- You should now be well into the process of
browsing the GapiDraw documention. - For this week you should make sure that you are
familiar with the documentation for
CGapiSurfaceBlt, CGapiSurfaceBltFast,
CGapiSurfaceAlphaBlt and CGapiSurfaceAlphaBltF
ast - You should have a read of how this can be used to
do some quite sophisticated things with
rotations, scaling, transparency and, in
particular, with alpha blending.