Class 3:实体管理——EntityManager

Class 3:实体管理——EntityManager文章介绍了在 Class3 中新增的实体管理模块 EntityManage 它负责处理游戏中的实体对象

大家好,欢迎来到IT知识分享网。

目录

Class 3:实体管理——EntityManager

原文件改动

新文件知识点

程序构建

主程序——main.c

共用配置头文件——Config.h

单例头文件——GameFunction.h

单例源文件——GameFunction.c

实体头文件——Entity.h

实体源文件——Entity.c

实体管理头文件——EntityManager.h

实体管理头源文件——EntityManager.c


Class 3:实体管理——EntityManager

原文件改动

相较于Class2,Class3新增实体管理部分

  1. Config.h用宏定义实现一个foreach循环,来快捷遍历数组
  2. GameFunction.c新增头文件EntityManager.h
  3. GameFunction.cinit()改动新增EntityManager* em = GetEntityManager();
  4. player1 = GetEntity();变为player1 = em->addEntity(GetEntity());
  5. GameFunction.cclean() 中的Cast(player1)->clean();改为GetEntityManager()->clean();
  6. GameFunction.cupdate() 中的Cast(player1)->update();改为GetEntityManager()->update();
  7. GameFunction.crender() 中的Cast(player1)->render();改为GetEntityManager()->render();
  8. Entity.c中的update()取消输出

新文件知识点

  1. define定义多行函数
    //定义常量 #define MAX_VALUE 100       //定义整型变量MAX_VALUE值为100 #define USER_NAME "huge"   //定义字符串变量USER_NAME值为"huge" #define PI 3.       //定义浮点数变量PI值为3. ​ //定义简单函数 #define MAX(a,b) (a>b)?a:b //取两个数最大值 #define MIN(a,b) (a<b)?a:b //取两个数最小值 ​ //定义复杂多行的函数 #define   MACRO(arg1,   arg2)   do   {   \   \ stmt1;   \ stmt2;   \   \ }   while(0) 关键是要在每一个换行的时候加上一个 "\ "

程序构建

主程序——main.c

#include <stdio.h> #include "GameFuntion.h" ​ int main(int argc,char *argv[]) {   float frameRate = 1000.0/24;   //帧率   uint32_t startTime = 0;   uint32_t frameTime = 0; ​   GameFuntion* game = GameInstance();   game->init("SDL",640,480);   while(game->running())   {       startTime = SDL_GetTicks();       game->update();       game->render();       game->handleEvents(); ​       frameTime = SDL_GetTicks() - startTime;       if(frameRate - frameTime > 0)       {           SDL_Delay(frameRate - frameTime);       }   }   game->clean();   return 0; }

共用配置头文件——Config.h

#ifndef CONFIGER_H_ #define CONFIGER_H_ ​ #include <stdbool.h> #include "SDL.h" #pragma comment(lib,"SDL2.lib") #pragma comment(lib,"SDLmain.lib") ​ #define foreach(val,arr)   \ for (size_t i = 0,ctr = 0;i<sizeof(arr)/sizeof(arr[0]);i++,ctr = 0)\   for(val = arr[i];ctr < 1;++ctr) #endif ​ ​ /*【示例】高难度:用宏定义实现一个foreach循环,来快捷遍历数组 #include <stdio.h> #define foreach(val,arr)   \ for (size_t i = 0,ctr = 0;i<sizeof(arr)/sizeof(arr[0]);i++,ctr = 0)\   for(val = arr[i];ctr < 1;++ctr) int main() {   int arr[10] = {1,2,3,4,5,6,7,8,9,10};   foreach(int a,arr)   {       printf("%d",a);   }   char* str[] = {"hello","world"};   foreach(char* val,str)   {       puts(val);   }   return 0; } #*/

单例头文件——GameFunction.h

#ifndef GAMEFUNTION_H_ #define GAMEFUNTION_H_ ​ #include "Config.h" ​ typedef struct GameFuntion {   SDL_Window* window;   SDL_Renderer* renderer;   SDL_Event events;   bool isRunning;   //声明函数指针   //返回值类型 (*指针变量名) (形参列表)   bool (*init)(const char* title,int w,int h);   void (*clean)();   void (*update)();   void (*render)();   void (*handleEvents)();   bool (*running)();   void (*quit)(); }GameFuntion; GameFuntion* GameInstance(); ​ #endif 

单例源文件——GameFunction.c

#include "GameFuntion.h" #include "Entity.h" #include "EntityManager.h" static bool init(const char* title,int w,int h); static void clean(); static void update(); static void render(); static void handleEvents(); static bool running(); static void quit(); static GameFuntion* pthis = NULL; ​ GameFuntion* GameInstance() {   static GameFuntion game;   if (!pthis)   {       pthis = &game;       pthis->init = init;       pthis->clean = clean;       pthis->update = update;       pthis->render = render;       pthis->handleEvents = handleEvents;       pthis->running = running;       pthis->quit = quit;   }       return pthis; } Entity* player1; Entity* player2; bool init(const char* title,int w,int h) {   if(SDL_Init(SDL_INIT_EVERYTHING) == 0)   {       SDL_Log("SDL Init");       pthis->window = SDL_CreateWindow(title,SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,w,h,SDL_WINDOW_SHOWN);       if (pthis->window)       {           SDL_Log("Window Created");       }       pthis->renderer = SDL_CreateRenderer(pthis->window,-1,0);       if(pthis->renderer)       {           SDL_Log("Renderer Created");       }       pthis->isRunning = true;   }   else   {       pthis->isRunning = false;   }   EntityManager* em = GetEntityManager(); //新增   player1 = em->addEntity(GetEntity()); //改动,原:player1 = GetEntity();   player2 = em->addEntity(GetEntity());   return pthis->isRunning; } void clean() { GetEntityManager()->clean(); //新增   //Cast(player1)->clean();   //Cast(player2)->clean();   SDL_DestroyRenderer(pthis->renderer);   SDL_DestroyWindow(pthis->window);   SDL_Quit();   SDL_Log("SDL Clean"); } int cnt = 0; void update() {   cnt++;   GetEntityManager()->update();   //Cast(player1)->update();   //Cast(player2)->update(); } void render() {   //SDL_Log("cnt:%d",cnt);   GetEntityManager()->render();   //Cast(player1)->render();   //Cast(player2)->render(); } void handleEvents() {   if(SDL_PollEvent(&pthis->events))   {       if(pthis->events.type == SDL_QUIT)       {           quit();       }   } } bool running(){return pthis->isRunning;} static void quit(){pthis->isRunning = false;}

实体头文件——Entity.h

#ifndef ENTITY_H_ #define ENTITY_H_ #include "Config.h" typedef struct Entity {   bool (*init)();   void (*clean)();   void (*update)();   void (*render)(); ​ }Entity; Entity* GetEntity(); Entity* entity_cast(Entity* e); #define Cast(e) entity_cast(e) #endif

实体源文件——Entity.c

#include "Config.h" #include "Entity.h" static bool init(); static void clean(); static void update(); static void render(); ​ static Entity* pthis = NULL; Entity* GetEntity() {   Entity* ins = SDL_calloc(1,sizeof(Entity));   SDL_assert(ins != NULL);   pthis = ins;   pthis->init = init;   pthis->clean = clean;   pthis->update = update;   pthis->render = render;   return pthis; } Entity* entity_cast(Entity* e) {   pthis = e;   return e; } bool init() {       return true; } void clean() {   SDL_Log("%s",__FUNCTION__); } void update() {   //SDL_Log("%s,%p",__FUNCTION__,pthis); } void render() {   // SDL_Log("%s",__FUNCTION__); }

实体管理头文件——EntityManager.h

#ifndef ENTITYMANAGER_H_ #define ENTITYMANAGER_H_ #include "Config.h" ​ typedef struct Entity Entity; ​ typedef struct EntityManager {   Entity Entities;   //实体指针数组   int capacity; //容量   int size;   Entity* (*addEntity)(Entity* e); //添加实体   void (*removeEntity)(Entity* e); //移除实体   bool (*init)();   void (*clean)();   void (*update)();   void (*render)(); }EntityManager; EntityManager* GetEntityManager(); ​ #endif

实体管理头源文件——EntityManager.c

#include "EntityManager.h" #include "Entity.h" #define foreach_Manager(val,arr) \ for (size_t i = 0,ctr = 0;i<arr->size;i++,ctr = 0)\ for(val = arr->Entities[i];ctr < 1;++ctr) static Entity* addEntity(Entity* e); static void removeEntity(Entity* e); static bool init(); static void clean(); static void update(); static void render(); static EntityManager* pthis = NULL; EntityManager* GetEntityManager() { static EntityManager em; if(!pthis) { pthis = &em; pthis->addEntity = addEntity; pthis->removeEntity = removeEntity; pthis->init = init; pthis->clean = clean; pthis->update = update; pthis->render = render; pthis->init(); } return pthis; } Entity* addEntity(Entity* e) { pthis->Entities[pthis->size++] = e; return e; } void removeEntity(Entity* e) { for(int i = 0;i<pthis->size;i++) { Entity* en = pthis->Entities[i]; if(en == e) { e->clean(); SDL_free(e); for(int pos = i;pos < pthis->size-1;pos++) { pthis->Entities[i] = pthis->Entities[i+1]; } pthis->size--; break; } } } bool init() { pthis->capacity = 8; pthis->size = 0; pthis->Entities = SDL_calloc(pthis->capacity,sizeof(Entity*)); SDL_assert(pthis->Entities!=0); //断言 } void clean() { foreach_Manager(Entity* e,pthis) //遍历 { Cast(e)->clean(); } } void update() { foreach_Manager(Entity* e,pthis) { Cast(e)->update(); } } void render() { foreach_Manager(Entity* e,pthis) { Cast(e)->render(); } }

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/126229.html

(0)
上一篇 2025-09-20 16:26
下一篇 2025-09-20 16:45

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信