Download presentation
1
Programming Video Games
With C/C++ and Allegro Programming Video Games
2
Class Agenda We will: Discuss video games and how they work
Overview our tools, and install them Develop a plan for creating Pong Write a basic Pong game Elaborate on the game, time permitting
3
Video Games What is a video game? How do they work?
4
What is a video game? Interactive
Tight communication between player and game Player has control over the video game Imaginative Entertaining What video games does the class play? What do they have in common? Why are they different, or better than movies or TV? == interactivity. Player learns to respond and “feel” the game, as he is constantly forced to respond to the game. More control to the player gives them power, making video games appealing Video games are rarely based on reality, and provide a story and experience much like books and movies. Genres of video games, referring back to the games listed. History of video games, Pong leading to Atari, then Pacman. Future of video games, parallel to movies.
5
Model of a Video Game Loading Control Logic Feedback Unloading
Before you even start playing the game, what must you wait for it to do? Once game loaded, it goes into a repetitive loop. Game mostly composed of a large main loop, which cycles many times a second. (also the framerate) Every cycle, it must get input from the player, update the game world accordingly, and output the changed world to the player. The cycle repeats until the player exits, and the game unloads. Feedback Unloading
6
C/C++ and Allegro Why should we use C/C++?
Why is Allegro good to start with?
7
C/C++ Programming Language High level, but lower than BASIC
More complicated, but more versatile Universal Strongly-typed C is a programming language like HTML, Visual Basic, Foxpro, etc. It is high level, you do not see actual memory transaction or assembler, but it is much lower than BASIC which wraps it around completely. It is more complicated, but with that complexity you get more freedom and versatility to do what you want. There is a good balance. You can program in C/C++ on almost any computer or system. It is universally accepted, generally, you can’t go wrong with C/C++. Biggest difference from basic is the syntax and that variables MUST BE IN THE SAME CAPS OR NO CAPS STATE.
8
C/C++ | Hello World #include<stdio.h> main() { }
printf("Hello World"); } Main() is a function. The parentheses will have the arguments. The braces include the code to be run. Printf(const char); is also a function, and it recieves a string of text and prints it out to the console. All commands must be ended with a semicolon. #include tells the computer to use a library. Refresher of C/C++, we will learn bits and pieces as we go along.
9
Allegro Library Cross-Platform Very easy to learn and use
Has powerful features Has 3D capability with OpenGL Allegro is a game programming library, which is a set of functions that work with the operation system to draw and get input on the computer. DirectX, OpenGL, are some examples of libraries. Allegro can work on unix, windows, mac, dos, atari, amiga… unlike directx and even opengl. Allegro is easy to learn and use, as it does not require extensive knowledge of DirectX. It has powerful features, that allow you to do things easily without limiting you in what you can do. You can upgrade up to 3D with OpenGL Explain 2D/3D controversy, talk about difference between Allegro, SDL, and DirectX
10
Installing Allegro Windows is simple install Linux:
You need X11 development package You need gcc You need Allegro Standard ./configure + make depend + make + make install Install gcc/dev cpp first. Walk through of installing Allegro on Windows – simple click and go with dev-cpp, and the dev-pak. Walk through of installing on Linux, need gcc (sudo apt-get install dev-essentials) Once done, get the allegro library. make, make install.
11
Breaking Down Pong So, how are we going to make it?
Note how important design documents are (this is was it is). Discuss personal anecdote about various games.
12
Pong Two paddles and a ball – simple, effective.
13
Loading Initialize Allegro Load images into memory
Make variables to hold temporary info Location of paddles, and the ball The player score The speed of the ball Make sure everything worked Start the game loop Images are stored in Allegro’s special BITMAP, which is a custom type of variable added to C/C++ by the variable. You then load images from a file using a function, and they are placed in the BITMAP. Variables to hold this information are simply integers, and need to be set at the beginning for use. You need to start Allegro in order to do ANYTHING, and it opens up a window. Checking to see if it worked is a good idea, as it gives you an idea as to why something didn’t work. Finally, launching the game loop and checking if the user pressed ESC is essential.
14
Gathering Input (Control)
Check if keys are up or down Optionally, use the mouse to move Checking keys is EASY. You use if-then statements in C/C++. If the keys are up or down, then adjust the location of the paddle accordingly. If using the mouse, simply move the cursor along with the paddle.
15
Processing (Logic) Adjust the paddle location (based on input)
Adjust the ball location, using the ball speed Check to see if the ball hit the paddle If it did, bounce it off Check to see if the ball hit the wall Check to see if anyone scored Update the score if they did, restart Adjusting the paddle is simply adding or subtracting the y variable. Adjusting the ball variable uses an x and y velocity, added to it’s location. Use collision to determine if the ball hit the paddle, the wall, or the score zone.
16
Drawing (Feedback) Delete what was on the screen before
Draw the paddles Draw the ball You need to delete what was on the screen before, because if you didn’t you would have the following effect. Drawing the paddles and ball is obvious.
17
Programming Pong Initializing Allegro
18
Initializing Allegro #include “allegro.h” main () { allegro_init(); install_keyboard(); install_mouse() allegro_message(“Hello!”); allegro_exit(); } #include includes the library in the code, so that you can use. the main function is a function that is first called on execution. it is IMPORTANT. you must have it. allegro_init() starts the library, and allows you to use most functions. notice how a semicolon follows it. Install_keyboard and _mouse lets you use the keyboard and mouse. allegro_message draws a message on the screen, in this case, hello world. allegro_exit unloads the library and frees memory.
19
Setting Bit-Depth Bit-depth is a measurement of the amount of color that a computer can process 8 bit == 256 colors, 32 bit == millions of colors Allegro was designed for 8-bit systems In order for it to work, we need to set it to 32-bit int depth = desktop_color_depth(); if (depth == 0) depth = 32; set_color_depth(depth) This is simply a piece of code that is a “gotcha”, that is, you need to have for it to work properly. Simply put, the bit-depth is set improperly by Allegro. We need to send to the right bit depth.
20
Selecting a Graphics Mode
set_gfx_mode(type of window, width, height, 0, 0); int res = set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0); if (res != 0) { allegro_message(allegro_error); exit(-1); } set_gfx_mode basically starts all video processing, and opens a window. it takes three important arguments, the type of window to open, and the size of that window in x and y. a function also has a RETURN TYPE. it is what the function is “equal to”. the return type can be void, int, etc. in this case, set_gfx_mode returns a 0 when everything is OK! when it does not equal a 0, that means something went wrong. exit(-1) STOPS the program. the -1 is simply any number, it is not important. allegro_message from the last slide makes a popupbox.
21
Review you initialize allegro with allegro_init();, and include it with #include”allegro.h” you stop it with allegro_exit(); functions: allegro_message(), set_gfx_mode(), exit(),
22
Programming Pong Drawing to the Screen Double-buffering Transparency
23
Adding a Main Loop A main loop is the most important part of a game
while (!key[KEY_ESC]) { // action happens here } A while loop is VERY similar to a function and an if statement. it loops around until the condition is no longer true the ! operator is called a BANG operator. it means, NOT. the key[KEY_ESC] is an array, or a big list of keys that are pressed or not. arrays are accessed like so: array[0] .. array[1] … etc. KEY_ESC actually stands for a number, since you can have letters in an array. there are other keys, like KEY_UP, KEY_DOWN, etc. the actual value of that is either 0, or 1. when it is 0, the statement is true (it is NOT down). when the statement becomes 1 when a button is pressed, the loop stops. (because it IS true, since the button is down.) the double splash is a COMMENT, the compiler and the computer IGNORE everything following it on the line. these are useful to comment your code.
24
Drawing to the Screen BITMAP *paddle; paddle = load_bitmap(“paddle1.bmp”, NULL) draw_sprite(where to draw the image to, the image itself, x location, y location) draw_sprite(screen, paddle, 20, 240); a BITMAP is a special type of variable, much like an integer. it is defined by Allegro, and all it does is hold an image. notice the star – that is very important. it is called a POINTER. a POINTER makes the variable an ADDRESS instead of a an image. so, if you gave the pointer of a house to your friends – they could find it and look at it. this is easy for your friends to do. however, if you gave them a normal variable of your house, you would literally be picking up the house and handing it to them. in computers, this is the same. a BITMAP is a 64 byte variable, but a pointer is only 4 bytes. that way, when you are giving your house to different people, it is much easier just to tell them the location instead of giving them a house. load_bitmap is a function that takes a filename and loads it, it is always a *.bmp file. the second argument will always be NULL for our purposes. draw_sprite is a function that draws to the screen. “screen” is a special variable that lets you draw to the screen, just like the BITMAP, it is an address or a pointer to the screen. paddle is our image, and 20,240 is the location we’re drawing at.
25
Moving the Paddle int paddle1y = 240; if(key[KEY_DOWN]) { paddle1y = paddle1y + 3; } draw_sprite(screen, paddle, 20, paddle1y); clear_bitmap(screen); an INTEGER is simply a WHOLE number. you abbreviate it as int, and the variable name follow. the equals sign sets it to (middle of the screen) the if statement checks the key array if the down array is pressed, if it is, then it moves the paddle down.
26
Double Buffering Monitors refresh (update) ~70 times a second
Drawing a sprite to a screen is SLOW Copying memory <-> memory is FAST Solution? Have two copies of the screen Draw on the copy that is NOT on the real screen Swap the copies When you draw directly to the screen, it is SLOW. the screen refreshes by the time you’re done drawing, and that rips the image and makes it ‘not pretty’. we can get by this by using a DOUBLE BUFFER However, if you’re drawing to an image in memory, this is FAST. Also, if you’re simply replacing the entire screen, this is FAST. Therefore, if we don’t draw to the physical screen, but to a memory image, this will be fast. After we have finished drawing, we simply put the memory image on the physical screen – fast. Result? no image rip.
27
Double Buffering BITMAP *buffer; buffer = create_image(SCREEN_W, SCREEN_H); while(!key[KEY_ESC]) { // draw to BUFFER draw_sprite(buffer, paddle, 20, paddle1y); draw_sprite(screen, buffer, 0, 0); clear_bitmap(buffer); } First, we have to make that second copy of the screen we were talking about. This is the same as making any image holder, BITMAP. We make it, and then we have to initiliaze it with an empty screen, first. We use create_image for it. Allegro has special variable called SCREEN_W and SCREEN_H that have the current screen size in it, so we don’t have to write 640x480. Now that we made our second copy of the screen, we go into the main loop. We draw to the BUFFER this time, because it is wayyy faster. Once we did all our drawing, we are ready to do our fast switch-a-roo with the screen. We draw to the screen, and then we clear the buffer so it’s empty last time and does not lag.
28
Transparency draw_sprite() will NEVER draw hot pink
The value for hot pink in RGB is (255,0,255) We use hot pink for transparency A sprite is usually a BMP file that has a black background, and the sprite on top of it. However, when this is used, a problem occurs like the one shown above. We are drawing black over something that is already there, erasing what is underneath. This is Bad. Draw_sprite() does NOT draw hot pink. That means that if you use it as a background, it will NOT erase what is underneath. It merely draws just the sprite
29
Review What a main loop is, why it is important
BITMAP is a special variable that holds images a pointer is an ADDRESS functions: draw_sprite(), load_bitmap(); How to move the paddle, if statements, clearing the screen. Drawing to a variable. Double buffering, why it is important, how it works. Transparency, hot pink, and the blackness around an object. Now we have a fully interactive paddle – mover!
30
Programming Pong Ball Physics Bouncing Frame-rate
31
Ball Physics A ball will have an (x,y) location
A ball also has a velocity, or speed in (x,y) format To find the next location of the ball, we ADD the velocity to the current location The velocity of the ball is very similar to the velocity of a car moving along a highway. For example, the location of the car is its position along the highway. Let’s assume that our car is 5 miles into the highway. The velocity of the car is very simply the speed in miles per hour. Let’s assume that our car is moving at five miles per hour. Therefore, one can assume that the next position of the car on the highway will be 10 miles into the highway. We use the same methods to determine the position of the ball as it moves across the screen.
32
Ball Physics int ball_x = 320; int ball_y = 240; int ball_vel_x = 1; int ball_vel_y = 0; ball_x = ball_x + ball_vel_x; ball_y = ball_y + ball_vel_y; The first two lines create the x and y variables that will hold the location of the ball. These values are preset to the center of the screen, which in our case happens to be (320, 240). The next two lines initialize and preset the values for the ball’s velocity or speed. A velocity of x = 1 and y = 0 will mean the ball should move exclusively sideways. To update the next position of the ball, we simply add the velocity of the ball to the balls current disk.
33
Ball Bouncing Imagine a basketball falling towards the floor
It is falling down What is its velocity? It has hit the ground What is its velocity, now? It is coming back up What is this finally velocity? When the basketball falls to the ground, its velocity is negative relative to the ground. As it gradually falls to the ground, the speed remains generally constant. When it hits the ground, it has no velocity. However, when it starts coming back up, it has a velocity that is negative to the one that we had previously. (it is now positive). The same will work for our pong ball. If we simply invert the value of the velocity, the ball will go the opposite way it went before. A more interesting way to do it is just to invert the x variable. This way, the ball does not bounce diretly back, but does so at a 90 degree angle.
34
Ball Bouncing if(ball_y >= SCREEN_H) { ball_y_vel = -ball_y_vel; } if(ball_y <= 0) { SCREEN_H is a special variable declared by Allegro that has the vertical screen size saved (SCREEN_W is the horizontal counterpart). If the ball has a value greater than the size of the screen, it means it is OFF the screen and is OUT of bounds. That means we need to bounce it off to get it back into play. Now – why are reversing only the y variable? Simply because if both variables were inversed, then the ball would bounce straight back. If only the y variable is flipped, then the ball continues moving in its original horizontal direction. 0 is also the beginning of the screen, where we also need to bounce it back.
35
Frame-rate (FPS) Frame-rate is how fast the game runs
It is usually measured in FPS (Frames Per Second) The number of cycles the game completes in one second is the frame-rate A good frame rate to run at is ~30 fps rest(5); Frame-rate determines the number of cycles that the game main loop completes in one second. If you run at a faster frame-rate, the game will consequently run and move faster. Therefore, we need to fix the frame-rate in order to have the game run at a predicted speed. Frame-rate limiting systems are complex, but a simple system that simply slows down the loop is a suitable work around. Rest(x); simply tells the computer to wait for x number of milliseconds (1000 milliseconds == 1 second) Experiment with the value passed to rest() until the game runs at an acceptable speed.
36
Review How does a ball bounce? What happens to the velocity after a bounce? How does a ball move? How is the velocity affected? What is frame rate? why is it important to keep it in check?
37
Programming Pong Keeping Score Collision AI
38
Keeping Score When is a point scored?
When it passes the right edge (x = 640) Or the left edge (x = 0) We need to check the ball to determine if a point is scored. The players’ score is stored in an integer value
39
Keeping Score int player_1_score = 0; int player_2_score = 0; if(ball_x >= 640) { player_1_score = player_1_score + 1; ball_x = 0; ball_y = 0; } if(ball_x <= 0) { player_2_score = player_2_score + 1; First, we need to initialize the score of both players to 0 (else it will be a random value filled with what it was set to before). Then, we need to check if the ball has passed the right edge. If it has, then we need to add a point to the left player (player 1). If it has passed the left end, then we need to add a point to the right player (player 2). We need to reset the x and y values of the ball so the game can start again. Additionally, we can reset the x and y velocitys of the ball to make it more random.
40
Collision A simple method of collision is box-box
An imaginary box is drawn over a sprite If two boxes intersect, there is a collision We can check box collision by checking corners Demonstration A computer does not inherently know the size, location, or shape of the sprites. In order to find out if there is a collision, we need to simplify for the computer. One way of doing this is telling the computer to imagine boxes around the two sprites, and to see if any of the corners of the boxes intersect. The rule is like so – if a corner of a box is between the vertical and horizontal sides of another box, then it is inside that box. If a corner is inside that box, then there is a collision. Refer to the *.swf in the folder.
41
Artificial Intelligence
We will be using a finite-state machine If the ball is above the paddle, the paddle will move up If the ball is below the paddle, the paddle will move down Very simple “if” statements The paddle will very simply try to be on the same level as the ball.
42
Artificial Intelligence
if(ball_y > paddle2y) { paddle2y += 5; } if(ball_y < paddle2y) { paddle2y -= 5; Simply put the paddle always tries to be on the same level as the ball. The if statement checks if the ball is above or below the paddle, and if it is, it tries to correct itself so that it is equal.
43
Review Artificial Intelligence, how we do a simple state machine.
Collision, box-box, circle-circle?
44
Conclusion Where do we go next? Resources Other game ideas
Make the game 2 player Add a menu to the game Make the game end after a score of 10 Add power-ups to the game Resources Other game ideas You can do a lot of things with Allegro. Refer to RESOURCES.txt for info on where to go next.
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.