官术网_书友最值得收藏!

The player's spaceship game object

Up to this point, we have been keeping all of the values that track our player's ship in global variables. From an organizational perspective, this is less than ideal. The first game object we will create will be the player's ship object. We will start with a basic class and add more object-oriented features to our code later.

Here is the code for our new header file, game.hpp:

#ifndef __GAME_H__
#define __GAME_H__
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <emscripten.h>
#include <stdio.h>
#include <stdbool.h>
#include <math.h>
#include <string>
#include <vector>

#define SPRITE_FILE "sprites/Franchise.png"
#define MAX_VELOCITY 2.0
#define PI 3.14159
#define TWO_PI 6.28318

extern Uint32 last_time;
extern Uint32 last_frame_time;
extern Uint32 current_time;
extern SDL_Window *window;
extern SDL_Renderer *renderer;
extern SDL_Rect dest;
extern SDL_Texture *sprite_texture;
extern SDL_Event event;
extern bool left_key_down;
extern bool right_key_down;
extern bool up_key_down;
extern bool down_key_down;
extern bool space_key_down;
extern float delta_time;
extern int diff_time;

class PlayerShip {
public:
float m_X;
float m_Y;
float m_Rotation;
float m_DX;
float m_DY;
float m_VX;
float m_VY;

PlayerShip();
void RotateLeft();
void RotateRight();
void Accelerate();
void Decelerate();
void CapVelocity();
void Move();
void Render();
};

extern PlayerShip player;
#endif

All of our CPP files will include this game.hpp header file. The first few lines of this file are to make sure we do not include this file more than once. We are then defining all of the global variables we had defined in our older C files:

extern Uint32 last_time;
extern Uint32 last_frame_time;
extern Uint32 current_time;
extern SDL_Window *window;
extern SDL_Renderer *renderer;
extern SDL_Rect dest;
extern SDL_Texture *sprite_texture;
extern SDL_Event event;
extern bool left_key_down;
extern bool right_key_down;
extern bool up_key_down;
extern bool down_key_down;
extern float delta_time;

In the header file, we are not allocating space on to the heap. The use of the extern keyword before our global variable definitions tells the compiler that we declared the global variable in one of the .cpp files. Right now, we still have a lot of global variables. We will be reducing the number of these globals as we make modifications to our code in this chapter.

If this were production code, it would make sense to move all of these values into classes, but, for now, we are only creating a PlayerShip object. We also have our class definition for PlayerShip. Developers usually create class definitions inside header files.

After we define all of our global variables, we will need our class definition.

Here is the definition of our PlayerShip class:

class PlayerShip {
public:
float m_X;
float m_Y;
float m_Rotation;
float m_DX;
float m_DY;
float m_VX;
float m_VY;

PlayerShip();
void RotateLeft();
void RotateRight();
void Accelerate();
void Decelerate();
void CapVelocity();
void Move();
void Render();
};

extern PlayerShip player;

In this book, we are going to declare all of our attributes public. That means our code can access them from anywhere, not just from inside this function. If you are working on a project with more than one developer, this is not usually considered to be a good practice. Preventing other classes from being able to directly modify some of our attributes such as m_DX and m_DY is a good idea if you do not want another developer to directly alter specific attributes that only functions in a class are meant to modify. For demonstration purposes, however, having everything in our class defined as public will simplify our design.

After we define our attributes, we have a series of functions that will be associated with this class once defined. The first function, PlayerShip()has the same name as our class, which makes it the constructor, that is, the function that is called by default when our app creates an object of the  PlayerShip type. If we wished, we could define a destructor function, which would run when the object was destroyed, by calling it ~PlayerShip(). We do not currently need a destructor for that object so we will not define it here, which means we will rely on C++ to create a default destructor for this class.

All of the other functions we have defined in this class correspond to functions we created in previous C versions of our game. Moving all of these functions to a class allows us to organize our code better. Notice that after our class definition, we created another global variable that is a PlayerShip called player. The compiler shares this player object in all of the .cpp files that include our game.hpp file.

主站蜘蛛池模板: 扎鲁特旗| 辉南县| 竹北市| 新田县| 郴州市| 南投县| 金门县| 连南| 昌江| 大安市| 桂平市| 平山县| 积石山| 汶上县| 综艺| 胶南市| 延安市| 乌兰察布市| 云阳县| 东宁县| 民县| 商水县| 威信县| 佳木斯市| 龙州县| 新邵县| 宜黄县| 滨海县| 桦甸市| 古浪县| 夹江县| 随州市| 本溪市| 体育| 东莞市| 舞钢市| 中宁县| 湘乡市| 墨脱县| 临沭县| 高尔夫|