Each entity has a unique ID-the encapsulation of the entity and entitymanager classes.

Source: Internet
Author: User

Why is a unique ID required?


It is good to have a unique ID. When transmitting data over the network, you must specify a player or operate a combat unit, all you need to do is transmit an int type ID. Each entity in the game is uniquely identified. This is the meaning of having an entity.

Entity class


We create an entity class that has a m_nid member and uses a static counter in the constructor to create a unique ID value for m_nid.
//////////////////////////////////////// /// // <Br/> // copyright (c) tiaotiao <br/> // filename: entity. h <br/> // Creator: tiaotiao <br/> // Date: 2010-1-14 <br/> // comment: provides a unique ID for the subclass, all entities that require IDs inherit this class <br/> // <br/> /////////////////////// //////////////////////////////////////// <br/> class centity <br/> {<br/> public: <br/> centity (void) <br/>{< br/> static int s_ncount = 1; <br/ > M_nid = s_ncount ++; <br/>}< br/> virtual ~ Centity (void) {}< br/> Public: <br/> int ID () {return m_nid ;}< br/> protected: <br/> int m_nid; <br/>}; <br/>

You don't have to worry that the id value will exceed the int limit. If you do have some concerns, You can reset it to 1 when it reaches 2*10 ^ 9. Although this is still not rigorous, it is possible that in a new round of counting, the entity with a smaller ID is not destroyed, and there may be conflicts. We don't think this will happen here. If you need to create a magnificent project, you need to consider it separately.

With a unique ID, how do I find the corresponding object?


The server receives a command from the network, and the combat unit whose ID is a value must move forward. In this case, you need to find the corresponding instance by ID. This requirement can be easily implemented using map in STL.

Entitymanager class


Here we encapsulate it as the entitymanager class. The entitymanager class saves a map and provides the getentitybyid method. Here, I also deliver the new and delete responsibilities of the entity instance to the entitymanager because entitymanager can remove the ing in the map when the entity is created and destroyed, in this way, you do not have to worry that the deleted instance pointer can still be found in entitymanager.

//////////////////////////////////////// /// // <Br/> // Copyright (c) tiaotiao <br/> // FileName: EntityManager. h <br/> // Creator: Tiaotiao <br/> // Date: 2010-1-14 <br/> // Comment: Manages Entity instances, provide external methods for creating and destroying and searching for Entity <br/> ///////////////////// //////////////////////////////////////// // <br/> # include <map> <br/> # include "Entity. h "<br/> class CEntityManager <br/>{< br/> pu Blic: <br/> CEntityManager (void); <br/> virtual ~ CEntityManager (void); <br/> public: <br/> // create an Entity instance <br/> virtual CEntity * New () = 0; <br/> // destroy an Entity instance <br/> void Delete (CEntity * pkEntity); <br/> // search for the Entity pointer by ID, NULL is returned. <br/> CEntity * GetEntityByID (int nID); <br/> protected: <br/> // After subclass New object, add the object to the map <br/> CEntity * AddEntity (CEntity * pkEntity); <br/> protected: <br/> std: map <int, CEntity *> m_mapEntitys; <br/> };

// EntityManager. cpp <br/> # include "EntityManager. h "<br/> using namespace std; <br/> CEntityManager: CEntityManager (void) <br/>: m_mapEntitys () <br/>{< br/>}< br/> CEntityManager ::~ CEntityManager (void) <br/>{< br/>}< br/> void CEntityManager: Delete (CEntity * pkEntity) <br/>{< br/> int id = pkEntity-> ID (); <br/> m_mapEntitys.erase (m_mapEntitys.find (id); <br/> delete pkEntity; <br/>}< br/> CEntity * CEntityManager: GetEntityByID (int nID) <br/>{< br/> if (m_mapEntitys.find (nID )! = M_mapEntitys.end () <br/>{< br/> return m_mapEntitys [nID]; <br/>}< br/> return NULL; <br/>}< br/> CEntity * CEntityManager: AddEntity (CEntity * pkEntity) <br/>{< br/> int id = pkEntity-> ID (); <br/> m_mapEntitys [id] = pkEntity; <br/> return pkEntity; <br/>}

Supporting use


The following example shows how to use these two classes.

Here we create a simplified combat unit class unit, which inherits from entity and unitmanager inherits from entitymanager.

// Unit. h <br/> # include "entity. H "<br/> class cunit: <br/> Public centity <br/>{< br/> Public: <br/> cunit (void ); <br/> cunit (INT nunittype); <br/> virtual ~ Cunit (void); <br/> Public: <br/> int unittype () const {return m_nunittype ;}< br/> void unittype (INT Val) {m_nunittype = Val ;}< br/> Public: <br/> int X; <br/> int y; <br/> PRIVATE: <br/> int m_nunittype; <br/>}; <br/>

// Unit. CPP <br/> cunit: cunit (void): <br/> x (0), y (0), m_nunittype (0) <br/>{< br/>}< br/> cunit: cunit (INT nunittype): <br/> x (0), y (0 ), m_nunittype (0) <br/>{< br/>}< br/> cunit ::~ Cunit (void) <br/>{< br/>}< br/>

Note that this unit class has an overloaded constructor. When writing a unit class, the parent class entity does not have any restrictions on it, but inherits an ID of the parent class. All you need to do is focus on the logic of the Unit itself. The unit class CPP file does not do anything, but simply initializes the variable in the constructor.

# Include "entitymanager. H "<br/> # include" unit. H "<br/> class cunitmanager: <br/> Public centitymanager <br/>{< br/> Public: <br/> cunitmanager (void ); <br/> virtual ~ Cunitmanager (void); <br/> Public: <br/> virtual cunit * New (); <br/> cunit * New (INT nunittype ); <br/> cunit * getunitbyid (int nid); <br/>}; <br/>

// UnitManager. cpp <br/> # include "UnitManager. h "<br/> CUnitManager: CUnitManager (void) <br/>{< br/>}< br/> CUnitManager ::~ CUnitManager (void) <br/>{< br/>}< br/> CUnit * CUnitManager: New () <br/>{< br/> CUnit * pUnit = new CUnit (); <br/> AddEntity (pUnit); <br/> return pUnit; <br/>}< br/> CUnit * CUnitManager: New (int nUnitType) <br/>{< br/> CUnit * pUnit = new CUnit (nUnitType ); <br/> AddEntity (pUnit); <br/> return pUnit; <br/>}< br/> CUnit * CUnitManager: GetUnitByID (int nID) <br/>{< br/> return (CUnit *) GetEntityByID (nID); <br/>}

The point is that unitmanager needs to do something.
The first is to implement the pure virtual function centity * New () of the parent class and change the return value to cunit *. Do not forget to call addentity after the new statement to add it to the map ing.
The second thing is to provide a getunitbyid method. Although the parent class has provided the getentitybyid method to meet the requirements, the purpose of this method is only to implement type conversion and make the semantics clearer.
In addition, the last thing is that if the unit class provides other overloaded constructors, there must be a corresponding new method in unitmanager.

Although the following two points are not mandatory, doing so will make the unitmanager class easier to use.
When writing the entitymanager subclass, remember to do these three things.

Summary


This is a simple encapsulation but practical. This structure is widely used in my recently written projects, making it easy to find and manage instances.

Finally, pay attention to the following principles:
1. You can only create a unit instance using the new method of unitmanager.
2. Whoever calls the new method to obtain the unit instance is responsible for calling the delete method of unitmanager to destroy it.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.