Design of the role in the game (C language description)
Recently I was writing an RPG Game. I used my spare time to design a role module and share it with my friends who love the game. The code is divided into three parts: 1. abstract role class, 2. the role class controlled by the player. this game uses the hge 2D engine code:
I. Abstract role categories:
FGRoleObject. h file:
Class FGRoleObject {public:
Static void Init (HGE * m_hge) {hge = m_hge ;}
// Logic virtual void Logic () = 0;
// Draw virtual void Render () = 0;
// Obtain the X coordinate float GetX () {return m_x ;}
// Obtain the Y coordinate float GetY () {return m_y ;}
// Obtain the ID int GetID () {return m_ID ;}
// Get the name char * GetName () {return m_Name ;}
// Obtain the int GetLevel () {return m_Level ;}
// Obtain HP float GetHp () {return m_Hp ;}
// Obtain MaxHp float GetMaxHp () {return m_MaxHp ;}
// Obtain Ep float GetEp () {return m_Ep ;}
// Obtain MaxEp float GetMaxEp () {return m_MaxEp ;}
// Obtain CP float GetCp () {return m_CP ;}
// Obtain MaxCp float GetMaxCp () {return m_MaxCp;} // obtain STR float GetSTR () {return m_STR ;}
// Obtain DEF float GetDEF () {return m_DEF ;}
// Obtain ATS float GetATS () {return m_ATS ;}
// Obtain ATF float GetADF () {return m_ADF ;}
// Obtain SPD float GetSPD () {return m_SPD ;}
// Obtain DEX float GetDEX () {return m_DEX ;}
// Obtain ADL float GetAGL () {return m_AGL ;}
// Get MOV float GetMOV () {return m_MOV ;}
// Obtain RNG float GetRNG () {return m_RNG ;}
// Obtain EXP float GetEXP () {return m_Exp ;}
// Obtain MaxExp float GetMaxExp () {return m_MaxExp ;}
// Obtain the camp type TYPE_Camp GetCamp () {return m_Camp ;}
// Set the collision region range void SetRect (float ltx, float lty, float rdx, float rdy) {m_rect.Set (ltx, lty, rdx, rdy );}
// Bool Intersect (FGRoleObject & role) {if (m_rect.Intersect (& role. m_rect) {return true;} else {return false ;}}
// Set the void SetAttribute (int _ level, float _ MaxHp, float _ Hp, float _ MaxEp, float _ Ep, float _ STR, float _ DEF, float _ ATS, float _ ADF, float _ SPD, float _ DEX, float _ AGL, float _ MOV, float _ RNG, float _ MaxCp, float _ CP, float _ MaxExp, float _ Exp, float _ NextExp); // set the status void SetMode (AtionMode _ mode) {m_ationmode = _ mode;} protected: // 1. 2. camp ID 3. role name 4. role X coordinate 5. role Y coordinate FGRoleObject (short _ id, TYPE_Camp _ camp, const char * _ name, float _ x, float _ y );
// Analyze virtual ~ FGRoleObject (void );
Static HGE * hge;
// Monetary static float Mria;
// Game time static float PlayTime;
// The type of the camp TYPE_Camp m_Camp;
// Char m_Name [256];
// Number short m_ID;
// Role x coordinate float m_x;
// Role y coordinate float m_y;
// Collision region object hgeRect m_rect;
// Speed float m_speed;
// Role attribute int m_Level;
Float m_MaxHp;
Float m_Hp;
Float m_MaxEp;
Float m_Ep;
Float m_STR; float m_DEF;
Float m_ATS; float m_ADF; float m_SPD; float m_DEX; float m_AGL; float m_MOV;
Float m_RNG;
Float m_MaxCp;
Float m_CP;
Float m_MaxExp;
Float m_Exp;
Float m_NextExp;
// Drection m_drection;
// Role status AtionMode m_ationmode ;};
FGRoleObject. cpp file:
# Include "FGRoleObject. h"
HGE * FGRoleObject: hge = 0;
FGRoleObject ::~ FGRoleObject (void ){
}
FGRoleObject: FGRoleObject (short _ id, TYPE_Camp _ camp, const char * _ name, float _ x, float _ y) {m_ID = _ id;
// Assign a value to the camp-we are still the enemy m_Camp = _ camp;
Strcpy (m_Name, _ name );
M_x = _ x;
M_y = _ y;
SetMode (WAIT );
// The collision area is not set during initialization, And the collision is 0 m_rect.Set );}
Void FGRoleObject: SetAttribute (int _ level, float _ MaxHp, float _ Hp, float _ MaxEp, float _ Ep, float _ STR, float _ DEF, float _ ATS, float _ ADF, float _ SPD, float _ DEX, float _ AGL, float _ MOV, float _ RNG, float _ MaxCp, float _ CP, float _ MaxExp, float _ Exp, float _ NextExp) {m_Level = _ level;
M_MaxHp = _ MaxHp;
M_Hp = _ Hp;
M_MaxEp = _ MaxEp;
M_Ep = _ Ep;
M_STR = _ STR; m_DEF = _ DEF;
M_ATS = _ ATS; m_ADF = _ ADF; m_SPD = _ SPD; m_DEX = _ DEX; m_AGL = _ AGL; m_MOV = _ MOV;
M_RNG = _ RNG;
M_MaxCp = _ MaxCp;
M_CP = _ CP;
M_MaxExp = _ MaxExp;
M_Exp = _ Exp;
M_NextExp = _ NextExp ;}
FGMyRole. h file:
Class FGMyRole: public FGRoleObject {public: // parameters of the base class: 1. 2. camp ID 3. role name 4. role X coordinate 5. role Y coordinate // parameters required for the hgeAnimation class: 6. x coordinate in the texture 7. y coordinate in the texture 8. 9. The width of each frame in the texture. height of each frame in the texture // 10. animation playback speed 11. the total number of frames for the animation is 12. texture required for animation // parameters of our role: 13. figure 14. role movement speed FGMyRole (short _ id, TYPE_Camp _ camp, char * _ name, float _ x, float _ y, float _ tx, float _ ty, float _ tw, float _ th, float _ fps, int _ nframe, HTEXTURE _ tex, short _ h_Index, float m _ Speed); virtual ~ FGMyRole (void); void Logic ();
Void Render ();
Short getheatri_uiindex () {return heatri_uiindex ;}
// Initialize the void InitEquips () of the equipment slot ();
// Array of the equipment bar-each game has five equipment slots, ItemObject * Equips [5].
Private: // role Avatar image index (UI) short hSpri_UIIndex;
// Animation object hgeAnimation * spr [8];
// Fps playback speed float FPS;
// Number of frames int Nframe;
// The X coordinate float tx in the texture;
// Float ty of Y coordinate in the texture;
// The long float tw in the texture;
// Float th in the texture ;};
FGMyRole. cpp file:
# Include "FGMyRole. h" # include "FGGameScreen. h"
FGMyRole: FGMyRole (short _ id, TYPE_Camp _ camp, char * _ name, float _ x, float _ y, float _ tx, float _ ty, float _ tw, float _ th, float _ fps, int _ nframe, HTEXTURE _ tex, short _ h_Index, float _ speed): FGRoleObject (_ id, _ camp, _ name, _ x, _ y) {SetAttribute (4,163,163,250,203, 46,500,100,250 );
M_speed = _ speed;
FPS = _ fps;
Nframe = _ nframe;
Tx = _ tx;
Ty = _ ty;
Tw = _ tw;
Th = _ th;
HSpri_UIIndex = _ h_Index;
For (int I = 0; I <8; I) {spr [I] = new hgeAnimation (_ tex, Nframe, FPS, tx, ty 128 * I, tw, th );
Spr [I]-> Play ();} m_drection = RIGHT; // initialize the role and equipment InitEquips ();}
FGMyRole ::~ FGMyRole (void) {for (int I = 7; I <0; I --) {if (spr [I]! = NULL) {delete spr [I];
Spr [I] = NULL ;}}}
Void FGMyRole: Logic () {// animation Update spr [m_drection]-> Update (hge-> Timer_GetDelta ());
// Status switch (m_ationmode) {case MOVE: // keyboard response if (hge-> Input_GetKeyState (HGEK_W) // {if (hge-> Input_GetKeyState (HGEK_D )) {m_y-= m_speed; m_x = m_speed; m_drection = RIGHTUP;
} Else if (hge-> Input_GetKeyState (HGEK_A) {m_y-= m_speed; m_x-= m_speed; m_drection = LEFTUP;} else if (hge-> Input_GetKeyState (HGEK_S )) {m_y = m_speed;
M_drection = DOWN;} else {m_y-= m_speed;
M_drection = UP ;}
Spr [m_drection]-> SetTexture (FGResMangner: mangner-> GetTexture ("role2-move1");} else if (hge-> Input_GetKeyState (HGEK_S )) // {if (hge-> Input_GetKeyState (HGEK_W) {m_y-= m_speed;
M_drection = UP;
} Else if (hge-> Input_GetKeyState (HGEK_D) {m_x = m_speed;
M_y = m_speed;
M_drection = RIGHTDOWN;} else if (hge-> Input_GetKeyState (HGEK_A) {m_x-= m_speed;
M_y = m_speed; m_drection = LEFTDOWN;} else {m_y = m_speed; m_drection = DOWN;} spr [m_drection]-> SetTexture (FGResMangner :: mangner-> GetTexture ("role2-move1");} else if (hge-> Input_GetKeyState (HGEK_D) // right {if (hge-> Input_GetKeyState (HGEK_W )) {m_x = m_speed;
M_y-= m_speed;
M_drection = RIGHTUP;} else if (hge-> Input_GetKeyState (HGEK_S) {m_x = m_speed;
M_y = m_speed;
M_drection = RIGHTDOWN;} else if (hge-> Input_GetKeyState (HGEK_A) {m_x-= m_speed;
M_drection = LEFT;} else {m_x = m_speed; m_drection = RIGHT;} spr [m_drection]-> SetTexture (FGResMangner: mangner-> GetTexture ("role2-move1 "));} else if (hge-> Input_GetKeyState (HGEK_A) // left {if (hge-> Input_GetKeyState (HGEK_W) {m_x-= m_speed;
M_y-= m_speed;
M_drection = LEFTUP;} else if (hge-> Input_GetKeyState (HGEK_D) {m_x = m_speed;
M_drection = RIGHT;} else if (hge-> Input_GetKeyState (HGEK_S) {m_x-= m_speed;
M_y = m_speed;
M_drection = LEFTDOWN;} else {m_x-= m_speed;
M_drection = LEFT;} spr [m_drection]-> SetTexture (FGResMangner: mangner-> GetTexture ("role2-move1 "));} else {// adjust the number of animation frames to 0 spr [m_drection]-> SetFrame (0); spr [m_drection]-> SetTexture (FGResMangner :: mangner-> GetTexture ("role2-waiting"); SetMode (WAIT);} if (hge-> Input_GetKeyState (HGEK_CTRL) {SetMode (ATTACT ); spr [m_drection]-> SetTexture (FGResMangner: mangner-> GetTexture ("role2-attact1"); spr [m_drection]-> SetSpeed (15 ); spr [m_drection]-> SetFrame (0);} break; case WAIT: // standby status // keyboard response if (hge-> Input_GetKeyState (HGEK_W )) // {if (hge-> Input_GetKeyState (HGEK_D) {m_drection = RIGHTUP;} else if (hge-> Input_GetKeyState (HGEK_A) {m_drection = LEFTUP ;} else if (hge-> Input_GetKeyState (HGEK_S) {m_drection = DOWN;} else {m_drection = UP;} spr [m_drection]-> SetTexture (FGResMangner :: mangner-> GetTexture ("role2-move1 "));
SetMode (MOVE);} else if (hge-> Input_GetKeyState (HGEK_S) // {if (hge-> Input_GetKeyState (HGEK_W) {m_drection = UP ;} else if (hge-> Input_GetKeyState (HGEK_D) {m_drection = RIGHTDOWN;} else if (hge-> Input_GetKeyState (HGEK_A) {m_drection = LEFTDOWN ;} else {m_drection = DOWN;} spr [m_drection]-> SetTexture (FGResMangner: mangner-> GetTexture ("role2-move1 "));
SetMode (MOVE);} else if (hge-> Input_GetKeyState (HGEK_D) // right {if (hge-> Input_GetKeyState (HGEK_W) {m_drection = RIGHTUP ;} else if (hge-> Input_GetKeyState (HGEK_S) {m_drection = RIGHTDOWN;} else if (hge-> Input_GetKeyState (HGEK_A) {m_drection = LEFT ;} else {m_drection = RIGHT;} spr [m_drection]-> SetTexture (FGResMangner: mangner-> GetTexture ("role2-move1 "));
SetMode (MOVE);} else if (hge-> Input_GetKeyState (HGEK_A) // left {if (hge-> Input_GetKeyState (HGEK_W) {m_drection = LEFTUP ;} else if (hge-> Input_GetKeyState (HGEK_D) {m_drection = RIGHT;} else if (hge-> Input_GetKeyState (HGEK_S) {m_drection = LEFTDOWN ;} else {m_drection = LEFT;} spr [m_drection]-> SetTexture (FGResMangner: mangner-> GetTexture ("role2-move1 "));
SetMode (MOVE);} if (hge-> Input_GetKeyState (HGEK_CTRL) {SetMode (ATTACT); spr [m_drection]-> SetTexture (FGResMangner :: mangner-> GetTexture ("role2-attact1"); spr [m_drection]-> SetSpeed (15); spr [m_drection]-> SetFrame (0 );}
Break; case ATTACT: // attack status if (spr [m_drection]-> GetFrame () = 7) {SetMode (WAIT); spr [m_drection]-> SetTexture (FGResMangner:: mangner-> GetTexture ("role2-waiting"); spr [m_drection]-> SetSpeed (5);} break; case BATTACT: // attacked status break; case DEATH: // dead break ;}
}
Void FGMyRole: Render () {spr [m_drection]-> Render (m_x, m_y );}
Void FGMyRole: InitEquips () {for (int I = 0; I <5; I) {Equips [I] = NULL ;}
Switch (m_ID) {case 0: // role 1 // weapon Equips [0] = new Weanpon (ItemObject: WEANPON, 0, 0, 0 ); // protection equipment Equips [1] = new Clothes (ItemObject: CLOTHES,); // shoes Equips [2] = new Clothes (ItemObject: CLOTHES, ); // jewelry Equips [3] = new Clothes (ItemObject: CLOTHES,); // jewelry Equips [4] = new Clothes (ItemObject: CLOTHES, ,); break; case 1: // role 2 Equips [0] = new Weanpon (ItemObject: WEANPON,); break ;}}
FGRoleManager. h file:
Class FGRoleManager {public: // management class object. This object has only one static FGRoleManager * mangner;
// The currently selected role object static FGRoleObject * CurRole;
// The role ID table is used to record the ID list of the total number of roles owned by the game player <short> listid;
List <short >:: iterator iterid;
~ FGRoleManager (void );
Static FGRoleManager * Instance (HGE * _ hge) {if (0 = mangner) {hge = _ hge;
FGRoleObject: Init (hge );
Return mangner = new FGRoleManager ();}
Return mangner ;}
Void Logic ();
Void Render ();
Void AddRole (FGRoleObject & _ object );
Void DeleteRole (FGRoleObject & _ object );
// Get role-Get FGRoleObject * GetRole (short ID) based on id );
// Cargo role id from the list short GetIDFromeList (short index );
// Obtain the number of people in our camp short GetMyRoleNums ();
// Obtain the number of enemy camp members short GetEnemyNums (); protected:
Private: list <FGRoleObject *> listobject;
List <FGRoleObject *>: iterator iterobject;
FGRoleManager (void );
Static HGE * hge ;};
FGRoleManager. cpp file:
HGE * FGRoleManager: hge = NULL;
FGRoleManager * FGRoleManager: mangner = NULL;
FGRoleObject * FGRoleManager: CurRole = NULL;
FGRoleManager: FGRoleManager (void ){
}
FGRoleManager ::~ FGRoleManager (void ){
} Void FGRoleManager: Logic () {// all roles run their own Logic for (iterobject = listobject. begin (); iterobject! = Listobject. end (); iterobject) {(* iterobject)-> Logic ();}}
Void FGRoleManager: Render () {// all roles run their own plotting for (iterobject = listobject. begin (); iterobject! = Listobject. end (); iterobject) {(* iterobject)-> Render ();}}
Void FGRoleManager: AddRole (FGRoleObject & _ object) {// Add the role object listobject. push_front (& _ object );
// Add the role id listid. push_back (& _ object)-> GetID ());
}
Void FGRoleManager: DeleteRole (FGRoleObject & _ object) {if (listobject. empty () return; listobject. remove (& _ object );}
Short FGRoleManager: GetMyRoleNums () {short temp = 0;
For (iterobject = listobject. begin (); iterobject! = Listobject. end (); iterobject) {if (* iterobject)-> GetCamp () = PLAYER) {temp ;}} return temp ;}
Short FGRoleManager: GetEnemyNums () {short temp = 0;
For (iterobject = listobject. begin (); iterobject! = Listobject. end (); iterobject) {if (* iterobject)-> GetCamp () = ENEMY) {temp ;}}
Return temp ;}
FGRoleObject * FGRoleManager: GetRole (short id) {for (iterobject = listobject. begin (); iterobject! = Listobject. end (); iterobject) {if (id = (* iterobject)-> GetID () {return * iterobject ;}}
Return NULL ;}
Short FGRoleManager: GetIDFromeList (short index) {int tempindex = 0;
For (iterid = listid. begin (); iterid! = Listid. end (); iterid) {if (tempindex = index) {return * iterid;} tempindex ;}
Return 0 ;}
This design uses inheritance and multiform. In the management class (FGRoleManager), there is a list of basic classes (FGRoleObjetct) to store subclass objects, and the list is used to manage subclass objects in a unified manner.
Below I will write down some of my design ideas:
Basic class FGRoleObject:
Class member:
Only the attributes of a game role can be written, such as hp mp x y (coordinates of the role ).
Note: In order to make this class more universal, what is universal? This class can be used in any game and can be used when writing any game. Because the engine used to make the game is different, the rendering processing will be different, therefore, the base class members can only write the attribute variables required by the entire game role.
Class member functions:
The common behaviors of game roles, such as collision processing and attribute setting, cannot be used.
Subclass FGMyRole:
Members in this class can add some specific variables of the role, which correspond to different resource objects according to different engine rendering and processing mechanisms, for example, if this class uses an animation object of hge to draw a role, you can add an animation object to the member. In addition, the role is equipped with a system, naturally, we need to add the data structure of the management equipment. Here we use an array of one weft.
FGRoleManager:
This class uses the list role base class pointer connection table to manage each object member method of the role. It mainly adds, deletes, and obtains a role by number. This type uses the single-piece mode. The entire game has only one role management object, and the second object management NPC is used to play, enemy, neutral, and other roles. These roles can all be added to the list table for unified management, such as unified rendering and unified logic. Because different types of objects exist in the connection table, there must be a type of identifier, this class uses an enum type to enumerate. Currently, only the camp type and the enemy camp type are written back to neutral types, such as npc. With this type identifier, you can easily obtain various role objects.
From the game sky