Go4Expert

Go4Expert (http://www.go4expert.com/)
-   Game Programming (http://www.go4expert.com/articles/game-programming/)
-   -   Game Programing Tutorial dedicated to Dra-cu (http://www.go4expert.com/articles/game-programing-tutorial-dedicated-dra-t11816/)

XXxxImmortalxxXX 4Jul2008 00:44

Game Programing Tutorial dedicated to Dra-cu
 
4 Attachment(s)
When I started game programming I had all the enthusiasm but lacked quality information on how to go about actually making a complete game. There is a definite lack of complete game programming tutorials. Much of my time was spent flicking from one webpage to another not finding anything particularly useful. So I’ve decided to write a tutorial for your benefit so by the end you will be able to have a complete game under your belt.

A perfect game to start off with, in my opinion, is Pong.

This project will use VC++ and OpenGL for the examples.

_

The main game loop

The main game loop of most games basically goes like this:

Handle input
Update movements
Check for collisions
Check game conditions
Render

Pong is no different. With these in mind we shall structure our Game_Main function around this.

Game States

The game will be in various states while running. We need to take care of these so we will have a global named gameState and define these at the beginning of our code. These are:

PLAYING
GAMEOVER
GETREADY
The GETREADY state will be a state when the player's have a chance to get ready when the ball is reset after a goal or a new game is started.

Game Objects

We will make use of the OO technology we should look at what objects the game will use. The advantages of using OO to encapsulate the objects will makes things a great deal more organised. Practicing these methods now will pay off when you have a large project, you wont have to wade through so much code to make modifications.

For a game such as Pong there aren't too many:-

Paddle
Ball
Wall
Goal
Board

Each of these we will create a class for and fill in as we progress.

Where do we start?

With most of my projects I like to get something happening on the screen so I can test things as I go. For this project I think a good place to start would be to get the board drawn on the screen. Just a simple rectangle will do for now. We can modify and add to it as we go.

We’ll create a new class CBoard to do this. This class will need to have attributes and functions added to operate in our game world.

Our class diagram for the board will be like this:-

CBoard
width
height
color[3]
Draw()

Pretty simple. The color array is just an RGB (red, green, blue) set for the board. We may add some attributes later, such as a texture for the board.

We’ll set the width/height and color attributes in the class constructor.

The class definition and implementation will look like this

Cboard.h

Code:

// CBoard.h //
// Author: william palmer=me //
// Forgotten Realms // 
#include #include
// For OpenGL calls
class CBoard
{
        public: CBoard(); // Constructor
        ~CBoard(); // Destructor
        float width, height; // Actual playing field size
        float color[3]; // RGB color set
        Draw(); // Draw to opengl screen
};

Code:


#include "CBoard.h"
// Class declaration

////////////////////////////////////////////////////////////////////

// Constructor
CBoard::CBoard(): width(13.0f),  // Initialize width and height
height(10.0f)
{
        color[0] = 0; // Set the board color to blue
        color[1] = 0;
        color[2] = 1;
}

////////////////////////////////////////////////////////////////////

// Destructor
CBoard::~CBoard() { }

////////////////////////////////////////////////////////////////////
// Draw to opengl screen
CBoard::Draw()
{
        glColor3fv(color); // Set the color using the rgb color set
        glBegin(GL_QUADS); // Draw the board with center at (0,0)
        glVertex3f(-width/2, -height/2, 0.0f);
        glVertex3f(-width/2, height/2, 0.0f);
        glVertex3f( width/2, height/2, 0.0f);
        glVertex3f( width/2, -height/2, 0.0f);
        glEnd();
}

We need to include the class definition in main.cpp, and for such a simple game we will declare the objects as globals and refer to them in our main.cpp functions.

Adding a couple of lines to the Game_Main() function to call the board class' Draw() function and we get something happening.

http://www.go4expert.com/images/arti...prog/game1.jpg

THE BALL



The ball is probally the most complex object we will have in our game, it is also the most interesting!

Our ball will need a few attributes. We need to keep track of it's position which we'll use x,y,z for. It also has a radius and a color similar to the board.

The ball has a speed vector [xi, yi, zi] which represents the relative movement of the ball. It will be used to update the ball position and direction. We shall talk more about this later.

To draw the ball in OpenGL we’ll get tricky and use a quadric. It sounds pretty in depth but it's just an easy way to draw a 3D sphere. The line attribute GLUquadricObj *sphere is a pointer to the quadric that we'll use to create and draw it. It’s pretty simple to use, check out the NeHe tut on quadrics if you want to know more.

We also have a function Reset() for when we want to return the ball to the start position whenever a goal is scored or a new game starts.

The Update() function will use the speed vector to update the ball position every game cycle. We will implement this later, and for now just get the ball to appear on screen.

The Draw() function will need to set the color a little differently for the ball since it is a 3D object. A simple call to set the material attributes in OpenGL does this.

Our class diagram for the ball:

CBall
x, y, z (Center of the ball)
xi, yi, zi (This is our speed vector)
radius
color[3]
GLUquadricObj *sphere
Draw()
Reset()
Update()

We implement this in CBall.h and CBall.cpp and add a couple of lines to the rendering section and see the result:

Cball.cpp
Code:

#include "CBall.h"                // Class declaration

////////////////////////////////////////////////////////////////////

// Constructor

CBall::CBall():
        x(0.0f),
        y(0.0f),
        z(0.0f),
        xi(0.5f),
        yi(0.5f),
        zi(0.0f),
        radius(0.5f)
{
        color[0] = 1;                                                        // Set the ball color
        color[1] = 1;
        color[2] = 0;

        sphere = gluNewQuadric();                                // Create a pointer to a quadric object
        gluQuadricNormals(sphere, GLU_SMOOTH);        // Create smooth normals
        gluQuadricTexture(sphere, GL_TRUE);                // Create texture coords
}

////////////////////////////////////////////////////////////////////
       
// Destructor

CBall::~CBall()
{
        gluDeleteQuadric(sphere);                                // Remove the quadric from memory
}

////////////////////////////////////////////////////////////////////

// Draw to opengl screen

CBall::Draw()
{
        float mat_diff[] = { color[0], color[1], color[2], 1.0 };        // We have to set material properties when dealing with quadrics
        glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diff);

        glPushMatrix();                                                                                  // Save current matrix, so translation doesnt affect rest of program
                glTranslatef(x+radius/2, y-radius/2, z+radius/2); // Translate sphere so it is centered around x,y,z
                gluSphere(sphere, radius/2, 10, 10);                          // Draw sphere
        glPopMatrix();                                                                                  // Restore matrix
}

////////////////////////////////////////////////////////////////////

// Reset the ball position and vector

CBall::Reset()
{
        x = y = z = 0;
        xi = 0.5f;
        yi = 0.5f;
        zi = 0;
}

////////////////////////////////////////////////////////////////////

CBall::Update()
{
        // Implement this later
}

CBall.h
Code:

#include <windows.h>
#include <gl\gl.h>                                                        // Header File For The OpenGL32 Library
#include <gl\glu.h>                                                        // Glu32 header for quadrics

class CBall {

  public:

                float x, y, z;                                                // Top-left position on screen
                float xi, yi, zi;                                        // Movement vector
                float radius;
                float color[3];

                CBall();                                                        // constructor
                ~CBall();                                                        // destructor
                Draw();                                                                // Draw to opengl screen
                Reset();                                                        // Reset ball position and vector
                Update();                                                        // Update ball's position with vector

        private:

                GLUquadricObj *sphere;                                // Storage for quadratic object

};

The other objects



The Walls

The class diagram:
CWall
x, y (Top left coordinates)
width
height
color[3]
Draw()

* We’ll assume the width runs along X-axis and height along the Y-axis.

These are just rectangles that we can position at the top and bottom of the board. We will use these to bounce the ball off when we do some collision detection.

We add lines to the Game_Init() function that position the walls and as with the other objects we need to draw we add a Draw() command to the rendering section.

Here is the code:-

CWall.h
Code:

// CWall.h

#include <windows.h>
#include <gl/gl.h>                                                        // For OpenGL calls

class CWall {

  public:

                float x, y;                                                        // Top left coordinates
                float width, height;                                // Actual playing field size
                float color[3];                                                // RGB color set

                CWall();                                                        // Constructor
                ~CWall();                                                        // Destructor

                Draw();                                                                // Draw to opengl screen
};

CWall.cpp

Code:

// CWall implementation

#include "CWall.h"                // Class declaration

////////////////////////////////////////////////////////////////////

// Constructor

CWall::CWall():
        width(13.0f),                                                                // Initialize width and height
        height(0.5f)
{
                color[0] = 1;                                                        // Set the wall color
                color[1] = 0;
                color[2] = 0;
}

////////////////////////////////////////////////////////////////////

// Destructor

CWall::~CWall()
{ }

////////////////////////////////////////////////////////////////////

// Draw to opengl screen

CWall::Draw()
{
        glColor3fv(color);                                                        // Set the color using the rgb color set

        glPushMatrix();                                                                // Store the matrix so we can do the translation

        glTranslatef(x, y, 0);                                                // Position wall at x,y

        glBegin(GL_QUADS);                                                        // Draw the board with center at (0,0)
                glVertex3f(0,                0,                        0);
                glVertex3f(0,                -height,        0);
                glVertex3f(width,        -height,        0);
                glVertex3f(width,  0,                        0);
        glEnd();

        glPopMatrix();                                                                // Restore previous matrix
}

The paddles



Class diagram:
CPaddle
x, y (Top left coordinates)
width
height
speed
color[3]
score

Draw()
Reset()

:Paddles aren’t much different from wall, except we will give them a movement speed and a player score. We also initialise their positions in Game_Init().

The Reset() function will be called when a new game starts, it will just reset the player's score back to zero.

CPaddle.h

Code:

// CPaddle.h

#include <windows.h>
#include <gl\gl.h>                                                        // Header File For The OpenGL32 Library

class CPaddle {

        public:

                float width, height;                                // Paddle dimensions
                float x, y;                                                        // Top-left position on screen
                float speed;                                                // Movement speed
                float color[3];                                                // RGB color of the paddle
                int score;                                                        // Player's score

                CPaddle();                                                        // Constructor
                ~CPaddle();                                                        // Destructor
                Draw();                                                                // Draw to opengl screen
                Reset();
};

CPaddle.cpp

Code:

// CPaddle implementation

#include "CPaddle.h"                // Class declaration

////////////////////////////////////////////////////////////////////

// Constructor

CPaddle::CPaddle():
        x(0.0f),
        y(0.0f),
        width(0.5f),
        height(3.0f),
        speed(0.3f),
        score(0)
{
        color[0] = 0;
        color[1] = 1;
        color[2] = 0;
}

////////////////////////////////////////////////////////////////////

// Destructor

CPaddle::~CPaddle()
{ }

////////////////////////////////////////////////////////////////////

// Draw to opengl screen

CPaddle::Draw()
{
        glColor3fv(color);

        glBegin(GL_QUADS);
          glVertex3f(x,                        y                  , 0.0f);
          glVertex3f(x,                        y - height, 0.0f);
          glVertex3f(x + width, y - height, 0.0f);
          glVertex3f(x + width, y                  , 0.0f);
    glEnd();
}

////////////////////////////////////////////////////////////////////

// Reset paddle for new game

CPaddle::Reset()
{
        score = 0;
}

The goal



Since the wall and goal are so similar, we can use a wall object to represent the goal. We don't need to see the goal so we'll just leave out the command for drawing it.

When checking we have positioned the goal in the right spot we can just do a call to the Draw() function and see it on screen.

Note: The objects share a lot of attributes which we could use to make an abstract base class to derive them from, but since this is a beginners project and there’s not too many objects we shall leave it be. If you don’t know what I mean, don’t worry it’s just a more advanced OO technique that can be learnt later.

clicke game2 for picture

Paddle movement



Looks like we have all the basic bits and pieces on the screen. I hope you don’t think it was very hard, the next section will get the game actually doing something.

Moving the paddle

The paddle movement is going to require input from the keyboard.

We will use the keys ‘A’ and ‘Z’ for player 1 and the up and down cursors for player 2.

To check if a key is pressed with this code framework is pretty easy. We just need to check each key using the function KEY_DOWN() in the Game_Main() loop.

For the ‘A’ key we just check KEY_DOWN(DIK_A).
Our code will be:

if (KEY_DOWN(DIK_A))
move player 1 paddle up

Too easy, the others work exactly the same. To move the player’s paddle we just update their position according to the paddle speed attribute of the class:

player1.y += speed;

does the trick.

Paddle/wall collisions



Okay, it's not too good if the paddles can fly off the screen so we'll be adding some collision detection with the walls to stop that.

To detect the collision we check if the edge of the paddle will move past the edge of the wall. When this happens we'll have to let the computer know what we'll want to happen, which in this case, the paddle stops next to the wall.

click collision Diagram to see the picture

By looking at the diagram we can see the edges we need to check. For the top wall we check:

if (Paddle.y > (topWall.y - topWall.height))

and the bottom wall:

if ((Paddle.y - Paddle.height) < bottomWall.y)

When the collision occurs, we set the Paddle.y position to that edge of the wall. This is done every game loop for both player1 and 2 in the collision section of Game_Main().

Ball movement



The most complex object of the game is the ball. As we mentioned before, the ball has a vector which tells us direction the ball is travelling.

If you don't know about vectors, a basic physics/science book will go into depth explaining it. The vector contains information describing how far to move on each axis.

For example: A vector where xi = 1 and yi = -2, would mean we would move 1 unit right on the x-axis and 2 units down on the y-axis.

So having a vector for a ball, we can easily make the ball go whatever direction we want just by changing the values of each component.

I have decided to add another attribute to the ball class. It will have a speed attribute which will allow us to alter the ball speed easily as the game progresses making it faster so there's a challenge. Again change it's value in the constructor if it is too slow/fast for your system. In combination with the ball vector we can write the Update() function:

x += xi * speed;
y += yi * speed;
z += zi * speed;

We will update the ball's current position every game loop in Game_Main() by calling the Update() function in the ball class.

Making these changes to the code we can now see the ball fly straight off the screen. Looks like we'll need to add some collision detection, that's next!

cball update

Code:

// CBall implementation

#include "CBall.h"                // Class declaration

////////////////////////////////////////////////////////////////////

// Constructor

CBall::CBall():
        x(0.0f),
        y(0.0f),
        z(0.0f),
        xi(0.5f),
        yi(0.5f),
        zi(0.0f),
        radius(0.25f),
        speed(0.15f)
{
        color[0] = 1;                                                        // Set the ball color
        color[1] = 1;
        color[2] = 0;

        sphere = gluNewQuadric();                                // Create a pointer to a quadric object
        gluQuadricNormals(sphere, GLU_SMOOTH);        // Create smooth normals
        gluQuadricTexture(sphere, GL_TRUE);                // Create texture coords
}

////////////////////////////////////////////////////////////////////
       
// Destructor

CBall::~CBall()
{
        gluDeleteQuadric(sphere);                                // Remove the quadric from memory
}

////////////////////////////////////////////////////////////////////

// Draw to opengl screen

CBall::Draw()
{
        float mat_diff[] = { color[0], color[1], color[2], 1.0 };        // We have to set material properties when dealing with quadrics
        glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diff);

        glPushMatrix();                                                                                // Save current matrix, so translation doesnt affect rest of program
                glTranslatef(x, y, z);                                                        // Translate ball position
                gluSphere(sphere, radius, 10, 10);                          // Draw sphere
        glPopMatrix();                                                                                // Restore matrix
}

////////////////////////////////////////////////////////////////////

// Reset the ball position and vector

CBall::Reset()
{
        x = y = z = 0;
        xi = 0.5f;
        yi = 0.5f;
        zi = 0;
        speed = 0.15f;
}

////////////////////////////////////////////////////////////////////

CBall::Update()
{
        x += xi * speed;                                                        // Update ball position according to vector
        y += yi * speed;
        z += zi * speed;
}

Ball/Wall collisions



Testing for this type of collision is exactly the same as we did for the paddles. The only difference is when the collision occurs we want the ball to bounce off and go the other direction.

To make the ball go in the opposite direction the y vector component is just inverted. Therefore if we are travelling towards the top wall yi is positive, to go down we make it negative. The bottom wall is the same.

ball.yi = -ball.yi

This line acheives it for both scenarios.

Check out that collision test doing it's wonders:

Ball/paddle collisions



More collisions! If you mastered the last section this collision isn't much different.

Instead of working with ball.yi we work on ball.xi. We only need to check the front edge of the paddle (we can do the side edges of the paddle but it's not crucial).

We have to have an extra check in this collision. First we have the same as the wall only on the x-axis, then we have to check ball's y position is in position to hit the paddle.

Code:

if ((ball.x - ball.radius < player1.x + player1.width) &&
  (ball.y < player1.y) &&
  (ball.y > player1.y - player1.height))
ball.xi = -ball.xi;

if ((ball.x + ball.radius > player2.x) &&
  (ball.y < player2.y) &&
  (ball.y > player2.y - player1.height))
ball.xi = -ball.xi;

It looks tough, but it is just the same as the other collisions with an extra check.
click game 3 to look at it

Scoring goals



Checking if a goal is scored should be easy if you've been following. The question is what do we do when a goal is scored?

First the player who scored needs to gain a point, we just add 1 to their score attribute.

player.score++

Secondly the ball needs to be reset and the player's should be given a little time to get ready. This is where our gameState variable will come in handy. We'll set it to GETREADY that was defined earlier for this purpose.

So we can test when to change from GETREADY back to PLAYING we need to use a timer which will be handled with a new global name gameStateTimer. The system function timeGetTime() is used to set it to the current time in milliseconds and add a delay for the time when we change states. 2000 milliseconds (2 seconds) for the delay should be fine.

When the game state is GETREADY I've displayed some text so the player's know what's going on.

In Game_Main() we check for the game state being GETREADY and test whether it is time to change back to PLAYING by comparing the timer with the current time.

One more thing is make sure the ball only moves when the game state is PLAYING

click game4 to view it

Nearly done!



Okay this is the home stretch. You will have a complete game after this!

There are a few loose ends that need to be tidied up.

First, we'll display the player's score in the top corners, a few lines in the text output section of Game_Main() and we're in buisness.

We will also check if the GAMEOVER condition occurs. When either of the player's score 7 points we'll end it.

Then, we'll make the game state start with GAMEOVER when we initialize the game and display "GAME OVER" the same as was done for "GET READY!".

Also we'll allow a new game to be started when we are in the GAMEOVER state and the space bar is pressed. We need to reset the player scores here, and change the game state to GETREADY.

Letting the players know the keys is a good idea when the game is in GAMEOVER state.

XXxxImmortalxxXX 4Jul2008 02:03

Re: Game Programing Tutorial dedicated to Dra-cu
 
1 Attachment(s)
This is the end of the tutorial i hoped you all like it below is the full source code and game.

I hope u like it

if you our anyone else needs help with this please dont hesitate to ask me thankyou all for reading this tutorial.



This tutorial was brought to you by XXxxImmortalxxXX




game download+source code



Game Download

XXxxImmortalxxXX 4Jul2008 02:06

Re: Game Programing Tutorial dedicated to Dra-cu
 
i really didnt know where to post this you can put this post where you may see fit

Admin


thankyou

XXxxImmortalxxXX 4Jul2008 02:20

Re: Game Programing Tutorial dedicated to Dra-cu
 
also i put a glitch in the game the first one to figure it out and send me the files will win a free copy of FPS CREATOR

this is not a lie its the truth hope to see you all try and figure it out.

7flint7 4Jul2008 04:58

Re: Game Programing Tutorial dedicated to Dra-cu
 
do we have to tell you where the glitch is in the source code or is it visible from game play? :smug:

shabbir 4Jul2008 10:12

Re: Game Programing Tutorial dedicated to Dra-cu
 
Quote:

Originally Posted by XXxxImmortalxxXX
i really didnt know where to post this you can put this post where you may see fit

Done that.
Quote:

Originally Posted by XXxxImmortalxxXX
also i put a glitch in the game the first one to figure it out and send me the files will win a free copy of FPS CREATOR

You had one code block in a single line and probably that could be.

By the way very nice article.

XXxxImmortalxxXX 4Jul2008 11:23

Re: Game Programing Tutorial dedicated to Dra-cu
 
Yes you must send me a valid game back to me with the updated code files in the section to where you updated the code at the following


//name
//time
//date
//what did you do and how did you change it
// if it is correct do you want the FPS CREATOR sent to you via mail or do you want a serial key and you just download the program at the site and enter in the serial key when you boot up the game


also the glitch is when you start up the game the pong instantly shoots to the top right hand corner slow its speed down and make it to where it goes <------- and ---------> instead of oblique


also thankyou very much for the compliment
Quote:

By the way very nice article
i really appreciate that alot.

More Tutorials coming soon on game programing next article will be related to

Visual Basic RPG programing in 2-D one of the best ways to start off with rpg programing is in a 2-d based way

Dra-cu 5Jul2008 12:49

Re: Game Programing Tutorial dedicated to Dra-cu
 
Thank you very much Immortal

Very helpful :)

XXxxImmortalxxXX 5Jul2008 12:51

Re: Game Programing Tutorial dedicated to Dra-cu
 
np mate i also posted another game programing article to teach you a simple RPG combat attack script made in VB

skp819 6Jan2009 11:02

Re: Game Programing Tutorial dedicated to Dra-cu
 
Thanks for sharing it.
Do you know any site for online tutorial of game programming.

virender.ets 7Feb2011 16:04

Re: Game Programing Tutorial dedicated to Dra-cu
 
Thanks for valuable tutorial.

seangtz 24Mar2011 09:25

Re: Game Programing Tutorial dedicated to Dra-cu
 
Quote:

Originally Posted by skp819 (Post 41121)
Thanks for sharing it.
Do you know any site for online tutorial of game programming.

Hey, I heard about iPhone Game Programming – Tutorial, it helps to cover basics of taking an OpenGL ES Application template available in Xcode and making the changes necessary so that we can use it for writing out game.

BabyBitch 29Jun2011 03:45

Re: Game Programing Tutorial dedicated to Dra-cu
 
Dear XXxxImmortalxxXX,

I can't download your full source code and game

I hope u will help me to download this game.

Mrdevid 6Aug2011 11:55

Re: Game Programing Tutorial dedicated to Dra-cu
 
Hello' This Mr devid. i am new here. Well this is my website. please feedback my website. Thanks.

rijolo012593 8Feb2012 15:03

Re: Game Programing Tutorial dedicated to Dra-cu
 
Nice tutorial sir. :)

Scripting 8Feb2012 21:48

Re: Game Programing Tutorial dedicated to Dra-cu
 
Good looking tutorial, btw. game programming this way is pain in *** :D If you want to programm some efficient game, you should use some preprogrammed libraries and functions :D

ManzZup 23Nov2012 21:27

Re: Game Programing Tutorial dedicated to Dra-cu
 
and this is what i waited for
at last something solid basic for beginning

thanks :D


All times are GMT +5.5. The time now is 08:18.