Title: Beginning
1Beginning Game Programming
Murray State University Computer Science and
Information Systems Dr. Bob - bob.pilgrim_at_murrayst
ate.edu
2This Workshop
The goal of this workshop is to give you a head
start in beginning your study of game
programming. CD - Includes C/C compiler and
code editor (IDE), Allegro 4.2 game development
software library, tutorials and demo programs,
other software tools useful for creating computer
games. Workshop covers Overview of
Game Programming How to Install C/C
Compiler and Allegro Using the
Integrated Development Environment (IDE)
Running, reviewing, and modifying demo programs.
3Game Programming as a Career
Computer game development is probably the most
rapidly growing field in high technology today,
but it is important to understand that you need
to keep your options open.
"People looking at games courses should
consider what else you might be able to do if you
can't get into the industry, where else you can
go... somebody studying computer science, maths,
or physics and then coming into a programming
role, means that they can then go off into a
number of different industries and be
successful." - Matthew Jeffrey (Head of Global
Talent Brand at EA) "Developers are considering
applicants who have more general degrees (such as
in computer science or fine art), even though
these programs don't always give their students
industry-specific training." - Ben Kuchera
(Opposable Thumbs journal)
4Comments from Game Developers
"In my school, I had a game project with a random
team. I did all the work while they played guitar
hero and occasionally contributed barely-usable
code (despite multiple efforts to engage them). I
got a job and they did not. Could there be a
correlation?!? I think there is! " -
Quasius "I'm a programmer. I left the game
industry and now I have better pay, much lower
hours, and more flexibility (work from home, set
my own hours). Now I actually have time to play
games." - nvanderh More and more companies are
recruiting right from colleges. Regardless, of
what college you go to, you can still get a job
in the games industry provided you have a certain
proficiency in the following areas. Math,
Physics, Extensive knowledge of C, AI
Programming, Graphics, Tools Development,
Operating Systems, and Compilers." - Matt
Gilgenbach, a video game developer
5Why Game Programming?
FORTUNE! GLORY!
FUN! Programming games can be more fun than
playing them. Computer/Video Game Industry is now
larger than the Movie Industry A great new game
can make its creator famous. Game programming
teaches many computer science (CS)
topics Real-Time Systems Issues Modeling/Physic
s Graphics and Animation Sound
Generation Graphical Design and
Layout Human/Computer Interfaces Scientific
Visualization
6Types of Games
Classic Arcade 1st Person Shooter RPG Sports/Racin
g Board Games Adventure/Puzzle Solving Flight
Simulators World Simulations Strategy/Wargames Fig
hting Games
7Can One Person Still Write a Great Game ?
YES!
While many popular computer games are the result
of 100s of programmers, designers, writers,
artists, and producers, there is still a place
for the lone programmer. The growing popularity
of online (e.g. applet-level) games and games on
PDA's, handhelds, and even cell-phones need great
games. Lone programmers and small start-up game
companies can fill this need.
8Great Games come from Great Ideas
Each of the types of games started out as one
game and one person's idea.
9Establishing and Maintaining a Game Theme
One of the most important and most difficult
parts of game design is a finding a good theme.
The theme of a game affects the mood of the
player. It is important to put some thought into
choosing an good theme before jumping into the
details of game design and development. Keep the
theme of your game in mind as you design game
objects, the background and characters, choose
sounds, and decide on the order of the action.
10The Game Loop
Setup Game
time through loop must be short and the same
for each pass
Get User Input
wait
Sound
Update Game State
Graphics
no
done?
yes
Stop Game
11Why Use Dev_C/C and Allegro
Open Source - That is to say, FREE!!! Runs on
PC's, or Mac's using most any Operating
System Hugh Developer Network Many
User/Support Groups http//alleg.sourceforge.
net/wip.html http//www.allegro.cc/ Large
Number of Games and Software Tools Available
- Microsoft Windows
- Linux
- Mac OS X
- Solaris
- BeOS
- FreeBSD
12Enough Talk Already! Let's Get Started!!!
Installing Dev_C/C
- Open your Game Programming Workshop CD and copy
the file named devcpp-4.9.9.2_setup.exe to your
computer's desktop. - Run this install program. (Use the default
values for all options.) - Find and open the Dev_Cpp folder on your
computer (This folder should be installed at the
root level, i.e. at C\ ) - Copy the folder named Test_Dev_Cpp from the CD
into this folder. - Double click on the Dev-C desktop icon to
launch the compiler. - Under File, choose Open Project or File..., and
from inside the Dev-Cpp Test folder, select
Test_Dev_Cpp.dev. - Under the Execute menu, select Compile and Run.
13Loading the Allegro Software Library
- Open the Allegro-minGW-4.2.0 folder on your CD.
- Open the Dev_Cpp folder on your computer.
Locate the folders named lib and include. - Copy the contents of the lib folder on the CD
into the lib folder on your computer. (Note
Don't copy the folder, just its contents. - Copy the contents of the include folder on the
CD (including the sub-folder named allegro) into
the include folder on your computer. - Copy the contents of the bin folder on the CD
into the C\Windows\System32\ folder on your
computer. (These are files with a .dll
extension) - From your CD copy the folder named Test_Allegro
into the Dev_Cpp folder on your computer. - From the File menu, choose Open Project or
File... and select Test_Allegro.dev. - From the Execute menu, choose Compile and Run.
14Wow! That was easy...
Now we are ready to create our own projects.
1. Click on New Project taskbar icon.
2. Create an Empty Project named First_Project
3. Create a new source file called main.cpp and
add it to the current project.
15Wow! That was easy...
Now, we will learn how to create our own
project...
4. Right-click First_Project and choose Project
Options
5. Under the General Tab select Win32 GUI Type
6. Under Parameters Tab add the line -lalleg to
Linker and click on OK.
You are now ready to begin writing a graphics
program.
16First_Project
Enter this text in the editor, save, compile and
run it.
include ltallegro.hgt int main(void)
allegro_init() allegro_exit() return
0 END_OF_MAIN()
// includes allegro library in project
// starts and ends allegro // graphics commands
go between these lines
Since there are no graphics commands, nothing
will appear but you should get an error-free
compile.
17What Happened?
If you typed everything correctly your program
should have compiled and run with no messages
and no display. Otherwise you will see error
messages...
The first error wll be highlighted in the text
with a message trying to tell you what when
wrong. Fix each error in the order they appear
and only one at a time. This is because the
error checker is a dumb program that can get
lost. This problem is so common it has a special
name ERROR PROPAGATION
18First_Project
include ltallegro.hgt int main(void)
allegro_init() set_gfx_mode(GFX_SAFE, 640,
480, 0, 0) install_keyboard()
while(!keyKEY_ESC) allegro_exit()
return 0 END_OF_MAIN()
Now add these lines between allegro_init() and
allegro_exit() set_gfx_mode( ) defines a
display 640 x 480 pixels install_keyboard( )
lets your program take command from the keyboard
while(!keyKEY_ESC) tells the program to
wait on this line until the ESC
key has been pressed
19First_Project
include ltallegro.hgt int main(void)
allegro_init() set_gfx_mode(GFX_SAFE, 640,
480, 0, 0) install_keyboard()
while(!keyKEY_ESC) allegro_exit()
return 0 END_OF_MAIN()
When we run the program this time, a rectangular
display window named First_Project should appear
with a black background. This is the window that
will display the graphics, when we tell the
program what to display. Allegro gives this
window the name, screen. The whle( ) statement
tells the program to wait until the user presses
the ESC key.
20Drawing in the Graphics Window
include ltallegro.hgt define BLUE
makecol(0,0,255) int main(void)
allegro_init() set_gfx_mode(GFX_SAFE, 640,
480, 0, 0) install_keyboard()
rect(screen,50,60,150,160,BLUE)
while(!keyKEY_ESC) allegro_exit()
return 0 END_OF_MAIN()
defines the color BLUE using red, green,
blue (RGB) values
this statement tells the program to draw a
rectangle in the graphics window with one corner
at x50, y60 and the opposite corner at
x150 and y160 (100x100 pixel box)
21A Closer Look
640,0
0,0
50,60
rect(screen,50,60,150,160,BLUE)
150,160
increasing y
480
each point in this window is defined by a pair of
numbers (x,y)
increasing x
640
22RGB Color Values
255,255,0
0,255,0
255,0,0
255,0,255
0,255,255
0,0,255
Mixing Light is additive so 255,255,255
makes white
Each value is a number between 0 and 255.
makecol(rval,gval,bval) can be used to create
over 16 million colors
0,0,0 BLACK
23Try These Drawing Commands
int my_color my_color makecol(255,255,0) putpi
xel(screen,320,240,my_color) line(screen,10,100,6
30,100,my_color) rectfill(screen,200,300,250,370,
makecol(100,0,200)) circle(screen,230,110,30,make
col(50,200,10)) circlefill(screen,500,400,10,make
col(0,0,100)) ellipsefill(screen,185,210,100,30,m
akecol(50,50,50)) ellipsefill(screen,
180,200,100,30,makecol(255,0,0))
ellipse(screen, 175,195,100,30,makecol(255,180,18
0))
24Example Shapes
25A First Look at
ANIMATION
x max_x/2 y max_y/2 vx 2
vy -3 while(!keyKEY_ESC)
xold x yold y x x
vx y y vy if(xltradius
xgtmax_x-radius) vx -vx
if(yltradius ygtmax_y-radius) vy
-vy circle(screen,xold,yold,radius,BLACK)
circle(screen,x,y,radius,BLUE)
rest(20)
x,y is the ball position (starts in the middle of
the screen the speed of the ball in the x and y
directions - vx,vy
old position of ball
new position of ball
if ball reaches the edge, it bounces off (v
-v)
erase (undraw) old ball draw new ball
wait awhile (milliseconds)
26Bouncing Ball Demo
- Copy the folder named BouncingBall_Demo_01 from
your CD to the Dev-Cpp folder on your computer. - Open this folder and then load the project
BouncingBall_Demo_01.dev - Compile and Run this program
- Modify the values of vx, vy and the value in the
rest( ) function. With each change, run the
program and notice the effect of your changes.
27Making a Program Respond to User Keyboard Entry
install_keyboard() while(!keyKEY_ESC)
pxold px pyold py x x
vx y y vy px (int)x py
(int)y //watch out for sticky walls
if(pxltradius pxgtmax_x-radius) vx -vx
if(pyltradius pygtmax_y-radius) vy
-vy circle(screen,pxold,pyold,radius,BLAC
K) circle(screen,px,py,radius,BLUE)
rest(20) if(keyKEY_LEFT) vx
vx - 0.1 if(keyKEY_RIGHT) vx vx
0.1 if(keyKEY_UP) vy vy -
0.1 if(keyKEY_DOWN) vy vy 0.1
keyboard entry arrow keys change the x
and y velocity of the ball
28Interactive Bouncing Ball Demo
- Copy the folder named BouncingBall_Demo_02 from
your CD to the Dev-Cpp folder of your computer - Open the project and run it.
- Notice the effect of holding down one or more of
the arrow keys. - End the program and review the source code for
the user actions. - Modify the program and add key controls (such as
the digit keys) to change the color or size of
the ball.
Allegro defines KEYS as, A KEY_A 1
KEY_1 Z KEY_Z
circle(screen,px,py,radius,BLUE)
29Sound
Allegro gives us an easy way to add sound to our
game programs.
play_sample(sample_filename, volume, panning,
pitch, FALSE)
name of sample sound file to play
volume 0 to 255
speaker balance 0 to 255 (128 for equal balance)
frequency at which sample sound is played (1000
is normal)
looping (repeat sound) FALSE no, TRUE yes
30Adding Sound to the Bouncing Ball
Before using the play_sample( ) function, we
have to tell the computer which sounds we will be
playing. Add this code to BouncingBall_Demo_02
near the top of main.cpp (just after
install_keyboard( ) will be fine).
SAMPLE boing1 SAMPLE boing2 if
(install_sound(DIGI_AUTODETECT, MIDI_NONE, "") !
0) allegro_message("Error initializing
sound system") return 1 boing1
load_sample("boing1.wav") boing2
load_sample("boing2.wav")
Copy the sound files boing1.wav and boing2.wav
from the Sound Files folder into the
BouncingBall_Demo_02 folder.
31Now add the play_sample( ) functions to the
bounce detection code. Since we are adding a
second line of code to the if statements, we will
need to add curley brackets to hold them.
Otherwise the program will not know that the
sound files should be played only when the
conditional statement in the if( ) is true
if (pxltradius pxgtmax_x-radius) vx
-vx play_sample(boing1, 128, 128, 1000,
FALSE) if (pyltradius pygtmax_y-radius)
vy -vy play_sample(boing2, 255, 128,
1000, FALSE)
After modifying and running your version of the
Bouncing Ball, try running BouncingBall_Demo to
compare. In this version we set the pitch based
on the speed of the ball...
32WAV Sound Demo left-right balance, volume,
pitch control
SAMPLE sample1 SAMPLE sample2 int
panning 128 int pitch 1000 int
volume 128 //initialize the program
allegro_init() install_keyboard()
install_timer() set_gfx_mode(MODE, WIDTH,
HEIGHT, 0, 0) //install a digital sound
driver if (install_sound(DIGI_AUTODETECT,
MIDI_NONE, "") ! 0)
allegro_message("Error initializing sound
system") return 1
33//display program information textout_ex(screen,fo
nt,"PlayWave Program (ESC to quit)",0,0,15,0) tex
tprintf_ex(screen,font,0,10,15,0,"Snd Driver
s",digi_driver-gtname) textout_ex(screen,font,"Pl
aying clapping.wav...",0,20,15,0) textout_ex(scre
en,font,"Left,Right - Pan Left,Right",0,50,15,0)
textout_ex(screen,font,"Up,Down - Pitch
Raise,Lower",0,60,15,0) textout_ex(screen,font,"-
, - Volume Down,Up",0,70,15,0) //load
the wave file sample1 load_sample("evil_laugh.wa
v") sample2 load_sample("clapping.wav") if
(!sample1 !sample2) allegro_message("Err
or reading wave file") return 1 //play
the sample with looping play_sample(sample1,
volume, panning, pitch, TRUE) play_sample(sample2
, volume, panning, pitch, TRUE)
34while (!keyKEY_ESC) //change the panning
if ((keyKEY_LEFT) (panning gt 0))
panning-- else if ((keyKEY_RIGHT)
(panning lt 255)) panning //change
the pitch (rounding at 512) if ((keyKEY_UP)
(pitch lt 16384)) pitch ((pitch 513)
/ 512) 1 else if ((keyKEY_DOWN)
(pitch gt 64)) pitch ((pitch 511) /
512) - 1 //change the volume if
(keyKEY_EQUALS volume lt 255)
volume else if (keyKEY_MINUS volume gt
0) volume-- //adjust the sample
adjust_sample(sample1, 255-volume, 255-panning,
pitch, TRUE) adjust_sample(sample2, volume,
panning, pitch, TRUE) //pause
rest(5) destroy_sample(sample1) destroy_sampl
e(sample2) remove_sound()
35Pong The First Computer Game
We are going to look inside PONG, the first
computer game.
review Pong_Demo_01 Pong_Demo_02
36Deconstructing Pong
game space the game is played in a
rectangular box ball the ball travels in a
straight line until hitting an obstacle ball
bounces off top and bottom of game space
bounces off right face of left paddle and left
face of right paddle if ball encounters sides
of game space point is scored and play
restarts left and right paddles paddles stay
on sides of game space can move up and down only
paddles can put "english" on ball if ball hits
near the top or the bottom scoreboard keeps a
record of players scores - first to 11 wins
37game loop
init variables
quit game ?
yes
init allegro
no
new game ?
save old positiions
init
ball at top or bottom
bounce ball
exit allegro
ball hit paddle
return ball
ball miss paddle
score reset
update scoreboard
players input
Pong Game Block Diagram
paddles at top or bottom
stop paddle
animate
end loop
38Initialize Game State - PONG
// initialize game state padLeftX 20
// left paddle x-position
padRightX SCREEN_W - 20 // right paddle
x-position padLeftY SCREEN_H/2 //
left paddle y-position padRightY SCREEN_H/2
// right paddle y-position bxi
SCREEN_W/2 // starting ball
x-position byi SCREEN_H/2
// starting ball y-position bvyi 0
// starting ball
y-velocity bvxi 2
// starting ball x-velocity bx bxi
// ball
x-position by byi
// ball y-position bvx bvxi
// ball x-velocity
bvy bvyi //
ball y-velocity Lcount 0
// left-player score Rcount 0
// right-player
score
39Top of Main Loop - PONG
// check for game quit if (keyKEY_ESC)
done true // save current
paddle and ball positions before updates
padLeftYold padLeftY padRightYold
padRightY bxold bx byold by //
update ball position bx bvx by bvy //
bounce ball off top and bottom of game space if
(by lt 0 by gt SCREEN_H) bvy -bvy
40Manage Ball Hitting Paddle - PONG
// manage ball hitting left paddle if ((bx lt
padLeftX padWidth/2) (abs(padLeftY -
by)ltpadHeight/2)) bx padLeftX
padWidth/2 bvx - bvx bvy 0
if (padLeftY-bylt-padHeight/5) bvy 1 if
(padLeftY-bygtpadHeight/5) bvy - 1 if
(padLeftY-bylt-padHeight/4) bvy 2 if
(padLeftY-bygtpadHeight/4) bvy - 2 //
manage ball hitting right paddle if ((bx gt
padRightX - padWidth/2) (abs(padRightY -
by)ltpadHeight/2)) bx padRightX -
padWidth/2 bvx - bvx bvy 0
if (padLeftY-bylt-padHeight/5) bvy 1 if
(padLeftY-bygtpadHeight/5) bvy - 1 if
(padRightY-bylt-padHeight/4) bvy 2 if
(padRightY-bygtpadHeight/4) bvy - 2
41Checking Game Space Limits
(0,0)
?
if(padLeftYltpadHeight/2) padLeftY
padHeight/2 if(padLeftYgtSCREEN_H -
padHeight/2) padLeftY SCREEN_H -
padHeight/2 if(padRightYltpadHeight/2)
padRightY padHeight/2 if(padRightYgtSCREEN_H -
padHeight/2) padRightY SCREEN_H -
padHeight/2
padHeight
padLeftY
After player inputs have been handled the new
positions of the movable objects need to be
checked to ensure that they are within the game
space limits. What to do to keep the objects
inside the game space depends on the object's
function. For the paddles, you can just replace
the new position with the limiting position as if
it has hit a boundary.
42Manage Ball Passing Paddle - PONG
// manage ball missing left paddle if (bx lt
padLeftX padWidth/2) rectfill(screen,0,0
,SCREEN_W,SCREEN_H,BLACK) Rcount 1
bx bxi SCREEN_W/3 by byi bvy
0 bvx -bvxi // manage ball missing
right paddle if (bx gt padRightX - padWidth/2)
rectfill(screen,0,0,SCREEN_W,SCREEN_H,BLACK
) Lcount 1 bx bxi - SCREEN_W/3
by byi bvy 0 bvx bvxi
// update scoreboard rectfill(screen,
SCREEN_W/2-25,0,SCREEN_W/225,20,BLACK)
textprintf_ex(screen, font, SCREEN_W/2-20, 10,
15, -1, "d d", Lcount, Rcount)
43Players Move Paddles Using A,Z and K,M Keys - PONG
// manage user input for paddle movement if
(keyKEY_A) padLeftY - padVy if
(keyKEY_Z) padLeftY padVy if
(keyKEY_K) padRightY - padVy if
(keyKEY_M) padRightY padVy
44Stop Paddles at Boundary of Game Space - PONG
// manage paddles touching boundary of game space
if (padLeftYltpadHeight/2) padLeftY
padHeight/2 if (padLeftYgtSCREEN_H -
padHeight/2) padLeftY SCREEN_H -
padHeight/2 if (padRightYltpadHeight/2)
padRightY padHeight/2 if (padRightYgtSCREEN_H
- padHeight/2) padRightY SCREEN_H -
padHeight/2
45Animate Game - PONG
// animate ball and paddles circlefill(screen,bxol
d,byold,rad,BLACK) circlefill(screen,bx,by,rad,YE
LLOW) rectfill(screen,padLeftX-padWidth/2,padLeft
Yold-padHeight/2,
padLeftXpadWidth/2,padLeftYoldpadHeight/2,BLACK)
rectfill(screen,padRightX-padWidth/2,padRightYol
d-padHeight/2,
padRightXpadWidth/2,padRightYoldpadHeight/2,BLAC
K) rectfill(screen,padLeftX-padWidth/2,padLeftY-p
adHeight/2,padLeftX
padWidth/2,padLeftYpadHeight/2,GREEN) rectfill(s
creen,padRightX-padWidth/2,padRightY-padHeight/2,p
adRightX
padWidth/2,padRightYpadHeight/2,RED) rest(1)
46Adding some Excitement with a Bit of Randomness
Version 01 of Pong_Demo is functional but BORING!
Lets add some excitement by increasing the speed
of the return ball each time the ball hits the
center of the paddle. We can also randomize the
speed of the ball a little every now and
then. Insert the following lines of code at the
bottom of the if( ) that deals with the ball
hitting the paddle (both left and right).
if (bvy 0) bvx - 1 if (bvxlt-8) bvy
rand() 4 - 2 if (rand() 100 gt 94) bvy
rand() 4 - 2
You can skip the exercise and run Pong_Demo_02 to
see the changes.
47KING PONG
Now run King_Pong to see the value of adding
sound to your game.
48Game Space Layout
(SCREEN_W,0)
(0,0)
maintain 4 to 3 aspect ratio
(0,SCREEN_H)
(SCREEN_W,SCREEN_H)
49Computer Input Demo Programs
Keyboard Input Demo - Displays an open circle on
screen. Circle can be moved using the arrow
keys. The diameter of the circle can be changed
using the Page-Up and Page-Down keys. Movement
of circle is limited to keep circle on
screen. Mouse Graphics Demo - The program
demonstrates the use of the mouse in Allegro.
Mouse movement moves a spot on the screen.
Pressing the LEFT, RIGHT, or both mouse buttons
changed the color of the spot. Gamepad Demo - A
USB game controller must be plugged in for this
program to function. Program detects the game
pad and shows a simple graphical display
indicating the number of joysticks (2-axis) and
sliders (1-axis) controls, and the number of
buttons including the front fire buttons.
Program moves a yellow spot in screen, controlled
by 1st 2-axis control, the size of the spot is
changed by pressing button 7 and 8 and six
different sound events are invoked by pressing
buttons 1 through 6.
50Keyboard Demo run keyboard_input_demo
allegro_init() install_keyboard()
51Mouse Input Demo Mouse_Graphics_Demo
allegro_init() install_mouse()
52Joystick Input Demo joystick_demo
joystick_graphics_demo plug in generic gamepad
(USB) first
allegro_init() install_joystick(JOY_TYPE_AUTODETE
CT)
53GamePad Graphics Demo gamepad_demo
54GamePad Graphics Control Demo Sample Source Code
while(!keypressed()) //graphics loop
poll_joystick() xold x yold y
radius_old radius
if(joy0.stick0.axis0.poslt0) x x - 2
if(joy0.stick0.axis0.posgt0) x x 2
if(joy0.stick0.axis1.poslt0) y y - 2
if(joy0.stick0.axis1.posgt0) y y 2
if(joy0.button6.bgt0) radius radius - 1
if(joy0.button7.bgt0) radius radius 1
if(xgtmax_x) x max_x if(xlt0)
x 0 if(ygtmax_y) y max_y if(ylt0)
y 0 if(radiuslt2) radius 2
if(radiusgt100) radius 100
if(xold!x yold!y radius_old!radius)
circlefill(screen,xold,yold,radius_old,BLACK)
circlefill(screen,x,y,radius,YELLOW)
55Double Buffering
The purpose of double buffering is to eliminate
or reduce the flicker in an animation due to
drawing directly on the display being viewed
(screen). Instead we will draw on a bitmap
elsewhere in memory and then transfer (blit) the
completed image to the screen in one operation.
BITMAP buffer int ret
set_gfx_mode(GFX_AUTODETECT_WINDOWED, max_x,
max_y, 0, 0) if (ret!0)
allegro_message(allegro_error) return
1 buffer create_bitmap(SCREEN_W,
SCREEN_H) clear_bitmap(buffer) blit(buffer
, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H)
56Draw_Sprite_Demo Demonstrates loading and
displaying background image, loading, animation
and scaling of sprites, and blitting to replace
background under moving sprite. Includes loading
and playing sound with volume as a function of
distance from a specific point. Movement of
sprite is through arrow keys. Sound is invoked
with spacebar, when Carman sprite is close to
Chef. Special Features A simple 3D effect is
achieved by scaling sprite as it moves up and
down in scene.
57Sample Graphics Output
58Draw Sprite Demo
int main() char filename
"southpark_town.bmp" BITMAP bkg_image
BITMAP cartman int x, y double
scale int xold,yold int vol 128 int max_x
640 int max_y 480 SAMPLE
chef_hello int volume 255 int pan
128 int pitch 1000
//initialize the program allegro_init() inst
all_keyboard() set_color_depth(16)
set_gfx_mode(GFX_AUTODETECT_WINDOWED, max_x,
max_y, 0, 0) if (install_sound(DIGI_AUTO
DETECT, MIDI_NONE, "") ! 0)
allegro_message("Error initializing sound
system") return 1
59 //load the wave file chef_hello
load_sample("chef-hello_there_children.wav")
bkg_image load_bitmap(filename, NULL)
if (!bkg_image) set_gfx_mode(GFX_TE
XT, 0, 0, 0, 0) allegro_message("Error
loading s", filename) return 1
blit(bkg_image, screen, 0, 0, 0, 0, SCREEN_W,
SCREEN_H) //rectfill(screen,0,0,max_x,max_y,
GREEN) //print some status information
textprintf_ex(screen,font,0,0,WHITE,0,"Resolution
ixi", SCREEN_W, SCREEN_H)
textprintf_ex(screen, font, 0, 10, WHITE,0,"Color
depth i", bitmap_color_depth(screen))
//load the cartman bitmap cartman
load_bitmap("cartman.bmp", NULL) x
SCREEN_W/2 - cartman-gtw/2 y SCREEN_H/2
60//main loop while (!keyKEY_ESC) scale
(max_y/2 4.0(double)(y-max_y/2))/(double)(max_y
/2) stretch_sprite(screen, cartman, x, y,
scalecartman-gtw,scalecar
tman-gth) textprintf_ex(screen,font,0,20,WHITE,
0, "Location ixi", x, y) rest(20) xold
x yold y if(keyKEY_UP) y y -
1 if(keyKEY_DOWN) y y 1
if(keyKEY_LEFT) x x - 2 if(keyKEY_RIGHT)x
x 2 if(xold!x yold!y)
blit(bkg_image, screen, x, y, x, y,
scalecartman-gtw,scalecartman
-gth) if(xgtmax_x-cartman-gtw-20) x
max_x-cartman-gtw-20 if(xlt-20) x -20
if(ygtmax_y-cartman-gth) y max_y-cartman-gth
if(yltmax_y/2) y max_y/2 vol 255 -
abs(x-425) - abs(y-250) if(vollt0) vol 0
if(keyKEY_SPACE volgt10)
stop_sample(chef_hello)
play_sample(chef_hello,vol,128,1000,FALSE)
rest(100)
61Rotating Sprites Demo
rotate_sprite(buffer,sprite,x,y,itofix(ang))
ang is the angle of rotation in allegro units
0 - 360 degrees 0 - 255 allegro angle
units
Angles (ang) must be converted from integer to
fixed precision type values using the itofix( )
function included in the allegro library.
62Fifty-Two Pickup run CardDemo
As an example of accessing sprites from a
two-dimensional sprite sheet, we will drop cards
randomly onto the screen from a 52-card deck.
Actually we will be selecting card images at
random, so there will be many more that 52 cards
displayed.
63Managing the Cards Sprite
rank (0..12)
950
suit (0..3)
392
(rank73,suit98)
98
73
64Complete Source Code - 52 Pick-Up
void main(void) int cardwidth 73 int
cardheight 98 int width 1180 int
height 720 char filename
"cards_orig.bmp" BITMAP cards BITMAP
buffer allegro_init()
install_keyboard() set_color_depth(16)
int ret set_gfx_mode(GFX_AUTODETECT_WINDOWED,
width, height,0,0) cards
load_bitmap(filename, NULL) buffer
create_bitmap(width,height)
clear_bitmap(buffer) srand(time(NULL))
while(!keyKEY_ESC)
blit(cards,buffer,rand()13cardwidth,(rand()4)c
ardheight, rand()(width-cardwi
dth),rand()(height-cardheight),
cardwidth,cardheight) blit(buffer,screen,
0,0,0,0,width,height)
allegro_exit() END_OF_MAIN()
65Sample Run
66Translucent Sprites
Translucent sprites are used for many special
effects. The principle behind translucency is to
combine the r,g,b values of two pixels occupying
the same location in a bitmap. Normally you
replace the background pixels with the overlaying
sprite pixels using the blit( ) function. We
will set a to a value between 0.0 and 1.0 to
represent the fraction of the foreground pixel to
be used, so (1-a) will be the amount of the
background pixel used.
int pixbk, rbk, gbk, bbk int pixsp, rsp, gsp,
bsp pixbk getpixel(bkgimage,i,j) pixsp
getpixel(spriteimg,k,m) rbk getr(pixbk)
rsp getr(pixsp) gbk getg(pixbk) gsp
getg(pixsp) bbk getb(pixbk) bsp
getb(pixsp) rbk alpharbk
(1.0-alpha)rsp gbk alphagbk
(1.0-alpha)gsp bbk alphagbk
(1.0-alpha)bsp pixbk makecol(rbk,gbk,bbk)
67Card Drop Screen Saver CardScreenSaver demos
translucent sprites
In this example we will modify the previous card
demo to cause the cards to fade out after they
have been dropped onto the screen. This demo
woul make a good screen saver. After each card
drop will will reduce the brightness of every
pixel of the screen image using the function
dimmer( ).
void dimmer(void) int pix int r,g,b
for(int i0iltwidthi) for(int
j0jltheightj) pix
getpixel(buffer,i,j) r getr(pix)
g getg(pix) b
getb(pix) r - 8 g - 8
b - 8 if(rlt0) r0
if(glt0) g0 if(blt0) b0
pix makecol(r,g,b)
putpixel(buffer,i,j,pix)
68Modified Main Loop
while(!keyKEY_ESC)
blit(cards,buffer,rand()13cardwidth,(rand()4)c
ardheight, rand()(width-cardwid
th),rand()(height-cardheight),
cardwidth,cardheight
) dimmer() blit(buffer,screen,0,
0,0,0,width,height) allegro_exit()
69Sample Run
70Animated Sprite Demo uses Prince of Persia Sprite
Sheet
71(No Transcript)
72(No Transcript)
73(No Transcript)
74(No Transcript)
75(No Transcript)
76(No Transcript)
77(No Transcript)
78Sprite Sheet
728 x 90 pixels each image region is 728/13 56
x 90 pixels default transparency color is magenta
rgb (255,0,255)
num_steps 0 while(!keyKEY_ESC)
for(int i0ilt13i)
move num_stepsstep_size
blit(bkg_image, buffer, 660-move-10, 380,
660-move-10, 380, 76, 90)
masked_blit(sprite_sheet,buffer,
i56,0,660-move,380,56,90)
blit(buffer,screen,0,0,0,0,SCREEN_W,SCREEN_H)
num_steps 1 if(movegt720)
num_steps 0 rest(80)
covers old sprite with the proper region of the
background image
selects the proper segment of the sprite sheet to
display
79 char backname "BlueBkg.bmp" char
spritename "alladin.bmp" BITMAP
bkg_image BITMAP sprite_sheet BITMAP
buffer int sprite_width 56
int sprite_height 90 int step_size
5 int num_steps
int move //initialize the
program allegro_init() install_keyboard()
set_color_depth(16) set_gfx_mode(GFX_AUTODETE
CT_WINDOWED, 640, 480, 0, 0) bkg_image
load_bitmap(backname, NULL) if
(!bkg_image) set_gfx_mode(GFX_TEXT,
0, 0, 0, 0) allegro_message("Error
loading s", backname) return 1
sprite_sheet load_bitmap(spritename,NULL)
if(!sprite_sheet)
set_gfx_mode(GFX_TEXT,0,0,0,0)
allegro_message("Error loading s", spritename)
return 1
80buffer create_bitmap(SCREEN_W,
SCREEN_H) clear_bitmap(buffer) blit(bkg_image,bu
ffer,0,0,0,0,640,480) masked_blit(sprite_sheet,bu
ffer,0,0,15,130,728,90) num_steps
0 while(!keyKEY_ESC) for(int
i0ilt13i) move num_stepsstep_size
blit(bkg_image, buffer, 660-move-10, 380,
660-move-10, 380, 76, 90)
masked_blit(sprite_sheet,buffer,
i56,0,660-move,380,56,90)
blit(buffer,screen,0,0,0,0,SCREEN_W,SCREEN_H)
num_steps 1 if(movegt720) num_steps
0 rest(80) destroy_bitmap(bkg_image)
destroy_bitmap(sprite_sheet) allegro_exit() ret
urn 0
81Sprite Sheet for The Prince of Persia
82Creating a Sprite Image
In PowerPoint the objects are movable, so
animations are much simpler to create. Make sure
that each copy of the sprite is equally spaced in
the sprite sheet.
reference image
sprite_width 98 pixels
Tank Composed of Power Point 3D Objects
finished sprite sheet with transparency
83Tank Sprite Demo Implements an animated sprite
of a tank with a separately moveable gun tube
(barrel) on the turret. Tank motions is
controlled using the Z and X keys. Gun barrel
elevation is controlled using the Q and A keys.
Uses a sprite sheet created using Power Point and
Paint Shop Pro (see Lecture 9 for more info).
Demonstrates the integration of multi-part
sprites with rotate_sprite( ), masked_blit( ) and
normal blit( ) functions. Special Features
Sounds are integrated with sprite actions and
left-to-right panning is used to adjust the sound
levels in each speaker to correspond to sprite
position. Z and X move tank
backward and forward Q and A
raise and lower turret gun
84Sample Output
Z - move backward X - move forward Q - barrel
up A - barrel down
85Tank Sprite Demo Setup
char backname "BlueBkg.bmp" char
spritename "tank_sprite_sheet_sm.bmp"
char turretname "turretsprite.bmp"
BITMAP bkg_image BITMAP sprite_sheet
BITMAP turret_sprite BITMAP buffer
SAMPLE backsound SAMPLE tanksound
SAMPLE turretsound int sprite_width
98 int sprite_height 60 int step_size
5 int num_steps,i int move 0
int tankpan int turret_ang 255 bool
tankon false bool turreton false
Frames of moving tank are separated by 98 pixels
horizontally and fit in a 98 x 60 pixel
rectangle. The smallest move increment is set to
5 pixels. The horizontal position of the tank is
set by, move num_steps step_size
86Loading Bitmaps and WAV Files
//initialize the program allegro_init() install_k
eyboard() set_color_depth(16) set_gfx_mode(GFX_A
UTODETECT_WINDOWED, 760, 480, 0, 0)
bkg_image load_bitmap(backname,
NULL) sprite_sheet load_bitmap(spritename,NULL
) turret_sprite load_bitmap(turretname,NULL)
buffer create_bitmap(SCREEN_W,
SCREEN_H) clear_bitmap(buffer) blit(bkg_image,bu
ffer,0,0,0,0,760,480) //install a digital
sound driver if (install_sound(DIGI_AUTODETECT,
MIDI_NONE, "") ! 0) allegro_message("Error
initializing sound system") return 1
backsound load_sample("dead_wind_loop.wav")
tanksound load_sample("tankgo.wav") turretsou
nd load_sample("turret.wav") play_sample(backso
und, 128, 128, 1000, TRUE)
87Initial Position
i 0 num_steps 0 rotate_sprite(buffer,turret
_sprite,36,413,itofix(255)) masked_blit(sprite_s
heet,buffer, 15,10, 15, 405,
sprite_width,sprite_height)
blit(buffer,screen,0,0,0,0,SCREEN_W,SCREEN_H)
i3
i2
i1
i0
88Actions in Main Game Loop
while(!keyKEY_ESC) // barrel up
// barrel down // tank
backward // tank forward
// turn off tanksound //turn
off turretsound // draw and
display next frame
89Turret Gun Actions
// barrel up if(keyKEY_Q) turret_ang -
1 if(turret_anglt200) turret_ang200
if(!turreton) play_sample(turretsound,
255,tankpan,1000,TRUE) turreton true
adjust_sample(turretsound,255,tankpan,1000,T
RUE) // barrel down if(keyKEY_A)
turret_ang 1 if(turret_anggt255)
turret_ang 255 if(!turreton)
play_sample(turretsound,255,tankpan,1000,TRUE)
turreton true adjust_sample(turret
sound,255,tankpan,1000,TRUE)
90Turret Gun Tube Rotation
255
rotate_sprite(turret_sprite, buffer,destx,desty,it
ofix(ang))
ang
192
turret_sprite is twice as long as barrel because
axis of rotation is at the center of the image
and we wish to rotate barrel about one
end. placement of barrel in destination image is
offset so that back end of barrel is aligned with
front of tank turret.
91Tank Motion Actions
// tank backward if(keyKEY_X) i (i1)
4 num_steps 1 move
num_stepsstep_size tankpan
255move/SCREEN_W if(!tankon)
play_sample(tanksound,255,tankpan,1000,TRUE)
tankon true
adjust_sample(tanksound,255,tankpan,1000,TRUE)
// tank forward if(keyKEY_Z) i
i-1 if(ilt0) i3 num_steps -1 move
num_stepsstep_size tankpan
255move/SCREEN_W if(!tankon)
play_sample(tanksound,255,tankpan,1000,TRUE)
tankon true
adjust_sample(tanksound,255,tankpan,1000,TRUE)
92Stop Sounds Actions and Display
// turn off tanksound if(!keyKEY_X
!keyKEY_Z) stop_sample(tanksound)
tankon false // turn off
turretsound if(!keyKEY_A !keyKEY_Q)
stop_sample(turretsound) turreton false
// draw and display next
frame blit(bkg_image, buffer, 0,0,0,0,SCREEN_W,SCR
EEN_H) rotate_sprite(buffer,turret_sprite,36
move,413,itofix(turret_ang)) masked_blit(sprite_s
heet,buffer, 15isprite_width,
10, 15 move, 405, sprite_width,sprite_height)
blit(buffer,screen,0,0,0,0,SCREEN_W,SCREEN_H
) rest(80)
93Collision Detection - Atomic Fireflies Collision_D
etection_Demo_02
for(int k0kltNum-1k) for(int
mk1mltNumm) collide(k,m)
void collide(int k, int m)
if(collision_check) // handle
collision
Note Straight-line distance is not the most
efficient method for detecting collisions.
Compare with hit( ) function shown later.
double dist(int k, int m) return
sqrt(pow((ballk.x-ballm.x),2.0)
pow((ballk.y-ballm.y),2.0))
94Collision Detection Demo Program creates an
array of small moving objects that bounce around
the screen. For each frame, the location of all
pairs of objects are compared. When a pair is
detected to have collided, the event is marked
with an explosion event. The explosion event
begins a sixteen frame explosion sequence with
its position and velocity equal to the everage
position and velocity of the pair of colliding
objects. Special Features Demonstrates display
of multiple animated events. Collision_Detection_
Demo uses left and right arrow to change the
number of fireflies on screen.
95Collision Detection - Atomic Fire Flies
96Moving Balls and Explosion Struct Lists
struct ball_state double x
double y double vx double vy
int px int py int pxold
int pyold ball100 struct fire_state
double x double y double vx
double vy int count fire100c
97Extracting Frames from 2D Sprite
void draw_explosion(int x, int y, int c)
masked_blit(explosion,buffer,(c
4)64,(c/4)64,x-32,y-32,64,64) c 1
sprite images are 64 x 64 pixels
col c 4 row c / 4
Sometimes sprite sheets are arranged in
two-dimensional arrays of images. In these cases
we need to determine in which row and column each
image is placed so that they can be accessed and
displayed in the proper sequence.
256 x 256 pixel image of explosion
98Managing Multiple Animated Sprites
for(int k0kltbcount-1k) for(int
mk1mltbcountm) collide(k,m)
for(int q0qltfcountq)
if(fireq.count0) play_sample(exploderan
d()4,rand()56200,rand()256,
800rand()400,FALSE)
draw_explosion((int)fireq.x,(int)fireq
.y,fireq.count) fireq.x fireq.vx
fireq.y fireq.vy remove_fireballs()
draw_explosion( ) increments frame count of the
explosion sprites
Successive frames of two or more animated sprites
should be displayed concurrently. In this
example the frame count (fcount) is set to 0 by
the draw_explosion( ) function so it can be
removed from the active sprite list, fire .
99Managing An Array of Moving Objects
for(int i 0 iltbcounti) balli.pxold
balli.px balli.pyold balli.py
balli.x balli.x balli.vx rand()4-2
balli.y balli.y balli.vy
rand()4-2 balli.px (int)balli.x
balli.py (int)balli.y
if(balli.pxltradius balli.pxgtmax_x-radius)
balli.vx -balli.vx
if(balli.xgtradius)
balli.x(double)(max_x-radius) else
balli.x(double)radius
if(balli.pyltradius balli.pygtmax_y-radius)
balli.vy -balli.vy
if(balli.ygtradius)
balli.y(double)(max_y-radius) else
balli.yradius
circlefill(buffer,balli.pxold,balli.pyold,radi
us,ORANGE) circlefill(buffer,balli.px,ball
i.py,radius,BLUE)
100Detecting Collisions and Managing the Collision
List
int hit(int k, int m, int range) int xsep
int ysep xsep (int) (ballk.x -
ballm.x) ysep (int) (ballk.y -
ballm.y) if(xsepltrange xsepgt-range
ysepltrange ysepgt-range) return 1
else return 0 void collide(int k, int
m) if(hit(k,m,close_enough))
fcount1 firefcount-1.x (ballk.x
ballm.x)/2.0 firefcount-1.y
(ballk.y ballm.y)/2.0
firefcount-1.vx (ballk.vx
ballm.vx)/2.0 firefcount-1.vy
(ballk.vy ballm.vy)/2.0
firefcount-1.count 0
101Removing Completed Fireballs from the Fire List
void remove_fireballs(void) int inc 0
int dec 0 bool done (fcountlt0)
while(!done) if(fireinc.countgt15
decltfcount) dec 1
if(decltfcount) fireinc
firedec if(fireinc.countlt15)
inc 1 dec 1
done (decgtfcount)
fcount inc
fire. list is scanned and all members with
countgt15 are dropped. fcount is reduced by the
number of members eliminated.
102Side Scrolling Games
- Setting the World View
- Scrolling
- Defining Fixed Objects and Their
Actions/Reactions - Background
- Foreground
- Block
- Movable/Breakable
- Defining Characters and other Animated Objects
- Player
- Opponents
- Animated Interactive Object
- Loading Maps
- Controlling Display
103Scrolling
Horizontal (or vertical) scrolling gives us the
freedom to implement a game world that is much
larger than our display screen. Through the use
of double buffering and blitting we can smoothly
move through the game always displaying a view of
the game centered on the action and our character.
104Scanning a Panoramic Image A Step Toward
Horizontal Scrolling
while(!keyKEY_ESC) if(keyKEY_LEFT)
blitx - 3 if(blitxlt0) blitx 0
if(keyKEY_RIGHT) blitx 3
if(blitxSCREEN_Wgtbkgwidth) blitx bkgwidth -
SCREEN_W blit(bkgimage,buffer,blitx,blit
y,0,0,SCREEN_W,SCREEN_H) blit(buffer,screen,0,0
,0,0,SCREEN_W,SCREEN_H)
blitx and blity define the corner of the portion
of the bkgimage that will be displayed. bounding
conditions are used to ensure that the display
window stays inside the limits of the bkgimage.
105// Horizontal Scrolling Demo 1 include
ltallegro.hgt int max_x 640 int max_y
480 int blitx 0 int bkgwidth 7249
int bkgheight 529 int blity 0 char
filename "talafar.bmp" BITMAP bkgimage
BITMAP buffer void main(void)
allegro_init() install_keyboard()
set_color_depth(16) int ret
set_gfx_mode(GFX_AUTODETECT_WINDOWED, max_x,
max_y, 0, 0) bkgimage load_bitmap(filename,N
ULL) buffer create_bitmap(SCREEN_W,
SCREEN_H) while(!keyKEY_ESC)
if(keyKEY_LEFT) blitx - 3
if(blitxlt0) blitx 0
if(keyKEY_RIGHT) blitx 3
if(blitxSCREEN_Wgtbkgwidth) blitx bkgwidth -
SCREEN_W blit(bkgimage,buffer,blitx,b
lity,0,0,SCREEN_W,SCREEN_H)
blit(buffer,screen,0,0,0,0,SCREEN_W,SCREEN_H)
rest(1) END_OF_MAIN()
106The Central Object
int max_x 640 int max_y 529 int
chxmin 10 int chxmax 7239 int chymin
0 int chymax 519 int bkgwidth 7249 int
bkgheight 529 int blitx 320 int blity
40 double chx,chy,chvx,chvy,chax,chay double
chvxmax 20.0 double chvxmin -20.0 double
bounce 0.8 double dt 0.1
y
x
chx - x position chy - y position chvx - x
velocity chvy - y velocity chax - x
acceleration chay - y acceleration
107Motion in a Constant Gravitational Field
Separate the motion in the x direction
(horizontal) from motion in the y direction
(vertical). Gravity acts in the negative y
direction (-9.8 m/s2). There is no force in the
x direction on a moving object (without friction).
x, y - object location vx, vy - object
velocity ay - object acceleration due to gravity
-9.8 meters/second/second.
y
x
108Motion Controlled by Acceleration
chx 30.0 chy (double)chymax chvx 0.0
chvy 0.0 chay 9.8 chax 0.0
chvy chvy chaydt chvx chvx chaxdt chy
chy chvydt 0.5chaydtdt chx chx
chvxdt 0.5chaxdtdt
main loop
if(keyKEY_LEFT) chax - 1.0
if(chaxlt-5.0) chax -5.0
if(keyKEY_RIGHT) chax 1.0
if(chaxgt5.0) chax5.0
109Positioning the Display Screen in the World View
First the display screen is centered on the ball
and then its horizontal and/or vertical position
is shifted as needed to keep the display inside
the world view.
blitx (int)chx - SCREEN_W/2 blity (int)chy -
SCREEN_H/2 if(blitxlt0) blitx
0 if(blitxSCREEN_Wgtbkgwidth) blitx
bkgwidth - SCREEN_W if(blitylt0) blity
0 if(blitySCREEN_Hgtbkgheight) blity
bkgheight - SCREEN_H circlefill(bkgimage,(int)ch
x,(int)chy,8,makecol(255,0,0)) blit(bkgimage,buff
er,blitx,blity,0,0,SCREEN_W,SCREEN_H) blit(buffer
,screen,0,0,0,0,SCREEN_W,SCREEN_H)
110Drawing a Bitmap - Sample Output
111Loading a Bitmap
include ltallegro.hgt int main(void) char
filename "game_bkg.bmp" BITMAP image
int ret allegro_init()
install_keyboard() set_color_depth(16)
ret set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640,
480, 0, 0) if (ret ! 0)
allegro_message(allegro_error) return
1 //load the image file image
load_bitmap(filename, NULL) if (!image)
set_gfx_mode(GFX_TEXT, 0, 0, 0, 0)
allegro_message( "Error loading s" ,
filename) return 1 //display
the image blit(image, screen, 0, 0, 0, 0,
SCREEN_W, SCREEN_H) //done drawing--delete
bitmap from memory destroy_bitmap(image)
//display video mode information
textprintf_ex(screen,font, 0, 0, 1, -1, "dxd"
,SCREEN_W,SCREEN_H) //wait for keypress
while (!keypressed()) allegro_exit()
return 0 END_OF_MAIN()
112Sample Run
113Embedding Fixed Objects
vpix
game bkg image
hpix
map array
nrows
ncols
We can associate a text array with the game world
specifying the location of fixed sprites and
other game objects. The size of each sprite
region in pixels is given by, Each region will
be represented by an integer in the map array.
The value of the integer will determine the
properties of the object such as, movable,
breakable, background, foreground, etc...
spwidth hpix/ncols spheight vpix/nrows
114Map Array Details
Sprite Width 29 pixels Sprite
Height 20 pixels
560 28
0 - no sprite 1 - background sprite 2 - block
(immovable) 3 - movable 4 - breakable 5 - other
objects (such as ramps and pits).
115Loading Map Array
include ltfstream.hgt struct cell
int sprnum int block int
breakable int row int
col map28250 void load_map(void)
ifstream inFile inFile.open("map.dat")
for(int r0rltnrowsr) for(int
c0cltncolsc) inFile gtgt
maprc.sprnum inFile.close()
116Displaying the Map Array Cells in the Game World
View
load_map() for(int r 0rltnrowsr)
for(int c 0cltncols c) cnum
maprc.sprnum if(cnum 0) col BLUE
if(cnum 1) col GREEN if(cnum 2)
col RED if(cnum 3) col YELLOW
rectfill(bkgimage, cpwidth2, rpheight2,
(c1)pwidth-3, (r1)pheight-3,col)
leaves some space around each cell
pwidth width of cell in pixels pheight height
of cell in pixels
117Building a List of Blocking Cells
struct block int xmin int xmax
int ymin int ymax blocks100
for(int r 0rltnrowsr) for(int c
0cltncolsc) if(maprc.sprnum2)
blocksnumblocks.xmin pwidthc
blocksnumblocks.xmax pwidth(c1)
blocksnumblocks.ymin pheightr
blocksnumblocks.ymax pheight(r1)
numblocks 1
defines the limits each blocking cell
118Managing Collisions
When ball region is inside block a collision is
detected. Since there the ball can be in only
one place a hit is set and all other block tests
are suspended for this moment in the game. We
must also determine which surface of the block
the ball has contacted. In this example we use
the closest edge. Warning When there is a tie,
odds things can happen. We'll refer to these
anomalies as "special features" of the game. -)
119Code for Managing Collisions with Blocks
hit false for(int i0iltnumblocksi)
if(inside(chx,chy,sep,blocksi) !hit)
hit true dtime 0
diffxleft abs(((int)chxsep) -
blocksi.xmin) diffxright
abs(((int)chx-sep)-blocksi.xmax)
diffytop abs(((int)chysep) - blocksi.ymin)
diffybottom abs(((int)chy-sep) -
blocksi.ymax) diffx
min(diffxleft,diffxright) diffy
min(diffytop,diffybottom)
if(diffxltdiffy) chvx -
chvx if(diffxleftltdiffxright)
chx blocksi.xmin - sep
else chx blocksi.xmax sep
else chvy
- chvy if(diffytopltdiffybottom)
chy blocksi.ymin - sep
else chy blocksi.ymax
sep
120Redrawing Background Cells
hstart ((int)chx-pwidth)/pwidth hfinish
((int)chxpwidth)/pwidth vstart
((int)chy-pheight)/pheight vfinish
((int)chypheight)/pheight if(hstartlt0) hstart
0 if(hfinishgtncols) hfinish
ncols if(vstartlt0) vstart 0 if(vfinishgtnrows)
vfinish nrows for(int rvstartrltvfinishr)
for(int chstartclthfinishc)
cnum maprc.sprnum if(cnum 0)
col BLUE if(cnum 1) col GREEN
if(cnum 2) col RED if(cnum