2D Game Development with OpenGL – Creating the player object
The next step in the development of the game is to add a player object. To keep the game simple, we wont be using any sort of inheritance and will be keeping all object types entirely separate. This section will be pretty small, adding 2 more files to our source tree, making a small modification to the Makefile and adding 3 lines of code to Main.cpp.
Player.h
The first new file which will be added is Player.h which will hold the definition for our Player object. This file’s basic form is as follows:
class Player
{
private:
int health;
float x, y;
bool moving;
public:
int getHealth(void);
float getX(void);
float getY(void);
void startMoving(void);
void stopMoving(void);
void update();
void draw();
};
This basic class contains elements which will help simulate our tank. The health attribute will be used to determine whether the tank has been destroyed or not, x and y are pretty obvious (the tank location), the moving boolean will be used in the update method to decide whether to move the tank or not and there are a few public functions which can be used to access these attributes. It is good to note, however, that most of these attributes might become deprecated later on in the development phase due to the possible implementation of the Box2D physics engine. The update and draw methods will be called from the update and render methods in the game loop found in Main.cpp.
Player.cpp
The next file to be added is Player.cpp. This contains the code for the functions defined in the Player class from Player.h.
#include "Player.h"
#include <GL/gl.h>
/**
Return health of player
*/
int Player::getHealth(void)
{
return health;
}
/**
Return X location
*/
float Player::getX(void)
{
return x;
}
/**
Return y location
*/
float Player::getY(void)
{
return y;
}
/**
Start tank moving forward
*/
void Player::startMoving(void)
{
moving = true;
}
/**
Stop tank moving forward
*/
void Player::stopMoving(void)
{
moving = false;
}
/**
Player's update function
*/
void Player::update()
{
}
/**
<Insert obvious comment here>
*/
void Player::draw()
{
glBegin(GL_QUADS);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 1.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
glEnd();
}
Reading through the functions should give you a general idea of what each one does, most of them being simple one line return statements. The only change is within the draw function in which I have added code to test whether OpenGL is working correctly. If the draw function gets called, a big white box should be drawn, filling to top right area of the window. If this behavior is confusing, I recommend reading about the OpenGL co-ordinate system. For the OpenGL code to work, GL/gl.h had to be included at the top. This file might be in a different location on your system!
For now, this is our complete starting point for the Player object. We will add it to Main.cpp and set it up for use.
Main.cpp Changes
First change we are going to make to Main.cpp is the inclusion of Player.h so that we can access the new class we have made. Just add the following to the list of the includes at the top:
#include "Player.h"
Then we can create a new object of type Player as a global variable for use throughout the game loop.
Player Player1;
The next step is to call the player1 functions update and draw. The update function should be called from the update function located in Main.cpp as follows:
Player1.update();
And then add the draw function call to the render function in Main.cpp:
Player1.draw();
These additions should be sufficient for now so save all source code files and open up the Makefile, ready to include Player.cpp into the compilation.
The whole source code in Main.cpp should now look something like this, the changes from this stage have been highlighted:
#include <iostream> #include <ctime> #include <GL/glfw.h> #include "Player.h" void render(); void update(); Player Player1; /** - sleep function - Cross platform sleep implementation */ void _sleep(double ms) { double st = clock(); if (ms <= 0) ms = 10; while (clock() < (st + ms)); } /** - main function - Program entry point */ int main(int argc, char** argv) { std::cout << "Loading Tank Game v1 (Noz3001.wordpress.com)" << std::endl; glfwInit(); // Create glfw window if (glfwOpenWindow(800, 600, 5, 6, 5, 0, 8, 0, GLFW_WINDOW) != GL_TRUE) std::cout << "Error creating window!" << std::endl; // Set window title glfwSetWindowTitle("Tank Game"); glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Start main game loop // This calls the functions which update objects and render them to screen while (true) { update(); render(); glfwSwapBuffers(); // Switch buffers (double buffering) _sleep(10); // Let a bit of CPU time for other processes } return 0; } /** - Render function - Used to draw objects to the screen. */ void render() { glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Colour to clear the scene glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // TODO: Draw stuff here! Player1.draw(); } /** - Update function - Updates objects. States, locations, etc */ void update() { // TODO: Update objects here Player1.update(); }
Makefile Changes
Not much needs to be changed in the Makefile, it should now look like this:
all:
g++ Main.cpp Player.cpp -o Game -lGL -lglfw
You should now be able to compile the changes with the
make
command and test them out. If you see the big white box, everything was successful!
In the next step, we will set up Box2D.


One Comment
Leave a CommentTrackbacks