SlideShare une entreprise Scribd logo
1  sur  132
Beginning Game Programming Murray State University Computer Science and Information Systems Dr. Bob - bob.pilgrim@murraystate.edu
This 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.
Game 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)
"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 Comments from Game Developers
Why 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/Physics Graphics and Animation Sound Generation Graphical Design and Layout Human/Computer Interfaces Scientific Visualization : :
Types of Games Classic Arcade 1st Person Shooter RPG Sports/Racing Board Games Adventure/Puzzle Solving Flight Simulators World Simulations Strategy/Wargames Fighting Games
Can One Person Still Write a Great Game ? 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. YES!
Great Games come from Great Ideas Each of the types of games started out as one game and one person's idea.
Establishing 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.
The Game Loop Update Game State Get User Input Sound Graphics Setup Game done? Stop Game no yes wait time through loop  must be short and the  same for each pass the amount of wait depends on what else has been done in this pass
Why 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 ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Enough Talk Already! Let's Get Started!!! Installing Dev_C/C++ ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Loading the Allegro Software Library ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Wow!  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.
Wow!  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.
#include <allegro.h> int  main( void ) { allegro_init(); allegro_exit(); return  0; } END_OF_MAIN() First_Project // includes allegro library in project // starts and ends allegro // graphics commands go between these lines Enter this text in the editor, save, compile and run it. Since there are no graphics commands, nothing will appear but you should get an error-free compile.
What 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
#include <allegro.h> int  main( void ) { allegro_init(); set_gfx_mode(GFX_SAFE, 640, 480, 0, 0); install_keyboard(); while (!key[KEY_ESC]); allegro_exit(); return  0; } END_OF_MAIN() First_Project 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(!key[KEY_ESC])  tells the program to wait on this line until the ESC key has been pressed
#include <allegro.h> int  main( void ) { allegro_init(); set_gfx_mode(GFX_SAFE, 640, 480, 0, 0); install_keyboard(); while (!key[KEY_ESC]); allegro_exit(); return  0; } END_OF_MAIN() First_Project 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.
Drawing in the Graphics Window #include <allegro.h> #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 (!key[KEY_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 x=50, y=60 and the opposite corner at x=150 and y=160 (100x100 pixel box)
A Closer Look 640 480 0,0 each point in this window is defined by a pair of numbers (x,y) 640,0 50,60 150,160 increasing y increasing x rect(screen,50,60,150,160,BLUE)
RGB Color Values Each value is a number between 0 and 255. Mixing Light is additive so 255,255,255 makes white 255,0,0 255,0,255 255,255,0 0,255,0 0,0,255 0,255,255 0,0,0 = BLACK  makecol( r val ,g val ,b val )  can be used to create over 16 million colors
Try These Drawing Commands int my_color; my_color = makecol(255,255,0); putpixel(screen,320,240,my_color); line(screen,10,100,630,100,my_color); rectfill(screen,200,300,250,370,makecol(100,0,200)); circle(screen,230,110,30,makecol(50,200,10)); circlefill(screen,500,400,10,makecol(0,0,100)); ellipsefill(screen,185,210,100,30,makecol(50,50,50)); ellipsefill(screen, 180,200,100,30,makecol(255,0,0));  ellipse(screen, 175,195,100,30,makecol(255,180,180));
Example Shapes putpixel(screen,320,240,my_color); line(screen,10,100,630,100,my_color); rectfill(screen,200,300,250,370,makecol(100,0,200)); circle(screen,230,110,30,makecol(50,200,10)); circlefill(screen,500,400,10,makecol(0,0,100)); ellipsefill(screen,185,210,100,30,makecol(50,50,50)); ellipsefill(screen, 180,200,100,30,makecol(255,0,0));  ellipse(screen, 175,195,100,30,makecol(255,180,180));
A First Look at ANIMATION x = max_x/2; y = max_y/2; vx = 2; vy = -3; while (!key[KEY_ESC]) { xold = x; yold = y; x = x + vx; y = y + vy; if (x<=radius || x>=max_x-radius) vx = -vx; if (y<=radius || y>=max_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)
Bouncing Ball Demo ,[object Object],[object Object],[object Object],[object Object],motion in x direction and y direction are kept separate position of ball as a function of time is p = p 0  + v 0 t + 1/2 at 2 Note the  scary Physics Formula
install_keyboard(); while (!key[KEY_ESC]) { pxold = px;  pyold = py; x = x + vx;  y = y + vy; px = ( int )x;  py = ( int )y; //watch out for sticky walls if (px<=radius || px>=max_x-radius)  vx = -vx; if (py<=radius || py>=max_y-radius)  vy = -vy; circle(screen,pxold,pyold,radius,BLACK); circle(screen,px,py,radius,BLUE); rest(20); if (key[KEY_LEFT])  vx = vx - 0.1; if (key[KEY_RIGHT])  vx = vx + 0.1; if (key[KEY_UP])  vy = vy - 0.1; if (key[KEY_DOWN])  vy = vy + 0.1; } Making a Program Respond to User Keyboard Entry keyboard entry arrow keys change the  x and y velocity of the ball
Interactive Bouncing Ball Demo ,[object Object],[object Object],[object Object],[object Object],[object Object],circle(screen,px,py,radius,BLUE); Allegro defines KEYS as, A = KEY_A  1  = KEY_1 : Z = KEY_Z
play_sample(sample_filename, volume, panning, pitch, FALSE); Sound Allegro gives us an easy way to add sound to our game programs. 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
SAMPLE  *boing1; SAMPLE  *boing2; if (install_sound(DIGI_AUTODETECT, MIDI_NONE, &quot;&quot;) != 0)  { allegro_message(&quot;Error initializing sound system&quot;); return 1; } boing1 = load_sample(&quot;boing1.wav&quot;); boing2 = load_sample(&quot;boing2.wav&quot;); Adding 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). Copy the sound files  boing1.wav  and  boing2.wav   from the Sound Files folder into the BouncingBall_Demo_02 folder.
if (px<=radius || px>=max_x-radius) { vx = -vx; play_sample(boing1, 128, 128, 1000, FALSE); } if (py<=radius || py>=max_y-radius) { vy = -vy; play_sample(boing2, 255, 128, 1000, FALSE); } Now 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 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...
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,  &quot;&quot; ) != 0)  { allegro_message( &quot;Error initializing sound system&quot; ); return  1; } WAV Sound Demo left-right balance, volume, & pitch control
//display program information textout_ex(screen,font, &quot;PlayWave Program (ESC to quit)&quot; ,0,0,15,0); textprintf_ex(screen,font,0,10,15,0, &quot;Snd Driver: %s&quot; ,digi_driver->name); textout_ex(screen,font, &quot;Playing clapping.wav...&quot; ,0,20,15,0); textout_ex(screen,font, &quot;Left,Right - Pan Left,Right&quot; ,0,50,15,0); textout_ex(screen,font, &quot;Up,Down  - Pitch Raise,Lower&quot; ,0,60,15,0); textout_ex(screen,font, &quot;-,+  - Volume Down,Up&quot; ,0,70,15,0); //load the wave file sample1 = load_sample( &quot;evil_laugh.wav&quot; ); sample2 = load_sample( &quot;clapping.wav&quot; ); if  (!sample1 || !sample2)  { allegro_message(&quot;Error reading wave file&quot;); return 1; } //play the sample with looping play_sample(sample1, volume, panning, pitch, TRUE); play_sample(sample2, volume, panning, pitch, TRUE);
while  (!key[KEY_ESC])  { //change the panning if  ((key[KEY_LEFT]) && (panning > 0)) panning--; else if  ((key[KEY_RIGHT]) && (panning < 255)) panning++; //change the pitch (rounding at 512) if  ((key[KEY_UP]) && (pitch < 16384)) pitch = ((pitch * 513) / 512) + 1;  else if  ((key[KEY_DOWN]) && (pitch > 64)) pitch = ((pitch * 511) / 512) - 1;  //change the volume if  (key[KEY_EQUALS] && volume < 255) volume++; else if  (key[KEY_MINUS] && volume > 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_sample(sample2); remove_sound();
Pong The First Computer Game We are going to look inside PONG, the first computer game. review Pong_Demo_01 & Pong_Demo_02
Deconstructing 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 &quot;english&quot; on ball if ball hits near the top or the bottom scoreboard keeps a record of players scores - first to 11 wins
init allegro init init variables new game ? save old positiions end loop game loop ball at top or bottom ball hit paddle ball miss paddle quit game ? update scoreboard players  input animate score & reset return ball bounce ball paddles at top or bottom stop paddle exit allegro Pong Game Block Diagram yes no
// 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 Initialize Game State - PONG
// check for game quit if  (key[KEY_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 <= 0 | by >= SCREEN_H) bvy = -bvy; Top of Main Loop - PONG
// manage ball hitting left paddle if  ((bx <= padLeftX + padWidth/2) & (abs(padLeftY - by)<=padHeight/2)) { bx = padLeftX + padWidth/2; bvx = - bvx; bvy = 0; if  (padLeftY-by<-padHeight/5) bvy = + 1; if  (padLeftY-by>padHeight/5)  bvy = - 1; if  (padLeftY-by<-padHeight/4) bvy = + 2; if  (padLeftY-by>padHeight/4)  bvy = - 2; } // manage ball hitting right paddle if  ((bx >= padRightX - padWidth/2) & (abs(padRightY - by)<=padHeight/2)) { bx = padRightX - padWidth/2; bvx = - bvx; bvy = 0; if  (padLeftY-by<-padHeight/5)  bvy = + 1; if  (padLeftY-by>padHeight/5)  bvy = - 1; if  (padRightY-by<-padHeight/4) bvy = + 2; if  (padRightY-by>padHeight/4)  bvy = - 2; } Manage Ball Hitting Paddle - PONG
if(padLeftY<padHeight/2) padLeftY = padHeight/2; if(padLeftY>SCREEN_H - padHeight/2) padLeftY = SCREEN_H - padHeight/2; if(padRightY<padHeight/2) padRightY = padHeight/2; if(padRightY>SCREEN_H - padHeight/2) padRightY = SCREEN_H - padHeight/2; Checking Game Space Limits  padHeight padLeftY (0,0) ? 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.
// manage ball missing left paddle if  (bx < 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 > 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/2+25,20,BLACK); textprintf_ex(screen, font, SCREEN_W/2-20, 10, 15, -1, &quot;%d %d&quot;, Lcount, Rcount);  Manage Ball Passing Paddle - PONG
// manage user input for paddle movement if  (key[KEY_A]) padLeftY -= padVy; if  (key[KEY_Z]) padLeftY += padVy; if  (key[KEY_K]) padRightY -= padVy; if  (key[KEY_M]) padRightY += padVy; Players Move Paddles Using A,Z and K,M Keys - PONG
// manage paddles touching boundary of game space  if  (padLeftY<padHeight/2) padLeftY = padHeight/2; if  (padLeftY>SCREEN_H - padHeight/2) padLeftY = SCREEN_H - padHeight/2; if  (padRightY<padHeight/2) padRightY = padHeight/2; if  (padRightY>SCREEN_H - padHeight/2) padRightY = SCREEN_H - padHeight/2; Stop Paddles at Boundary of Game Space - PONG
// animate ball and paddles circlefill(screen,bxold,byold,rad,BLACK); circlefill(screen,bx,by,rad,YELLOW); rectfill(screen,padLeftX-padWidth/2,padLeftYold-padHeight/2, padLeftX+padWidth/2,padLeftYold+padHeight/2,BLACK); rectfill(screen,padRightX-padWidth/2,padRightYold-padHeight/2, padRightX+padWidth/2,padRightYold+padHeight/2,BLACK); rectfill(screen,padLeftX-padWidth/2,padLeftY-padHeight/2,padLeftX+ padWidth/2,padLeftY+padHeight/2,GREEN); rectfill(screen,padRightX-padWidth/2,padRightY-padHeight/2,padRightX+ padWidth/2,padRightY+padHeight/2,RED); rest(1); Animate Game - PONG
Adding 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  (bvx<-8) bvy += rand() % 4 - 2; if  (rand() % 100 > 94) bvy += rand() % 4 - 2; You can skip the exercise and run Pong_Demo_02 to see the changes.
KING PONG Now run King_Pong to see the value of adding sound to your game.
(0,0) (0,SCREEN_H) (SCREEN_W,SCREEN_H) (SCREEN_W,0) maintain 4 to 3 aspect ratio Game Space Layout
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. Computer Input Demo Programs
allegro_init(); install_keyboard(); Keyboard Demo run keyboard_input_demo
Mouse Input Demo Mouse_Graphics_Demo allegro_init(); install_mouse();
Joystick Input Demo joystick_demo & joystick_graphics_demo plug in generic gamepad (USB) first allegro_init(); install_joystick(JOY_TYPE_AUTODETECT);
GamePad Graphics Demo gamepad_demo
while (!keypressed()) { //graphics loop poll_joystick(); xold = x; yold = y; radius_old = radius; if (joy[0].stick[0].axis[0].pos<0)  x = x - 2; if (joy[0].stick[0].axis[0].pos>0)  x = x + 2; if (joy[0].stick[0].axis[1].pos<0)  y = y - 2; if (joy[0].stick[0].axis[1].pos>0)  y = y + 2; if (joy[0].button[6].b>0) radius = radius - 1; if (joy[0].button[7].b>0) radius = radius + 1; if (x>max_x)  x = max_x; if (x<0)  x = 0; if (y>max_y)  y = max_y; if (y<0)  y = 0; if (radius<2)  radius = 2; if (radius>100) radius = 100; if (xold!=x || yold!=y || radius_old!=radius) circlefill(screen,xold,yold,radius_old,BLACK); circlefill(screen,x,y,radius,YELLOW); GamePad Graphics Control Demo Sample Source Code
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); Double 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.
Draw_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.
Sample Graphics Output
int  main() { char  *filename =  &quot;southpark_town.bmp&quot; ; 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(); install_keyboard(); set_color_depth(16); set_gfx_mode(GFX_AUTODETECT_WINDOWED, max_x, max_y, 0, 0); if  (install_sound(DIGI_AUTODETECT, MIDI_NONE,  &quot;&quot; ) != 0)  { allegro_message( &quot;Error initializing sound system&quot; ); return  1; } Draw Sprite Demo
//load the wave file chef_hello = load_sample( &quot;chef-hello_there_children.wav&quot; ); bkg_image = load_bitmap(filename, NULL); if  (!bkg_image)  { set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); allegro_message( &quot;Error loading %s&quot; , 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, &quot;Resolution = %ix%i&quot; ,  SCREEN_W, SCREEN_H); textprintf_ex(screen, font, 0, 10, WHITE,0, &quot;Color depth = %i&quot; ,  bitmap_color_depth(screen)); //load the cartman bitmap cartman = load_bitmap( &quot;cartman.bmp&quot; , NULL); x = SCREEN_W/2 - cartman->w/2; y = SCREEN_H/2;
//main loop while  (!key[KEY_ESC]) { scale = (max_y/2 + 4.0*(double)(y-max_y/2))/(double)(max_y/2); stretch_sprite(screen, cartman, x, y, scale*cartman->w,scale*cartman->h); textprintf_ex(screen,font,0,20,WHITE,0, &quot;Location = %ix%i&quot;, x, y); rest(20); xold = x;  yold = y;  if (key[KEY_UP])  y = y - 1; if (key[KEY_DOWN]) y = y + 1; if (key[KEY_LEFT]) x = x - 2; if (key[KEY_RIGHT])x = x + 2; if (xold!=x || yold!=y) blit(bkg_image, screen, x, y, x, y,  scale*cartman->w,scale*cartman->h); if (x>max_x-cartman->w-20) x = max_x-cartman->w-20; if (x<-20) x = -20; if (y>max_y-cartman->h) y = max_y-cartman->h; if (y<max_y/2) y = max_y/2; vol = 255 - abs(x-425) - abs(y-250); if (vol<0) vol = 0; if (key[KEY_SPACE] && vol>10) { stop_sample(chef_hello);  play_sample(chef_hello,vol,128,1000,FALSE); rest(100); } }
Rotating 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.
Fifty-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.
950 392 98 73 (rank*73,suit*98) rank = (0..12) suit = (0..3) Managing the Cards Sprite
void  main( void ) { int  cardwidth = 73; int  cardheight = 98; int  width = 1180; int  height = 720; char  *filename =  &quot;cards_orig.bmp&quot; ; 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 (!key[KEY_ESC]) { blit(cards,buffer,rand()%13*cardwidth,(rand()%4)*cardheight, rand()%(width-cardwidth),rand()%(height-cardheight), cardwidth,cardheight); blit(buffer,screen,0,0,0,0,width,height); } allegro_exit(); } END_OF_MAIN() Complete Source Code - 52 Pick-Up
Sample Run
Translucent 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 = alpha*rbk + (1.0-alpha)*rsp; gbk = alpha*gbk + (1.0-alpha)*gsp; bbk = alpha*gbk + (1.0-alpha)*bsp; pixbk = makecol(rbk,gbk,bbk);
Card 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  i=0;i<width;i++) for( int  j=0;j<height;j++) { pix = getpixel(buffer,i,j); r = getr(pix); g = getg(pix);  b = getb(pix); r -= 8; g -= 8; b -= 8; if (r<0) r=0; if (g<0) g=0; if (b<0) b=0; pix = makecol(r,g,b); putpixel(buffer,i,j,pix);  } }
while (!key[KEY_ESC]) { blit(cards,buffer,rand()%13*cardwidth,(rand()%4)*cardheight, rand()%(width-cardwidth),rand()%(height-cardheight), cardwidth,cardheight); dimmer(); blit(buffer,screen,0,0,0,0,width,height); } allegro_exit(); Modified Main Loop
Sample Run
Animated Sprite Demo uses Prince of Persia Sprite Sheet
 
 
 
 
 
 
 
Sprite 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 (!key[KEY_ESC]) { for ( int  i=0;i<13;i++) { move = num_steps*step_size; blit(bkg_image, buffer, 660-move-10, 380, 660-move-10, 380, 76, 90); masked_blit(sprite_sheet,buffer, i*56,0,660-move,380,56,90); blit(buffer,screen,0,0,0,0,SCREEN_W,SCREEN_H); num_steps +=1; if (move>720) num_steps = 0; rest(80); } } selects the proper segment of the sprite sheet to display covers old sprite with the proper region of the background image
char  *backname = &quot;BlueBkg.bmp&quot;; char  *spritename = &quot;alladin.bmp&quot;; 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_AUTODETECT_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( &quot;Error loading %s&quot; , backname); return  1; } sprite_sheet = load_bitmap(spritename,NULL); if (!sprite_sheet) { set_gfx_mode(GFX_TEXT,0,0,0,0); allegro_message(&quot;Error loading %s&quot;, spritename); return  1; }
buffer = create_bitmap(SCREEN_W, SCREEN_H); clear_bitmap(buffer); blit(bkg_image,buffer,0,0,0,0,640,480); masked_blit(sprite_sheet,buffer,0,0,15,130,728,90); num_steps = 0; while (!key[KEY_ESC]) { for ( int  i=0;i<13;i++) { move = num_steps*step_size; blit(bkg_image, buffer, 660-move-10, 380, 660-move-10, 380, 76, 90); masked_blit(sprite_sheet,buffer, i*56,0,660-move,380,56,90); blit(buffer,screen,0,0,0,0,SCREEN_W,SCREEN_H); num_steps +=1; if (move>720) num_steps = 0; rest(80); } } destroy_bitmap(bkg_image); destroy_bitmap(sprite_sheet); allegro_exit(); return  0;
Sprite Sheet for  The Prince of Persia
Creating a Sprite Image Tank Composed of Power Point 3D Objects finished sprite sheet with transparency reference 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. sprite_width = 98 pixels
Tank 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
Sample Output Z - move backward X - move forward Q - barrel up A - barrel down
char  *backname =  &quot;BlueBkg.bmp&quot; ; char  *spritename =  &quot;tank_sprite_sheet_sm.bmp&quot; ; char  *turretname =  &quot;turretsprite.bmp&quot; ; 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; Tank Sprite Demo Setup 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
//initialize the program allegro_init(); install_keyboard(); set_color_depth(16); set_gfx_mode(GFX_AUTODETECT_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,buffer,0,0,0,0,760,480); //install a digital sound driver if  (install_sound(DIGI_AUTODETECT, MIDI_NONE,  &quot;&quot; ) != 0)  { allegro_message( &quot;Error initializing sound system&quot; ); return  1; } backsound  = load_sample( &quot;dead_wind_loop.wav&quot; ); tanksound  = load_sample( &quot;tankgo.wav&quot; ); turretsound = load_sample( &quot;turret.wav&quot; ); play_sample(backsound, 128, 128, 1000, TRUE); Loading Bitmaps and WAV Files
i = 0; num_steps = 0; rotate_sprite(buffer,turret_sprite,36,413,itofix(255)); masked_blit(sprite_sheet,buffer, 15,10, 15, 405,  sprite_width,sprite_height); blit(buffer,screen,0,0,0,0,SCREEN_W,SCREEN_H); i=0 i=1 i=2 i=3 Initial Position
while (!key[KEY_ESC]) { // barrel up  // barrel down // tank backward // tank forward // turn off tanksound //turn off turretsound // draw and display next frame } Actions in Main Game Loop
// barrel up  if (key[KEY_Q]) { turret_ang -= 1; if(turret_ang<200) turret_ang=200; if(!turreton) { play_sample(turretsound,255,tankpan,1000,TRUE); turreton = true; } adjust_sample(turretsound,255,tankpan,1000,TRUE); } // barrel down if (key[KEY_A]) { turret_ang += 1; if (turret_ang>255) turret_ang = 255; if (!turreton) { play_sample(turretsound,255,tankpan,1000,TRUE); turreton = true; } adjust_sample(turretsound,255,tankpan,1000,TRUE); } Turret Gun Actions
Turret Gun Tube Rotation rotate_sprite(turret_sprite, buffer,destx,desty,itofix(ang)); 255 192 ang 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.
// tank backward if (key[KEY_X]) { i = (i+1) % 4; num_steps +=1; move = num_steps*step_size; tankpan = 255*move/SCREEN_W;  if (!tankon) { play_sample(tanksound,255,tankpan,1000,TRUE); tankon = true; } adjust_sample(tanksound,255,tankpan,1000,TRUE); } // tank forward if (key[KEY_Z]) { i = i-1; if (i<0) i=3; num_steps -=1; move = num_steps*step_size; tankpan = 255*move/SCREEN_W;  if (!tankon) { play_sample(tanksound,255,tankpan,1000,TRUE); tankon = true; } adjust_sample(tanksound,255,tankpan,1000,TRUE); }  Tank Motion Actions
// turn off tanksound if (!key[KEY_X] && !key[KEY_Z]) { stop_sample(tanksound); tankon = false; }  // turn off turretsound if (!key[KEY_A] && !key[KEY_Q]) { stop_sample(turretsound); turreton = false; }  // draw and display next frame blit(bkg_image, buffer, 0,0,0,0,SCREEN_W,SCREEN_H); rotate_sprite(buffer,turret_sprite,36 + move,413,itofix(turret_ang)); masked_blit(sprite_sheet,buffer, 15+i*sprite_width, 10, 15 + move, 405, sprite_width,sprite_height);  blit(buffer,screen,0,0,0,0,SCREEN_W,SCREEN_H); rest(80); Stop Sounds Actions and Display
Collision Detection - Atomic Fireflies Collision_Detection_Demo_02 for ( int  k=0;k<Num-1;k++) for ( int  m=k+1;m<Num;m++) collide(k,m); void  collide( int  k,  int  m) { if ([collision_check]) { // handle collision } } double  dist( int  k,  int  m) { return  sqrt(pow((ball[k].x-ball[m].x),2.0)  + pow((ball[k].y-ball[m].y),2.0)); } Note: Straight-line distance is not the most efficient method for detecting collisions.  Compare with hit( ) function shown later.
Collision 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.
Collision Detection - Atomic Fire Flies
struct  ball_state { double  x; double  y; double  vx; double  vy; int  px; int  py; int  pxold; int  pyold; } ball[100]; struct  fire_state { double  x; double  y; double  vx; double  vy; int  count; } fire[100];c Moving Balls and Explosion Struct Lists
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; } 256 x 256 pixel image of explosion col = c % 4 row = c / 4 sprite images are 64 x 64 pixels Extracting Frames from 2D Sprite 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.
for ( int  k=0;k<bcount-1;k++) for ( int  m=k+1;m<bcount;m++) collide(k,m); for ( int  q=0;q<fcount;q++) { if (fire[q].count==0) play_sample(explode[rand()%4],rand()%56+200,rand()%256, 800+rand()%400,FALSE); draw_explosion((int)fire[q].x,(int)fire[q].y,fire[q].count); fire[q].x += fire[q].vx; fire[q].y += fire[q].vy; } remove_fireballs(); Managing Multiple Animated 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[ ]. draw_explosion( )  increments frame count of the explosion sprites
for ( int  i = 0; i<bcount;i++) { ball[i].pxold = ball[i].px; ball[i].pyold = ball[i].py; ball[i].x = ball[i].x + ball[i].vx + rand()%4-2; ball[i].y = ball[i].y + ball[i].vy + rand()%4-2; ball[i].px = (int)ball[i].x; ball[i].py = (int)ball[i].y; if (ball[i].px<=radius || ball[i].px>=max_x-radius) { ball[i].vx = -ball[i].vx; if (ball[i].x>=radius) ball[i].x=(double)(max_x-radius); else ball[i].x=(double)radius; } if (ball[i].py<=radius || ball[i].py>=max_y-radius) { ball[i].vy = -ball[i].vy; if (ball[i].y>=radius) ball[i].y=(double)(max_y-radius); else ball[i].y=radius; } circlefill(buffer,ball[i].pxold,ball[i].pyold,radius,ORANGE); circlefill(buffer,ball[i].px,ball[i].py,radius,BLUE); } Managing An Array of Moving Objects
int  hit( int  k,  int  m,  int  range) { int  xsep; int  ysep; xsep = (int) (ball[k].x - ball[m].x); ysep = (int) (ball[k].y - ball[m].y); if (xsep<range && xsep>-range && ysep<range && ysep>-range) return  1; else return  0; } void  collide( int  k,  int  m) { if (hit(k,m,close_enough)) { fcount+=1; fire[fcount-1].x = (ball[k].x + ball[m].x)/2.0; fire[fcount-1].y = (ball[k].y + ball[m].y)/2.0; fire[fcount-1].vx = (ball[k].vx + ball[m].vx)/2.0; fire[fcount-1].vy = (ball[k].vy + ball[m].vy)/2.0; fire[fcount-1].count = 0; } } Detecting Collisions and Managing the Collision List
void  remove_fireballs(void) { int  inc = 0; int  dec = 0; bool  done = (fcount<=0); while (!done) {  if (fire[inc].count>15 && dec<fcount) dec += 1; if (dec<fcount) { fire[inc] = fire[dec]; if (fire[inc].count<=15) { inc += 1; dec += 1; } } done = (dec>=fcount); } fcount = inc; } Removing Completed Fireballs from the Fire[ ] List fire[ . ] list is scanned and all members with count>15 are dropped. fcount is reduced by the number of members eliminated. 12 2 2 16 4 16 16 7 8 inc dec 12 2 4 7 8 inc dec 16 16 7 8 fire[]
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],Side Scrolling Games
Scrolling 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.
Scanning a Panoramic Image A Step Toward Horizontal Scrolling while (!key[KEY_ESC]) { if (key[KEY_LEFT]) { blitx -= 3; if (blitx<0) blitx = 0; } if (key[KEY_RIGHT]) { blitx += 3; if (blitx+SCREEN_W>bkgwidth) blitx = bkgwidth - SCREEN_W; } blit(bkgimage,buffer,blitx,blity,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. display screen
// Horizontal Scrolling Demo 1 #include <allegro.h> int  max_x  = 640;  int  max_y = 480;  int  blitx = 0;   int  bkgwidth = 7249;  int  bkgheight = 529;  int  blity = 0; char  *filename =  &quot;talafar.bmp&quot; ;  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,NULL); buffer = create_bitmap(SCREEN_W, SCREEN_H); while (!key[KEY_ESC]) { if (key[KEY_LEFT]) { blitx -= 3; if (blitx<0) blitx = 0; } if (key[KEY_RIGHT]) { blitx += 3; if (blitx+SCREEN_W>bkgwidth) blitx = bkgwidth - SCREEN_W; } blit(bkgimage,buffer,blitx,blity,0,0,SCREEN_W,SCREEN_H); blit(buffer,screen,0,0,0,0,SCREEN_W,SCREEN_H); rest(1); } } END_OF_MAIN()
The 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; x y chx - x position chy - y position chvx - x velocity chvy - y velocity chax - x acceleration chay - y acceleration
Motion 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/s 2 ).  There is no force in the x direction on a moving object (without friction). x y x, y  - object location v x , v y  - object velocity a y  - object acceleration due to gravity = -9.8 meters/second/second.
chx = 30.0; chy = ( double )chymax; chvx = 0.0;  chvy = 0.0; chay = 9.8;  chax = 0.0; chvy = chvy + chay*dt; chvx = chvx + chax*dt; chy = chy + chvy*dt + 0.5*chay*dt*dt; chx = chx + chvx*dt + 0.5*chax*dt*dt; if(key[KEY_LEFT]) { chax -= 1.0; if(chax<-5.0) chax = -5.0; } if(key[KEY_RIGHT]) { chax += 1.0; if(chax>5.0) chax=5.0; } main loop Motion Controlled by Acceleration
blitx = ( int )chx - SCREEN_W/2; blity = ( int )chy - SCREEN_H/2; if (blitx<0) blitx = 0; if (blitx+SCREEN_W>bkgwidth) blitx = bkgwidth - SCREEN_W; if (blity<0) blity = 0; if (blity+SCREEN_H>bkgheight) blity = bkgheight - SCREEN_H; circlefill(bkgimage,( int )chx,(int)chy,8,makecol(255,0,0)); blit(bkgimage,buffer,blitx,blity,0,0,SCREEN_W,SCREEN_H); blit(buffer,screen,0,0,0,0,SCREEN_W,SCREEN_H); Positioning 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.
Drawing a Bitmap - Sample Output
#include <allegro.h> int  main( void ) { char  *filename =  &quot;game_bkg.bmp&quot; ; 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(  &quot;Error loading %s&quot;  , 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 ,  &quot;%dx%d&quot;  ,SCREEN_W,SCREEN_H); //wait for keypress while  (!keypressed()); allegro_exit(); return   0 ; } END_OF_MAIN() Loading a Bitmap
Sample Run
Embedding Fixed Objects  vpix hpix map array nrows ncols game bkg image 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... sp width  = hpix/ncols sp height  = vpix/nrows
Sprite Width  =  = 29 pixels Sprite Height =  = 20 pixels Map Array Details 560 28 0 - no sprite 1 - background sprite 2 - block (immovable) 3 - movable 4 - breakable 5 - other objects (such as ramps and pits). 0 0 0 0 0 0 0 0 0 29 x 20 pixels 250 28 1 2 7250 250
#include <fstream.h> struct  cell{ int  sprnum; int  block;  int  breakable;  int  row; int  col; }map[28][250]; void  load_map( void ) { ifstream inFile; inFile.open( &quot;map.dat&quot; ); for ( int  r=0;r<nrows;r++) for ( int  c=0;c<ncols;c++) inFile >> map[r][c].sprnum; inFile.close(); } Loading Map Array
Displaying the Map Array Cells in the Game World View load_map(); for ( int  r = 0;r<nrows;r++) { for ( int  c = 0;c<ncols; c++) { cnum = map[r][c].sprnum; if (cnum == 0) col = BLUE; if (cnum == 1) col = GREEN; if (cnum == 2) col = RED; if (cnum == 3) col = YELLOW; rectfill(bkgimage, c*pwidth+2, r*pheight+2,  (c+1)*pwidth-3, (r+1)*pheight-3,col); } } leaves some space around each cell pwidth = width of cell in pixels pheight = height of cell in pixels
struct  block{ int  xmin; int  xmax; int  ymin; int  ymax; }blocks[100]; for ( int  r = 0;r<nrows;r++) for ( int  c = 0;c<ncols;c++) if (map[r][c].sprnum==2) { blocks[numblocks].xmin = pwidth*c; blocks[numblocks].xmax = pwidth*(c+1); blocks[numblocks].ymin = pheight*r; blocks[numblocks].ymax = pheight*(r+1); numblocks += 1; } Building a List of Blocking Cells defines the limits each blocking cell
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 &quot;special features&quot; of the game. :-) Managing Collisions
hit = false; for ( int  i=0;i<numblocks;i++) { if (inside(chx,chy,sep,blocks[i]) && !hit) { hit = true; dtime = 0; diffxleft = abs(((int)chx+sep) - blocks[i].xmin); diffxright = abs(((int)chx-sep)-blocks[i].xmax); diffytop = abs(((int)chy+sep) - blocks[i].ymin); diffybottom = abs(((int)chy-sep) - blocks[i].ymax); diffx = min(diffxleft,diffxright); diffy = min(diffytop,diffybottom); if (diffx<diffy) { chvx = - chvx; if (diffxleft<diffxright) chx = blocks[i].xmin - sep; else chx = blocks[i].xmax + sep; } else { chvy = - chvy; if (diffytop<diffybottom) chy = blocks[i].ymin - sep; else chy = blocks[i].ymax + sep; } } } Code for Managing Collisions with Blocks
hstart = ((int)chx-pwidth)/pwidth; hfinish = ((int)chx+pwidth)/pwidth; vstart = ((int)chy-pheight)/pheight; vfinish = ((int)chy+pheight)/pheight; if (hstart<0) hstart = 0; if (hfinish>ncols) hfinish = ncols; if (vstart<0) vstart = 0; if (vfinish>nrows) vfinish = nrows; for ( int  r=vstart;r<=vfinish;r++) for ( int  c=hstart;c<=hfinish;c++) { cnum = map[r][c].sprnum; if (cnum == 0) col = BLUE; if (cnum == 1) col = GREEN; if (cnum == 2) col = RED; if (cnum == 3) col = YELLOW; rectfill(bkgimage, c*pwidth+2, r*pheight+2,  (c+1)*pwidth-3, (r+1)*pheight-3,col); } Redrawing Background Cells
Sample Displays
 
 
 
x 0  = 0  x 1  = 2x  x 2  = 4x  x 3  = 2x y 0  = 0  y 1  = -x  y 2  = 0  y 3  = x Laying Down the Base t col  = (N col  - c)/N col x start  = t col *x 0  + (1-t col )*x 1 y start  = t col *y 0  + (1-t col )*y 1 x finish  = t col *x 3  + (1-t col )*x 2 y finish  = t col *y 3  + (1-t col )*y 2 t row  = (N row  - r)/N row x = t row *x start  + (1-t row )*x finish y = t row *y start  + (1-t row )*y finish (x 2 y 2 ) (x 1 y 1 ) (x 3 y 3 ) (x 0 y 0 ) N row bitmap N col 2x x
3D Modeling by Orthographic Projection
Classic Isometric (3/4) View
x/2 pixels Alternative Methods for Surface Transformation px,py bx,by x pixels Nrow Ncol M =
Diablo II
Diablo II - Zoom
Diablo II - Level Editor Detail
Lessons Learned ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]

Contenu connexe

Tendances

Y1 gd engine_terminology
Y1 gd engine_terminologyY1 gd engine_terminology
Y1 gd engine_terminologyClintParis
 
Y1 gd engine_terminology -MPH (Michael P. Hughes)
Y1 gd engine_terminology -MPH (Michael P. Hughes)Y1 gd engine_terminology -MPH (Michael P. Hughes)
Y1 gd engine_terminology -MPH (Michael P. Hughes)Mike Hughes
 
Y1 gd engine_terminology
Y1 gd engine_terminologyY1 gd engine_terminology
Y1 gd engine_terminologyClintParis
 
Y1 js engine_terminology
Y1 js engine_terminologyY1 js engine_terminology
Y1 js engine_terminologyJamieShepherd
 
Lewis brady engine terminology (edited version)
Lewis brady engine terminology (edited version)Lewis brady engine terminology (edited version)
Lewis brady engine terminology (edited version)LewisB2013
 
Callum deighton engine terminology
Callum deighton engine terminologyCallum deighton engine terminology
Callum deighton engine terminologyDeightonater
 
Y1 gd engine_terminology (1)
Y1 gd engine_terminology (1) Y1 gd engine_terminology (1)
Y1 gd engine_terminology (1) TomCrook
 
Y1 gd engine_terminology (1) (4)
Y1 gd engine_terminology (1) (4) Y1 gd engine_terminology (1) (4)
Y1 gd engine_terminology (1) (4) TomCrook
 
daryl bates engine terminology
daryl bates engine terminology daryl bates engine terminology
daryl bates engine terminology DarylBatesGames
 
Y1 gd engine_terminology
Y1 gd engine_terminologyY1 gd engine_terminology
Y1 gd engine_terminologyNeilRogero
 
Game Engine terminology
Game Engine terminologyGame Engine terminology
Game Engine terminologySamDuxburyGDS
 
Game Engine Terminology Glossary
Game Engine Terminology GlossaryGame Engine Terminology Glossary
Game Engine Terminology GlossaryJoshuaRidett
 
Y1 gd engine_terminology
Y1 gd engine_terminologyY1 gd engine_terminology
Y1 gd engine_terminologyBen_Atherton
 
Anthony Bowes task 1 IG unit 70
Anthony Bowes task 1 IG unit 70Anthony Bowes task 1 IG unit 70
Anthony Bowes task 1 IG unit 70bowes96123
 
The Purposes and Functions of components of Game Engines
The Purposes and Functions of components of Game EnginesThe Purposes and Functions of components of Game Engines
The Purposes and Functions of components of Game Engineswdhanuka
 
Researched Definition
Researched DefinitionResearched Definition
Researched DefinitionArron96
 
Harry Johnson y1 gd engine_terminology
Harry Johnson y1 gd engine_terminologyHarry Johnson y1 gd engine_terminology
Harry Johnson y1 gd engine_terminology11275449
 

Tendances (17)

Y1 gd engine_terminology
Y1 gd engine_terminologyY1 gd engine_terminology
Y1 gd engine_terminology
 
Y1 gd engine_terminology -MPH (Michael P. Hughes)
Y1 gd engine_terminology -MPH (Michael P. Hughes)Y1 gd engine_terminology -MPH (Michael P. Hughes)
Y1 gd engine_terminology -MPH (Michael P. Hughes)
 
Y1 gd engine_terminology
Y1 gd engine_terminologyY1 gd engine_terminology
Y1 gd engine_terminology
 
Y1 js engine_terminology
Y1 js engine_terminologyY1 js engine_terminology
Y1 js engine_terminology
 
Lewis brady engine terminology (edited version)
Lewis brady engine terminology (edited version)Lewis brady engine terminology (edited version)
Lewis brady engine terminology (edited version)
 
Callum deighton engine terminology
Callum deighton engine terminologyCallum deighton engine terminology
Callum deighton engine terminology
 
Y1 gd engine_terminology (1)
Y1 gd engine_terminology (1) Y1 gd engine_terminology (1)
Y1 gd engine_terminology (1)
 
Y1 gd engine_terminology (1) (4)
Y1 gd engine_terminology (1) (4) Y1 gd engine_terminology (1) (4)
Y1 gd engine_terminology (1) (4)
 
daryl bates engine terminology
daryl bates engine terminology daryl bates engine terminology
daryl bates engine terminology
 
Y1 gd engine_terminology
Y1 gd engine_terminologyY1 gd engine_terminology
Y1 gd engine_terminology
 
Game Engine terminology
Game Engine terminologyGame Engine terminology
Game Engine terminology
 
Game Engine Terminology Glossary
Game Engine Terminology GlossaryGame Engine Terminology Glossary
Game Engine Terminology Glossary
 
Y1 gd engine_terminology
Y1 gd engine_terminologyY1 gd engine_terminology
Y1 gd engine_terminology
 
Anthony Bowes task 1 IG unit 70
Anthony Bowes task 1 IG unit 70Anthony Bowes task 1 IG unit 70
Anthony Bowes task 1 IG unit 70
 
The Purposes and Functions of components of Game Engines
The Purposes and Functions of components of Game EnginesThe Purposes and Functions of components of Game Engines
The Purposes and Functions of components of Game Engines
 
Researched Definition
Researched DefinitionResearched Definition
Researched Definition
 
Harry Johnson y1 gd engine_terminology
Harry Johnson y1 gd engine_terminologyHarry Johnson y1 gd engine_terminology
Harry Johnson y1 gd engine_terminology
 

Similaire à Game programming workshop

Introduction to html5 game programming with impact js
Introduction to html5 game programming with impact jsIntroduction to html5 game programming with impact js
Introduction to html5 game programming with impact jsLuca Galli
 
How to work with code blocks
How to work with code blocksHow to work with code blocks
How to work with code blocksTech Bikram
 
His162013 140529214456-phpapp01
His162013 140529214456-phpapp01His162013 140529214456-phpapp01
His162013 140529214456-phpapp01Getachew Ganfur
 
C language industrial training report
C language industrial training reportC language industrial training report
C language industrial training reportRaushan Pandey
 
C plus plus for hackers it security
C plus plus for hackers it securityC plus plus for hackers it security
C plus plus for hackers it securityCESAR A. RUIZ C
 
How to develop a Flutter app.pdf
How to develop a Flutter app.pdfHow to develop a Flutter app.pdf
How to develop a Flutter app.pdfSmith Daniel
 
codeblocks-instructions.pdf
codeblocks-instructions.pdfcodeblocks-instructions.pdf
codeblocks-instructions.pdfRavinderKSingla
 
Game Programming I - Introduction
Game Programming I - IntroductionGame Programming I - Introduction
Game Programming I - IntroductionFrancis Seriña
 
CIS 170 Effective Communication - tutorialrank.com
CIS 170 Effective Communication - tutorialrank.comCIS 170 Effective Communication - tutorialrank.com
CIS 170 Effective Communication - tutorialrank.comBartholomew19
 
Easy coding a multi device game with FireMonkey
Easy coding a multi device game with FireMonkeyEasy coding a multi device game with FireMonkey
Easy coding a multi device game with FireMonkeypprem
 
Devry cis-170-c-i lab-1-of-7-getting-started
Devry cis-170-c-i lab-1-of-7-getting-startedDevry cis-170-c-i lab-1-of-7-getting-started
Devry cis-170-c-i lab-1-of-7-getting-startednoahjamessss
 
Devry cis-170-c-i lab-1-of-7-getting-started
Devry cis-170-c-i lab-1-of-7-getting-startedDevry cis-170-c-i lab-1-of-7-getting-started
Devry cis-170-c-i lab-1-of-7-getting-startedgovendaagoovenda
 
Engine terminology
Engine terminologyEngine terminology
Engine terminologythomasmcd6
 
CIS 170 Inspiring Innovation/tutorialrank.com
 CIS 170 Inspiring Innovation/tutorialrank.com CIS 170 Inspiring Innovation/tutorialrank.com
CIS 170 Inspiring Innovation/tutorialrank.comjonhson110
 

Similaire à Game programming workshop (20)

Cpb2010
Cpb2010Cpb2010
Cpb2010
 
Introduction to html5 game programming with impact js
Introduction to html5 game programming with impact jsIntroduction to html5 game programming with impact js
Introduction to html5 game programming with impact js
 
Session 1 - c++ intro
Session   1 - c++ introSession   1 - c++ intro
Session 1 - c++ intro
 
How to work with code blocks
How to work with code blocksHow to work with code blocks
How to work with code blocks
 
C++ for hackers
C++ for hackersC++ for hackers
C++ for hackers
 
His162013 140529214456-phpapp01
His162013 140529214456-phpapp01His162013 140529214456-phpapp01
His162013 140529214456-phpapp01
 
C language industrial training report
C language industrial training reportC language industrial training report
C language industrial training report
 
C plus plus for hackers it security
C plus plus for hackers it securityC plus plus for hackers it security
C plus plus for hackers it security
 
How to develop a Flutter app.pdf
How to develop a Flutter app.pdfHow to develop a Flutter app.pdf
How to develop a Flutter app.pdf
 
codeblocks-instructions.pdf
codeblocks-instructions.pdfcodeblocks-instructions.pdf
codeblocks-instructions.pdf
 
Game Programming I - Introduction
Game Programming I - IntroductionGame Programming I - Introduction
Game Programming I - Introduction
 
CIS 170 Effective Communication - tutorialrank.com
CIS 170 Effective Communication - tutorialrank.comCIS 170 Effective Communication - tutorialrank.com
CIS 170 Effective Communication - tutorialrank.com
 
Easy coding a multi device game with FireMonkey
Easy coding a multi device game with FireMonkeyEasy coding a multi device game with FireMonkey
Easy coding a multi device game with FireMonkey
 
Devry cis-170-c-i lab-1-of-7-getting-started
Devry cis-170-c-i lab-1-of-7-getting-startedDevry cis-170-c-i lab-1-of-7-getting-started
Devry cis-170-c-i lab-1-of-7-getting-started
 
Devry cis-170-c-i lab-1-of-7-getting-started
Devry cis-170-c-i lab-1-of-7-getting-startedDevry cis-170-c-i lab-1-of-7-getting-started
Devry cis-170-c-i lab-1-of-7-getting-started
 
Pong
PongPong
Pong
 
Engine terminology
Engine terminologyEngine terminology
Engine terminology
 
The basics of c programming
The basics of c programmingThe basics of c programming
The basics of c programming
 
HTML5 Game Development frameworks overview
HTML5 Game Development frameworks overviewHTML5 Game Development frameworks overview
HTML5 Game Development frameworks overview
 
CIS 170 Inspiring Innovation/tutorialrank.com
 CIS 170 Inspiring Innovation/tutorialrank.com CIS 170 Inspiring Innovation/tutorialrank.com
CIS 170 Inspiring Innovation/tutorialrank.com
 

Dernier

Independent Joka Escorts ✔ 8250192130 ✔ Full Night With Room Online Booking 2...
Independent Joka Escorts ✔ 8250192130 ✔ Full Night With Room Online Booking 2...Independent Joka Escorts ✔ 8250192130 ✔ Full Night With Room Online Booking 2...
Independent Joka Escorts ✔ 8250192130 ✔ Full Night With Room Online Booking 2...noor ahmed
 
5* Hotels Call Girls In Goa {{07028418221}} Call Girls In North Goa Escort Se...
5* Hotels Call Girls In Goa {{07028418221}} Call Girls In North Goa Escort Se...5* Hotels Call Girls In Goa {{07028418221}} Call Girls In North Goa Escort Se...
5* Hotels Call Girls In Goa {{07028418221}} Call Girls In North Goa Escort Se...Apsara Of India
 
Nayabad Call Girls ✔ 8005736733 ✔ Hot Model With Sexy Bhabi Ready For Sex At ...
Nayabad Call Girls ✔ 8005736733 ✔ Hot Model With Sexy Bhabi Ready For Sex At ...Nayabad Call Girls ✔ 8005736733 ✔ Hot Model With Sexy Bhabi Ready For Sex At ...
Nayabad Call Girls ✔ 8005736733 ✔ Hot Model With Sexy Bhabi Ready For Sex At ...aamir
 
👙 Kolkata Call Girls Shyam Bazar 💫💫7001035870 Model escorts Service
👙  Kolkata Call Girls Shyam Bazar 💫💫7001035870 Model escorts Service👙  Kolkata Call Girls Shyam Bazar 💫💫7001035870 Model escorts Service
👙 Kolkata Call Girls Shyam Bazar 💫💫7001035870 Model escorts Serviceanamikaraghav4
 
Call Girls Manjri Call Me 7737669865 Budget Friendly No Advance Booking
Call Girls Manjri Call Me 7737669865 Budget Friendly No Advance BookingCall Girls Manjri Call Me 7737669865 Budget Friendly No Advance Booking
Call Girls Manjri Call Me 7737669865 Budget Friendly No Advance Bookingroncy bisnoi
 
↑Top Model (Kolkata) Call Girls Salt Lake ⟟ 8250192130 ⟟ High Class Call Girl...
↑Top Model (Kolkata) Call Girls Salt Lake ⟟ 8250192130 ⟟ High Class Call Girl...↑Top Model (Kolkata) Call Girls Salt Lake ⟟ 8250192130 ⟟ High Class Call Girl...
↑Top Model (Kolkata) Call Girls Salt Lake ⟟ 8250192130 ⟟ High Class Call Girl...noor ahmed
 
👙 Kolkata Call Girls Sonagachi 💫💫7001035870 Model escorts Service
👙  Kolkata Call Girls Sonagachi 💫💫7001035870 Model escorts Service👙  Kolkata Call Girls Sonagachi 💫💫7001035870 Model escorts Service
👙 Kolkata Call Girls Sonagachi 💫💫7001035870 Model escorts Serviceanamikaraghav4
 
👙 Kolkata Call Girls Park Circus 💫💫7001035870 Model escorts Service
👙  Kolkata Call Girls Park Circus 💫💫7001035870 Model escorts Service👙  Kolkata Call Girls Park Circus 💫💫7001035870 Model escorts Service
👙 Kolkata Call Girls Park Circus 💫💫7001035870 Model escorts Serviceanamikaraghav4
 
Call Girls Agency In Goa 💚 9316020077 💚 Call Girl Goa By Russian Call Girl ...
Call Girls  Agency In Goa  💚 9316020077 💚 Call Girl Goa By Russian Call Girl ...Call Girls  Agency In Goa  💚 9316020077 💚 Call Girl Goa By Russian Call Girl ...
Call Girls Agency In Goa 💚 9316020077 💚 Call Girl Goa By Russian Call Girl ...russian goa call girl and escorts service
 
↑Top Model (Kolkata) Call Girls Rajpur ⟟ 8250192130 ⟟ High Class Call Girl In...
↑Top Model (Kolkata) Call Girls Rajpur ⟟ 8250192130 ⟟ High Class Call Girl In...↑Top Model (Kolkata) Call Girls Rajpur ⟟ 8250192130 ⟟ High Class Call Girl In...
↑Top Model (Kolkata) Call Girls Rajpur ⟟ 8250192130 ⟟ High Class Call Girl In...noor ahmed
 
Low Rate Young Call Girls in Surajpur Greater Noida ✔️☆9289244007✔️☆ Female E...
Low Rate Young Call Girls in Surajpur Greater Noida ✔️☆9289244007✔️☆ Female E...Low Rate Young Call Girls in Surajpur Greater Noida ✔️☆9289244007✔️☆ Female E...
Low Rate Young Call Girls in Surajpur Greater Noida ✔️☆9289244007✔️☆ Female E...SofiyaSharma5
 
College Call Girls New Alipore - For 7001035870 Cheap & Best with original Ph...
College Call Girls New Alipore - For 7001035870 Cheap & Best with original Ph...College Call Girls New Alipore - For 7001035870 Cheap & Best with original Ph...
College Call Girls New Alipore - For 7001035870 Cheap & Best with original Ph...anamikaraghav4
 
Verified Trusted Call Girls Tambaram Chennai ✔✔7427069034 Independent Chenna...
Verified Trusted Call Girls Tambaram Chennai ✔✔7427069034  Independent Chenna...Verified Trusted Call Girls Tambaram Chennai ✔✔7427069034  Independent Chenna...
Verified Trusted Call Girls Tambaram Chennai ✔✔7427069034 Independent Chenna... Shivani Pandey
 
Book Sex Workers Available Kolkata Call Girls Service Airport Kolkata ✔ 62971...
Book Sex Workers Available Kolkata Call Girls Service Airport Kolkata ✔ 62971...Book Sex Workers Available Kolkata Call Girls Service Airport Kolkata ✔ 62971...
Book Sex Workers Available Kolkata Call Girls Service Airport Kolkata ✔ 62971...ritikasharma
 
Science City Kolkata ( Call Girls ) Kolkata ✔ 6297143586 ✔ Hot Model With Sex...
Science City Kolkata ( Call Girls ) Kolkata ✔ 6297143586 ✔ Hot Model With Sex...Science City Kolkata ( Call Girls ) Kolkata ✔ 6297143586 ✔ Hot Model With Sex...
Science City Kolkata ( Call Girls ) Kolkata ✔ 6297143586 ✔ Hot Model With Sex...rahim quresi
 

Dernier (20)

Independent Joka Escorts ✔ 8250192130 ✔ Full Night With Room Online Booking 2...
Independent Joka Escorts ✔ 8250192130 ✔ Full Night With Room Online Booking 2...Independent Joka Escorts ✔ 8250192130 ✔ Full Night With Room Online Booking 2...
Independent Joka Escorts ✔ 8250192130 ✔ Full Night With Room Online Booking 2...
 
Desi Bhabhi Call Girls In Goa 💃 730 02 72 001💃desi Bhabhi Escort Goa
Desi Bhabhi Call Girls  In Goa  💃 730 02 72 001💃desi Bhabhi Escort GoaDesi Bhabhi Call Girls  In Goa  💃 730 02 72 001💃desi Bhabhi Escort Goa
Desi Bhabhi Call Girls In Goa 💃 730 02 72 001💃desi Bhabhi Escort Goa
 
5* Hotels Call Girls In Goa {{07028418221}} Call Girls In North Goa Escort Se...
5* Hotels Call Girls In Goa {{07028418221}} Call Girls In North Goa Escort Se...5* Hotels Call Girls In Goa {{07028418221}} Call Girls In North Goa Escort Se...
5* Hotels Call Girls In Goa {{07028418221}} Call Girls In North Goa Escort Se...
 
Call Girls Chirag Delhi Delhi WhatsApp Number 9711199171
Call Girls Chirag Delhi Delhi WhatsApp Number 9711199171Call Girls Chirag Delhi Delhi WhatsApp Number 9711199171
Call Girls Chirag Delhi Delhi WhatsApp Number 9711199171
 
Nayabad Call Girls ✔ 8005736733 ✔ Hot Model With Sexy Bhabi Ready For Sex At ...
Nayabad Call Girls ✔ 8005736733 ✔ Hot Model With Sexy Bhabi Ready For Sex At ...Nayabad Call Girls ✔ 8005736733 ✔ Hot Model With Sexy Bhabi Ready For Sex At ...
Nayabad Call Girls ✔ 8005736733 ✔ Hot Model With Sexy Bhabi Ready For Sex At ...
 
👙 Kolkata Call Girls Shyam Bazar 💫💫7001035870 Model escorts Service
👙  Kolkata Call Girls Shyam Bazar 💫💫7001035870 Model escorts Service👙  Kolkata Call Girls Shyam Bazar 💫💫7001035870 Model escorts Service
👙 Kolkata Call Girls Shyam Bazar 💫💫7001035870 Model escorts Service
 
Goa Call "Girls Service 9316020077 Call "Girls in Goa
Goa Call "Girls  Service   9316020077 Call "Girls in GoaGoa Call "Girls  Service   9316020077 Call "Girls in Goa
Goa Call "Girls Service 9316020077 Call "Girls in Goa
 
Call Girls Manjri Call Me 7737669865 Budget Friendly No Advance Booking
Call Girls Manjri Call Me 7737669865 Budget Friendly No Advance BookingCall Girls Manjri Call Me 7737669865 Budget Friendly No Advance Booking
Call Girls Manjri Call Me 7737669865 Budget Friendly No Advance Booking
 
↑Top Model (Kolkata) Call Girls Salt Lake ⟟ 8250192130 ⟟ High Class Call Girl...
↑Top Model (Kolkata) Call Girls Salt Lake ⟟ 8250192130 ⟟ High Class Call Girl...↑Top Model (Kolkata) Call Girls Salt Lake ⟟ 8250192130 ⟟ High Class Call Girl...
↑Top Model (Kolkata) Call Girls Salt Lake ⟟ 8250192130 ⟟ High Class Call Girl...
 
👙 Kolkata Call Girls Sonagachi 💫💫7001035870 Model escorts Service
👙  Kolkata Call Girls Sonagachi 💫💫7001035870 Model escorts Service👙  Kolkata Call Girls Sonagachi 💫💫7001035870 Model escorts Service
👙 Kolkata Call Girls Sonagachi 💫💫7001035870 Model escorts Service
 
👙 Kolkata Call Girls Park Circus 💫💫7001035870 Model escorts Service
👙  Kolkata Call Girls Park Circus 💫💫7001035870 Model escorts Service👙  Kolkata Call Girls Park Circus 💫💫7001035870 Model escorts Service
👙 Kolkata Call Girls Park Circus 💫💫7001035870 Model escorts Service
 
Call Girls Agency In Goa 💚 9316020077 💚 Call Girl Goa By Russian Call Girl ...
Call Girls  Agency In Goa  💚 9316020077 💚 Call Girl Goa By Russian Call Girl ...Call Girls  Agency In Goa  💚 9316020077 💚 Call Girl Goa By Russian Call Girl ...
Call Girls Agency In Goa 💚 9316020077 💚 Call Girl Goa By Russian Call Girl ...
 
↑Top Model (Kolkata) Call Girls Rajpur ⟟ 8250192130 ⟟ High Class Call Girl In...
↑Top Model (Kolkata) Call Girls Rajpur ⟟ 8250192130 ⟟ High Class Call Girl In...↑Top Model (Kolkata) Call Girls Rajpur ⟟ 8250192130 ⟟ High Class Call Girl In...
↑Top Model (Kolkata) Call Girls Rajpur ⟟ 8250192130 ⟟ High Class Call Girl In...
 
Call Girls South Avenue Delhi WhatsApp Number 9711199171
Call Girls South Avenue Delhi WhatsApp Number 9711199171Call Girls South Avenue Delhi WhatsApp Number 9711199171
Call Girls South Avenue Delhi WhatsApp Number 9711199171
 
Low Rate Young Call Girls in Surajpur Greater Noida ✔️☆9289244007✔️☆ Female E...
Low Rate Young Call Girls in Surajpur Greater Noida ✔️☆9289244007✔️☆ Female E...Low Rate Young Call Girls in Surajpur Greater Noida ✔️☆9289244007✔️☆ Female E...
Low Rate Young Call Girls in Surajpur Greater Noida ✔️☆9289244007✔️☆ Female E...
 
College Call Girls New Alipore - For 7001035870 Cheap & Best with original Ph...
College Call Girls New Alipore - For 7001035870 Cheap & Best with original Ph...College Call Girls New Alipore - For 7001035870 Cheap & Best with original Ph...
College Call Girls New Alipore - For 7001035870 Cheap & Best with original Ph...
 
Verified Trusted Call Girls Tambaram Chennai ✔✔7427069034 Independent Chenna...
Verified Trusted Call Girls Tambaram Chennai ✔✔7427069034  Independent Chenna...Verified Trusted Call Girls Tambaram Chennai ✔✔7427069034  Independent Chenna...
Verified Trusted Call Girls Tambaram Chennai ✔✔7427069034 Independent Chenna...
 
Goa Call Girls 9316020077 Call Girls In Goa By Russian Call Girl in goa
Goa Call Girls 9316020077 Call Girls  In Goa By Russian Call Girl in goaGoa Call Girls 9316020077 Call Girls  In Goa By Russian Call Girl in goa
Goa Call Girls 9316020077 Call Girls In Goa By Russian Call Girl in goa
 
Book Sex Workers Available Kolkata Call Girls Service Airport Kolkata ✔ 62971...
Book Sex Workers Available Kolkata Call Girls Service Airport Kolkata ✔ 62971...Book Sex Workers Available Kolkata Call Girls Service Airport Kolkata ✔ 62971...
Book Sex Workers Available Kolkata Call Girls Service Airport Kolkata ✔ 62971...
 
Science City Kolkata ( Call Girls ) Kolkata ✔ 6297143586 ✔ Hot Model With Sex...
Science City Kolkata ( Call Girls ) Kolkata ✔ 6297143586 ✔ Hot Model With Sex...Science City Kolkata ( Call Girls ) Kolkata ✔ 6297143586 ✔ Hot Model With Sex...
Science City Kolkata ( Call Girls ) Kolkata ✔ 6297143586 ✔ Hot Model With Sex...
 

Game programming workshop

  • 1. Beginning Game Programming Murray State University Computer Science and Information Systems Dr. Bob - bob.pilgrim@murraystate.edu
  • 2. This 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.
  • 3. Game 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. &quot;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.&quot; - Matthew Jeffrey (Head of Global Talent Brand at EA) &quot;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.&quot; - Ben Kuchera (Opposable Thumbs journal)
  • 4. &quot;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! &quot; - Quasius &quot;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.&quot; - 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.&quot; - Matt Gilgenbach, a video game developer Comments from Game Developers
  • 5. Why 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/Physics Graphics and Animation Sound Generation Graphical Design and Layout Human/Computer Interfaces Scientific Visualization : :
  • 6. Types of Games Classic Arcade 1st Person Shooter RPG Sports/Racing Board Games Adventure/Puzzle Solving Flight Simulators World Simulations Strategy/Wargames Fighting Games
  • 7. Can One Person Still Write a Great Game ? 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. YES!
  • 8. Great Games come from Great Ideas Each of the types of games started out as one game and one person's idea.
  • 9. Establishing 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.
  • 10. The Game Loop Update Game State Get User Input Sound Graphics Setup Game done? Stop Game no yes wait time through loop must be short and the same for each pass the amount of wait depends on what else has been done in this pass
  • 11.
  • 12.
  • 13.
  • 14. Wow! 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.
  • 15. Wow! 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.
  • 16. #include <allegro.h> int main( void ) { allegro_init(); allegro_exit(); return 0; } END_OF_MAIN() First_Project // includes allegro library in project // starts and ends allegro // graphics commands go between these lines Enter this text in the editor, save, compile and run it. Since there are no graphics commands, nothing will appear but you should get an error-free compile.
  • 17. What 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
  • 18. #include <allegro.h> int main( void ) { allegro_init(); set_gfx_mode(GFX_SAFE, 640, 480, 0, 0); install_keyboard(); while (!key[KEY_ESC]); allegro_exit(); return 0; } END_OF_MAIN() First_Project 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(!key[KEY_ESC]) tells the program to wait on this line until the ESC key has been pressed
  • 19. #include <allegro.h> int main( void ) { allegro_init(); set_gfx_mode(GFX_SAFE, 640, 480, 0, 0); install_keyboard(); while (!key[KEY_ESC]); allegro_exit(); return 0; } END_OF_MAIN() First_Project 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.
  • 20. Drawing in the Graphics Window #include <allegro.h> #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 (!key[KEY_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 x=50, y=60 and the opposite corner at x=150 and y=160 (100x100 pixel box)
  • 21. A Closer Look 640 480 0,0 each point in this window is defined by a pair of numbers (x,y) 640,0 50,60 150,160 increasing y increasing x rect(screen,50,60,150,160,BLUE)
  • 22. RGB Color Values Each value is a number between 0 and 255. Mixing Light is additive so 255,255,255 makes white 255,0,0 255,0,255 255,255,0 0,255,0 0,0,255 0,255,255 0,0,0 = BLACK makecol( r val ,g val ,b val ) can be used to create over 16 million colors
  • 23. Try These Drawing Commands int my_color; my_color = makecol(255,255,0); putpixel(screen,320,240,my_color); line(screen,10,100,630,100,my_color); rectfill(screen,200,300,250,370,makecol(100,0,200)); circle(screen,230,110,30,makecol(50,200,10)); circlefill(screen,500,400,10,makecol(0,0,100)); ellipsefill(screen,185,210,100,30,makecol(50,50,50)); ellipsefill(screen, 180,200,100,30,makecol(255,0,0)); ellipse(screen, 175,195,100,30,makecol(255,180,180));
  • 24. Example Shapes putpixel(screen,320,240,my_color); line(screen,10,100,630,100,my_color); rectfill(screen,200,300,250,370,makecol(100,0,200)); circle(screen,230,110,30,makecol(50,200,10)); circlefill(screen,500,400,10,makecol(0,0,100)); ellipsefill(screen,185,210,100,30,makecol(50,50,50)); ellipsefill(screen, 180,200,100,30,makecol(255,0,0)); ellipse(screen, 175,195,100,30,makecol(255,180,180));
  • 25. A First Look at ANIMATION x = max_x/2; y = max_y/2; vx = 2; vy = -3; while (!key[KEY_ESC]) { xold = x; yold = y; x = x + vx; y = y + vy; if (x<=radius || x>=max_x-radius) vx = -vx; if (y<=radius || y>=max_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)
  • 26.
  • 27. install_keyboard(); while (!key[KEY_ESC]) { pxold = px; pyold = py; x = x + vx; y = y + vy; px = ( int )x; py = ( int )y; //watch out for sticky walls if (px<=radius || px>=max_x-radius) vx = -vx; if (py<=radius || py>=max_y-radius) vy = -vy; circle(screen,pxold,pyold,radius,BLACK); circle(screen,px,py,radius,BLUE); rest(20); if (key[KEY_LEFT]) vx = vx - 0.1; if (key[KEY_RIGHT]) vx = vx + 0.1; if (key[KEY_UP]) vy = vy - 0.1; if (key[KEY_DOWN]) vy = vy + 0.1; } Making a Program Respond to User Keyboard Entry keyboard entry arrow keys change the x and y velocity of the ball
  • 28.
  • 29. play_sample(sample_filename, volume, panning, pitch, FALSE); Sound Allegro gives us an easy way to add sound to our game programs. 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
  • 30. SAMPLE *boing1; SAMPLE *boing2; if (install_sound(DIGI_AUTODETECT, MIDI_NONE, &quot;&quot;) != 0) { allegro_message(&quot;Error initializing sound system&quot;); return 1; } boing1 = load_sample(&quot;boing1.wav&quot;); boing2 = load_sample(&quot;boing2.wav&quot;); Adding 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). Copy the sound files boing1.wav and boing2.wav from the Sound Files folder into the BouncingBall_Demo_02 folder.
  • 31. if (px<=radius || px>=max_x-radius) { vx = -vx; play_sample(boing1, 128, 128, 1000, FALSE); } if (py<=radius || py>=max_y-radius) { vy = -vy; play_sample(boing2, 255, 128, 1000, FALSE); } Now 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 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...
  • 32. 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, &quot;&quot; ) != 0) { allegro_message( &quot;Error initializing sound system&quot; ); return 1; } WAV Sound Demo left-right balance, volume, & pitch control
  • 33. //display program information textout_ex(screen,font, &quot;PlayWave Program (ESC to quit)&quot; ,0,0,15,0); textprintf_ex(screen,font,0,10,15,0, &quot;Snd Driver: %s&quot; ,digi_driver->name); textout_ex(screen,font, &quot;Playing clapping.wav...&quot; ,0,20,15,0); textout_ex(screen,font, &quot;Left,Right - Pan Left,Right&quot; ,0,50,15,0); textout_ex(screen,font, &quot;Up,Down - Pitch Raise,Lower&quot; ,0,60,15,0); textout_ex(screen,font, &quot;-,+ - Volume Down,Up&quot; ,0,70,15,0); //load the wave file sample1 = load_sample( &quot;evil_laugh.wav&quot; ); sample2 = load_sample( &quot;clapping.wav&quot; ); if (!sample1 || !sample2) { allegro_message(&quot;Error reading wave file&quot;); return 1; } //play the sample with looping play_sample(sample1, volume, panning, pitch, TRUE); play_sample(sample2, volume, panning, pitch, TRUE);
  • 34. while (!key[KEY_ESC]) { //change the panning if ((key[KEY_LEFT]) && (panning > 0)) panning--; else if ((key[KEY_RIGHT]) && (panning < 255)) panning++; //change the pitch (rounding at 512) if ((key[KEY_UP]) && (pitch < 16384)) pitch = ((pitch * 513) / 512) + 1; else if ((key[KEY_DOWN]) && (pitch > 64)) pitch = ((pitch * 511) / 512) - 1; //change the volume if (key[KEY_EQUALS] && volume < 255) volume++; else if (key[KEY_MINUS] && volume > 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_sample(sample2); remove_sound();
  • 35. Pong The First Computer Game We are going to look inside PONG, the first computer game. review Pong_Demo_01 & Pong_Demo_02
  • 36. Deconstructing 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 &quot;english&quot; on ball if ball hits near the top or the bottom scoreboard keeps a record of players scores - first to 11 wins
  • 37. init allegro init init variables new game ? save old positiions end loop game loop ball at top or bottom ball hit paddle ball miss paddle quit game ? update scoreboard players input animate score & reset return ball bounce ball paddles at top or bottom stop paddle exit allegro Pong Game Block Diagram yes no
  • 38. // 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 Initialize Game State - PONG
  • 39. // check for game quit if (key[KEY_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 <= 0 | by >= SCREEN_H) bvy = -bvy; Top of Main Loop - PONG
  • 40. // manage ball hitting left paddle if ((bx <= padLeftX + padWidth/2) & (abs(padLeftY - by)<=padHeight/2)) { bx = padLeftX + padWidth/2; bvx = - bvx; bvy = 0; if (padLeftY-by<-padHeight/5) bvy = + 1; if (padLeftY-by>padHeight/5) bvy = - 1; if (padLeftY-by<-padHeight/4) bvy = + 2; if (padLeftY-by>padHeight/4) bvy = - 2; } // manage ball hitting right paddle if ((bx >= padRightX - padWidth/2) & (abs(padRightY - by)<=padHeight/2)) { bx = padRightX - padWidth/2; bvx = - bvx; bvy = 0; if (padLeftY-by<-padHeight/5) bvy = + 1; if (padLeftY-by>padHeight/5) bvy = - 1; if (padRightY-by<-padHeight/4) bvy = + 2; if (padRightY-by>padHeight/4) bvy = - 2; } Manage Ball Hitting Paddle - PONG
  • 41. if(padLeftY<padHeight/2) padLeftY = padHeight/2; if(padLeftY>SCREEN_H - padHeight/2) padLeftY = SCREEN_H - padHeight/2; if(padRightY<padHeight/2) padRightY = padHeight/2; if(padRightY>SCREEN_H - padHeight/2) padRightY = SCREEN_H - padHeight/2; Checking Game Space Limits padHeight padLeftY (0,0) ? 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.
  • 42. // manage ball missing left paddle if (bx < 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 > 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/2+25,20,BLACK); textprintf_ex(screen, font, SCREEN_W/2-20, 10, 15, -1, &quot;%d %d&quot;, Lcount, Rcount); Manage Ball Passing Paddle - PONG
  • 43. // manage user input for paddle movement if (key[KEY_A]) padLeftY -= padVy; if (key[KEY_Z]) padLeftY += padVy; if (key[KEY_K]) padRightY -= padVy; if (key[KEY_M]) padRightY += padVy; Players Move Paddles Using A,Z and K,M Keys - PONG
  • 44. // manage paddles touching boundary of game space if (padLeftY<padHeight/2) padLeftY = padHeight/2; if (padLeftY>SCREEN_H - padHeight/2) padLeftY = SCREEN_H - padHeight/2; if (padRightY<padHeight/2) padRightY = padHeight/2; if (padRightY>SCREEN_H - padHeight/2) padRightY = SCREEN_H - padHeight/2; Stop Paddles at Boundary of Game Space - PONG
  • 45. // animate ball and paddles circlefill(screen,bxold,byold,rad,BLACK); circlefill(screen,bx,by,rad,YELLOW); rectfill(screen,padLeftX-padWidth/2,padLeftYold-padHeight/2, padLeftX+padWidth/2,padLeftYold+padHeight/2,BLACK); rectfill(screen,padRightX-padWidth/2,padRightYold-padHeight/2, padRightX+padWidth/2,padRightYold+padHeight/2,BLACK); rectfill(screen,padLeftX-padWidth/2,padLeftY-padHeight/2,padLeftX+ padWidth/2,padLeftY+padHeight/2,GREEN); rectfill(screen,padRightX-padWidth/2,padRightY-padHeight/2,padRightX+ padWidth/2,padRightY+padHeight/2,RED); rest(1); Animate Game - PONG
  • 46. Adding 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 (bvx<-8) bvy += rand() % 4 - 2; if (rand() % 100 > 94) bvy += rand() % 4 - 2; You can skip the exercise and run Pong_Demo_02 to see the changes.
  • 47. KING PONG Now run King_Pong to see the value of adding sound to your game.
  • 48. (0,0) (0,SCREEN_H) (SCREEN_W,SCREEN_H) (SCREEN_W,0) maintain 4 to 3 aspect ratio Game Space Layout
  • 49. 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. Computer Input Demo Programs
  • 50. allegro_init(); install_keyboard(); Keyboard Demo run keyboard_input_demo
  • 51. Mouse Input Demo Mouse_Graphics_Demo allegro_init(); install_mouse();
  • 52. Joystick Input Demo joystick_demo & joystick_graphics_demo plug in generic gamepad (USB) first allegro_init(); install_joystick(JOY_TYPE_AUTODETECT);
  • 53. GamePad Graphics Demo gamepad_demo
  • 54. while (!keypressed()) { //graphics loop poll_joystick(); xold = x; yold = y; radius_old = radius; if (joy[0].stick[0].axis[0].pos<0) x = x - 2; if (joy[0].stick[0].axis[0].pos>0) x = x + 2; if (joy[0].stick[0].axis[1].pos<0) y = y - 2; if (joy[0].stick[0].axis[1].pos>0) y = y + 2; if (joy[0].button[6].b>0) radius = radius - 1; if (joy[0].button[7].b>0) radius = radius + 1; if (x>max_x) x = max_x; if (x<0) x = 0; if (y>max_y) y = max_y; if (y<0) y = 0; if (radius<2) radius = 2; if (radius>100) radius = 100; if (xold!=x || yold!=y || radius_old!=radius) circlefill(screen,xold,yold,radius_old,BLACK); circlefill(screen,x,y,radius,YELLOW); GamePad Graphics Control Demo Sample Source Code
  • 55. 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); Double 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.
  • 56. Draw_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.
  • 58. int main() { char *filename = &quot;southpark_town.bmp&quot; ; 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(); install_keyboard(); set_color_depth(16); set_gfx_mode(GFX_AUTODETECT_WINDOWED, max_x, max_y, 0, 0); if (install_sound(DIGI_AUTODETECT, MIDI_NONE, &quot;&quot; ) != 0) { allegro_message( &quot;Error initializing sound system&quot; ); return 1; } Draw Sprite Demo
  • 59. //load the wave file chef_hello = load_sample( &quot;chef-hello_there_children.wav&quot; ); bkg_image = load_bitmap(filename, NULL); if (!bkg_image) { set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); allegro_message( &quot;Error loading %s&quot; , 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, &quot;Resolution = %ix%i&quot; , SCREEN_W, SCREEN_H); textprintf_ex(screen, font, 0, 10, WHITE,0, &quot;Color depth = %i&quot; , bitmap_color_depth(screen)); //load the cartman bitmap cartman = load_bitmap( &quot;cartman.bmp&quot; , NULL); x = SCREEN_W/2 - cartman->w/2; y = SCREEN_H/2;
  • 60. //main loop while (!key[KEY_ESC]) { scale = (max_y/2 + 4.0*(double)(y-max_y/2))/(double)(max_y/2); stretch_sprite(screen, cartman, x, y, scale*cartman->w,scale*cartman->h); textprintf_ex(screen,font,0,20,WHITE,0, &quot;Location = %ix%i&quot;, x, y); rest(20); xold = x; yold = y; if (key[KEY_UP]) y = y - 1; if (key[KEY_DOWN]) y = y + 1; if (key[KEY_LEFT]) x = x - 2; if (key[KEY_RIGHT])x = x + 2; if (xold!=x || yold!=y) blit(bkg_image, screen, x, y, x, y, scale*cartman->w,scale*cartman->h); if (x>max_x-cartman->w-20) x = max_x-cartman->w-20; if (x<-20) x = -20; if (y>max_y-cartman->h) y = max_y-cartman->h; if (y<max_y/2) y = max_y/2; vol = 255 - abs(x-425) - abs(y-250); if (vol<0) vol = 0; if (key[KEY_SPACE] && vol>10) { stop_sample(chef_hello); play_sample(chef_hello,vol,128,1000,FALSE); rest(100); } }
  • 61. Rotating 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.
  • 62. Fifty-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.
  • 63. 950 392 98 73 (rank*73,suit*98) rank = (0..12) suit = (0..3) Managing the Cards Sprite
  • 64. void main( void ) { int cardwidth = 73; int cardheight = 98; int width = 1180; int height = 720; char *filename = &quot;cards_orig.bmp&quot; ; 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 (!key[KEY_ESC]) { blit(cards,buffer,rand()%13*cardwidth,(rand()%4)*cardheight, rand()%(width-cardwidth),rand()%(height-cardheight), cardwidth,cardheight); blit(buffer,screen,0,0,0,0,width,height); } allegro_exit(); } END_OF_MAIN() Complete Source Code - 52 Pick-Up
  • 66. Translucent 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 = alpha*rbk + (1.0-alpha)*rsp; gbk = alpha*gbk + (1.0-alpha)*gsp; bbk = alpha*gbk + (1.0-alpha)*bsp; pixbk = makecol(rbk,gbk,bbk);
  • 67. Card 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 i=0;i<width;i++) for( int j=0;j<height;j++) { pix = getpixel(buffer,i,j); r = getr(pix); g = getg(pix); b = getb(pix); r -= 8; g -= 8; b -= 8; if (r<0) r=0; if (g<0) g=0; if (b<0) b=0; pix = makecol(r,g,b); putpixel(buffer,i,j,pix); } }
  • 68. while (!key[KEY_ESC]) { blit(cards,buffer,rand()%13*cardwidth,(rand()%4)*cardheight, rand()%(width-cardwidth),rand()%(height-cardheight), cardwidth,cardheight); dimmer(); blit(buffer,screen,0,0,0,0,width,height); } allegro_exit(); Modified Main Loop
  • 70. Animated Sprite Demo uses Prince of Persia Sprite Sheet
  • 71.  
  • 72.  
  • 73.  
  • 74.  
  • 75.  
  • 76.  
  • 77.  
  • 78. Sprite 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 (!key[KEY_ESC]) { for ( int i=0;i<13;i++) { move = num_steps*step_size; blit(bkg_image, buffer, 660-move-10, 380, 660-move-10, 380, 76, 90); masked_blit(sprite_sheet,buffer, i*56,0,660-move,380,56,90); blit(buffer,screen,0,0,0,0,SCREEN_W,SCREEN_H); num_steps +=1; if (move>720) num_steps = 0; rest(80); } } selects the proper segment of the sprite sheet to display covers old sprite with the proper region of the background image
  • 79. char *backname = &quot;BlueBkg.bmp&quot;; char *spritename = &quot;alladin.bmp&quot;; 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_AUTODETECT_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( &quot;Error loading %s&quot; , backname); return 1; } sprite_sheet = load_bitmap(spritename,NULL); if (!sprite_sheet) { set_gfx_mode(GFX_TEXT,0,0,0,0); allegro_message(&quot;Error loading %s&quot;, spritename); return 1; }
  • 80. buffer = create_bitmap(SCREEN_W, SCREEN_H); clear_bitmap(buffer); blit(bkg_image,buffer,0,0,0,0,640,480); masked_blit(sprite_sheet,buffer,0,0,15,130,728,90); num_steps = 0; while (!key[KEY_ESC]) { for ( int i=0;i<13;i++) { move = num_steps*step_size; blit(bkg_image, buffer, 660-move-10, 380, 660-move-10, 380, 76, 90); masked_blit(sprite_sheet,buffer, i*56,0,660-move,380,56,90); blit(buffer,screen,0,0,0,0,SCREEN_W,SCREEN_H); num_steps +=1; if (move>720) num_steps = 0; rest(80); } } destroy_bitmap(bkg_image); destroy_bitmap(sprite_sheet); allegro_exit(); return 0;
  • 81. Sprite Sheet for The Prince of Persia
  • 82. Creating a Sprite Image Tank Composed of Power Point 3D Objects finished sprite sheet with transparency reference 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. sprite_width = 98 pixels
  • 83. Tank 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
  • 84. Sample Output Z - move backward X - move forward Q - barrel up A - barrel down
  • 85. char *backname = &quot;BlueBkg.bmp&quot; ; char *spritename = &quot;tank_sprite_sheet_sm.bmp&quot; ; char *turretname = &quot;turretsprite.bmp&quot; ; 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; Tank Sprite Demo Setup 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
  • 86. //initialize the program allegro_init(); install_keyboard(); set_color_depth(16); set_gfx_mode(GFX_AUTODETECT_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,buffer,0,0,0,0,760,480); //install a digital sound driver if (install_sound(DIGI_AUTODETECT, MIDI_NONE, &quot;&quot; ) != 0) { allegro_message( &quot;Error initializing sound system&quot; ); return 1; } backsound = load_sample( &quot;dead_wind_loop.wav&quot; ); tanksound = load_sample( &quot;tankgo.wav&quot; ); turretsound = load_sample( &quot;turret.wav&quot; ); play_sample(backsound, 128, 128, 1000, TRUE); Loading Bitmaps and WAV Files
  • 87. i = 0; num_steps = 0; rotate_sprite(buffer,turret_sprite,36,413,itofix(255)); masked_blit(sprite_sheet,buffer, 15,10, 15, 405, sprite_width,sprite_height); blit(buffer,screen,0,0,0,0,SCREEN_W,SCREEN_H); i=0 i=1 i=2 i=3 Initial Position
  • 88. while (!key[KEY_ESC]) { // barrel up // barrel down // tank backward // tank forward // turn off tanksound //turn off turretsound // draw and display next frame } Actions in Main Game Loop
  • 89. // barrel up if (key[KEY_Q]) { turret_ang -= 1; if(turret_ang<200) turret_ang=200; if(!turreton) { play_sample(turretsound,255,tankpan,1000,TRUE); turreton = true; } adjust_sample(turretsound,255,tankpan,1000,TRUE); } // barrel down if (key[KEY_A]) { turret_ang += 1; if (turret_ang>255) turret_ang = 255; if (!turreton) { play_sample(turretsound,255,tankpan,1000,TRUE); turreton = true; } adjust_sample(turretsound,255,tankpan,1000,TRUE); } Turret Gun Actions
  • 90. Turret Gun Tube Rotation rotate_sprite(turret_sprite, buffer,destx,desty,itofix(ang)); 255 192 ang 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.
  • 91. // tank backward if (key[KEY_X]) { i = (i+1) % 4; num_steps +=1; move = num_steps*step_size; tankpan = 255*move/SCREEN_W; if (!tankon) { play_sample(tanksound,255,tankpan,1000,TRUE); tankon = true; } adjust_sample(tanksound,255,tankpan,1000,TRUE); } // tank forward if (key[KEY_Z]) { i = i-1; if (i<0) i=3; num_steps -=1; move = num_steps*step_size; tankpan = 255*move/SCREEN_W; if (!tankon) { play_sample(tanksound,255,tankpan,1000,TRUE); tankon = true; } adjust_sample(tanksound,255,tankpan,1000,TRUE); } Tank Motion Actions
  • 92. // turn off tanksound if (!key[KEY_X] && !key[KEY_Z]) { stop_sample(tanksound); tankon = false; } // turn off turretsound if (!key[KEY_A] && !key[KEY_Q]) { stop_sample(turretsound); turreton = false; } // draw and display next frame blit(bkg_image, buffer, 0,0,0,0,SCREEN_W,SCREEN_H); rotate_sprite(buffer,turret_sprite,36 + move,413,itofix(turret_ang)); masked_blit(sprite_sheet,buffer, 15+i*sprite_width, 10, 15 + move, 405, sprite_width,sprite_height); blit(buffer,screen,0,0,0,0,SCREEN_W,SCREEN_H); rest(80); Stop Sounds Actions and Display
  • 93. Collision Detection - Atomic Fireflies Collision_Detection_Demo_02 for ( int k=0;k<Num-1;k++) for ( int m=k+1;m<Num;m++) collide(k,m); void collide( int k, int m) { if ([collision_check]) { // handle collision } } double dist( int k, int m) { return sqrt(pow((ball[k].x-ball[m].x),2.0) + pow((ball[k].y-ball[m].y),2.0)); } Note: Straight-line distance is not the most efficient method for detecting collisions. Compare with hit( ) function shown later.
  • 94. Collision 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.
  • 95. Collision Detection - Atomic Fire Flies
  • 96. struct ball_state { double x; double y; double vx; double vy; int px; int py; int pxold; int pyold; } ball[100]; struct fire_state { double x; double y; double vx; double vy; int count; } fire[100];c Moving Balls and Explosion Struct Lists
  • 97. 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; } 256 x 256 pixel image of explosion col = c % 4 row = c / 4 sprite images are 64 x 64 pixels Extracting Frames from 2D Sprite 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.
  • 98. for ( int k=0;k<bcount-1;k++) for ( int m=k+1;m<bcount;m++) collide(k,m); for ( int q=0;q<fcount;q++) { if (fire[q].count==0) play_sample(explode[rand()%4],rand()%56+200,rand()%256, 800+rand()%400,FALSE); draw_explosion((int)fire[q].x,(int)fire[q].y,fire[q].count); fire[q].x += fire[q].vx; fire[q].y += fire[q].vy; } remove_fireballs(); Managing Multiple Animated 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[ ]. draw_explosion( ) increments frame count of the explosion sprites
  • 99. for ( int i = 0; i<bcount;i++) { ball[i].pxold = ball[i].px; ball[i].pyold = ball[i].py; ball[i].x = ball[i].x + ball[i].vx + rand()%4-2; ball[i].y = ball[i].y + ball[i].vy + rand()%4-2; ball[i].px = (int)ball[i].x; ball[i].py = (int)ball[i].y; if (ball[i].px<=radius || ball[i].px>=max_x-radius) { ball[i].vx = -ball[i].vx; if (ball[i].x>=radius) ball[i].x=(double)(max_x-radius); else ball[i].x=(double)radius; } if (ball[i].py<=radius || ball[i].py>=max_y-radius) { ball[i].vy = -ball[i].vy; if (ball[i].y>=radius) ball[i].y=(double)(max_y-radius); else ball[i].y=radius; } circlefill(buffer,ball[i].pxold,ball[i].pyold,radius,ORANGE); circlefill(buffer,ball[i].px,ball[i].py,radius,BLUE); } Managing An Array of Moving Objects
  • 100. int hit( int k, int m, int range) { int xsep; int ysep; xsep = (int) (ball[k].x - ball[m].x); ysep = (int) (ball[k].y - ball[m].y); if (xsep<range && xsep>-range && ysep<range && ysep>-range) return 1; else return 0; } void collide( int k, int m) { if (hit(k,m,close_enough)) { fcount+=1; fire[fcount-1].x = (ball[k].x + ball[m].x)/2.0; fire[fcount-1].y = (ball[k].y + ball[m].y)/2.0; fire[fcount-1].vx = (ball[k].vx + ball[m].vx)/2.0; fire[fcount-1].vy = (ball[k].vy + ball[m].vy)/2.0; fire[fcount-1].count = 0; } } Detecting Collisions and Managing the Collision List
  • 101. void remove_fireballs(void) { int inc = 0; int dec = 0; bool done = (fcount<=0); while (!done) { if (fire[inc].count>15 && dec<fcount) dec += 1; if (dec<fcount) { fire[inc] = fire[dec]; if (fire[inc].count<=15) { inc += 1; dec += 1; } } done = (dec>=fcount); } fcount = inc; } Removing Completed Fireballs from the Fire[ ] List fire[ . ] list is scanned and all members with count>15 are dropped. fcount is reduced by the number of members eliminated. 12 2 2 16 4 16 16 7 8 inc dec 12 2 4 7 8 inc dec 16 16 7 8 fire[]
  • 102.
  • 103. Scrolling 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.
  • 104. Scanning a Panoramic Image A Step Toward Horizontal Scrolling while (!key[KEY_ESC]) { if (key[KEY_LEFT]) { blitx -= 3; if (blitx<0) blitx = 0; } if (key[KEY_RIGHT]) { blitx += 3; if (blitx+SCREEN_W>bkgwidth) blitx = bkgwidth - SCREEN_W; } blit(bkgimage,buffer,blitx,blity,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. display screen
  • 105. // Horizontal Scrolling Demo 1 #include <allegro.h> int max_x = 640; int max_y = 480; int blitx = 0; int bkgwidth = 7249; int bkgheight = 529; int blity = 0; char *filename = &quot;talafar.bmp&quot; ; 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,NULL); buffer = create_bitmap(SCREEN_W, SCREEN_H); while (!key[KEY_ESC]) { if (key[KEY_LEFT]) { blitx -= 3; if (blitx<0) blitx = 0; } if (key[KEY_RIGHT]) { blitx += 3; if (blitx+SCREEN_W>bkgwidth) blitx = bkgwidth - SCREEN_W; } blit(bkgimage,buffer,blitx,blity,0,0,SCREEN_W,SCREEN_H); blit(buffer,screen,0,0,0,0,SCREEN_W,SCREEN_H); rest(1); } } END_OF_MAIN()
  • 106. The 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; x y chx - x position chy - y position chvx - x velocity chvy - y velocity chax - x acceleration chay - y acceleration
  • 107. Motion 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/s 2 ). There is no force in the x direction on a moving object (without friction). x y x, y - object location v x , v y - object velocity a y - object acceleration due to gravity = -9.8 meters/second/second.
  • 108. chx = 30.0; chy = ( double )chymax; chvx = 0.0; chvy = 0.0; chay = 9.8; chax = 0.0; chvy = chvy + chay*dt; chvx = chvx + chax*dt; chy = chy + chvy*dt + 0.5*chay*dt*dt; chx = chx + chvx*dt + 0.5*chax*dt*dt; if(key[KEY_LEFT]) { chax -= 1.0; if(chax<-5.0) chax = -5.0; } if(key[KEY_RIGHT]) { chax += 1.0; if(chax>5.0) chax=5.0; } main loop Motion Controlled by Acceleration
  • 109. blitx = ( int )chx - SCREEN_W/2; blity = ( int )chy - SCREEN_H/2; if (blitx<0) blitx = 0; if (blitx+SCREEN_W>bkgwidth) blitx = bkgwidth - SCREEN_W; if (blity<0) blity = 0; if (blity+SCREEN_H>bkgheight) blity = bkgheight - SCREEN_H; circlefill(bkgimage,( int )chx,(int)chy,8,makecol(255,0,0)); blit(bkgimage,buffer,blitx,blity,0,0,SCREEN_W,SCREEN_H); blit(buffer,screen,0,0,0,0,SCREEN_W,SCREEN_H); Positioning 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.
  • 110. Drawing a Bitmap - Sample Output
  • 111. #include <allegro.h> int main( void ) { char *filename = &quot;game_bkg.bmp&quot; ; 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( &quot;Error loading %s&quot; , 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 , &quot;%dx%d&quot; ,SCREEN_W,SCREEN_H); //wait for keypress while (!keypressed()); allegro_exit(); return 0 ; } END_OF_MAIN() Loading a Bitmap
  • 113. Embedding Fixed Objects vpix hpix map array nrows ncols game bkg image 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... sp width = hpix/ncols sp height = vpix/nrows
  • 114. Sprite Width = = 29 pixels Sprite Height = = 20 pixels Map Array Details 560 28 0 - no sprite 1 - background sprite 2 - block (immovable) 3 - movable 4 - breakable 5 - other objects (such as ramps and pits). 0 0 0 0 0 0 0 0 0 29 x 20 pixels 250 28 1 2 7250 250
  • 115. #include <fstream.h> struct cell{ int sprnum; int block; int breakable; int row; int col; }map[28][250]; void load_map( void ) { ifstream inFile; inFile.open( &quot;map.dat&quot; ); for ( int r=0;r<nrows;r++) for ( int c=0;c<ncols;c++) inFile >> map[r][c].sprnum; inFile.close(); } Loading Map Array
  • 116. Displaying the Map Array Cells in the Game World View load_map(); for ( int r = 0;r<nrows;r++) { for ( int c = 0;c<ncols; c++) { cnum = map[r][c].sprnum; if (cnum == 0) col = BLUE; if (cnum == 1) col = GREEN; if (cnum == 2) col = RED; if (cnum == 3) col = YELLOW; rectfill(bkgimage, c*pwidth+2, r*pheight+2, (c+1)*pwidth-3, (r+1)*pheight-3,col); } } leaves some space around each cell pwidth = width of cell in pixels pheight = height of cell in pixels
  • 117. struct block{ int xmin; int xmax; int ymin; int ymax; }blocks[100]; for ( int r = 0;r<nrows;r++) for ( int c = 0;c<ncols;c++) if (map[r][c].sprnum==2) { blocks[numblocks].xmin = pwidth*c; blocks[numblocks].xmax = pwidth*(c+1); blocks[numblocks].ymin = pheight*r; blocks[numblocks].ymax = pheight*(r+1); numblocks += 1; } Building a List of Blocking Cells defines the limits each blocking cell
  • 118. 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 &quot;special features&quot; of the game. :-) Managing Collisions
  • 119. hit = false; for ( int i=0;i<numblocks;i++) { if (inside(chx,chy,sep,blocks[i]) && !hit) { hit = true; dtime = 0; diffxleft = abs(((int)chx+sep) - blocks[i].xmin); diffxright = abs(((int)chx-sep)-blocks[i].xmax); diffytop = abs(((int)chy+sep) - blocks[i].ymin); diffybottom = abs(((int)chy-sep) - blocks[i].ymax); diffx = min(diffxleft,diffxright); diffy = min(diffytop,diffybottom); if (diffx<diffy) { chvx = - chvx; if (diffxleft<diffxright) chx = blocks[i].xmin - sep; else chx = blocks[i].xmax + sep; } else { chvy = - chvy; if (diffytop<diffybottom) chy = blocks[i].ymin - sep; else chy = blocks[i].ymax + sep; } } } Code for Managing Collisions with Blocks
  • 120. hstart = ((int)chx-pwidth)/pwidth; hfinish = ((int)chx+pwidth)/pwidth; vstart = ((int)chy-pheight)/pheight; vfinish = ((int)chy+pheight)/pheight; if (hstart<0) hstart = 0; if (hfinish>ncols) hfinish = ncols; if (vstart<0) vstart = 0; if (vfinish>nrows) vfinish = nrows; for ( int r=vstart;r<=vfinish;r++) for ( int c=hstart;c<=hfinish;c++) { cnum = map[r][c].sprnum; if (cnum == 0) col = BLUE; if (cnum == 1) col = GREEN; if (cnum == 2) col = RED; if (cnum == 3) col = YELLOW; rectfill(bkgimage, c*pwidth+2, r*pheight+2, (c+1)*pwidth-3, (r+1)*pheight-3,col); } Redrawing Background Cells
  • 122.  
  • 123.  
  • 124.  
  • 125. x 0 = 0 x 1 = 2x x 2 = 4x x 3 = 2x y 0 = 0 y 1 = -x y 2 = 0 y 3 = x Laying Down the Base t col = (N col - c)/N col x start = t col *x 0 + (1-t col )*x 1 y start = t col *y 0 + (1-t col )*y 1 x finish = t col *x 3 + (1-t col )*x 2 y finish = t col *y 3 + (1-t col )*y 2 t row = (N row - r)/N row x = t row *x start + (1-t row )*x finish y = t row *y start + (1-t row )*y finish (x 2 y 2 ) (x 1 y 1 ) (x 3 y 3 ) (x 0 y 0 ) N row bitmap N col 2x x
  • 126. 3D Modeling by Orthographic Projection
  • 128. x/2 pixels Alternative Methods for Surface Transformation px,py bx,by x pixels Nrow Ncol M =
  • 130. Diablo II - Zoom
  • 131. Diablo II - Level Editor Detail
  • 132.