大家好,欢迎来到IT知识分享网。
目录
Class 3:实体管理——EntityManager
原文件改动
相较于Class2,Class3新增实体管理部分
- Config.h用宏定义实现一个foreach循环,来快捷遍历数组
- GameFunction.c新增头文件EntityManager.h
- GameFunction.c中init()改动新增EntityManager* em = GetEntityManager();
- player1 = GetEntity();变为player1 = em->addEntity(GetEntity());
- GameFunction.c中clean() 中的Cast(player1)->clean();改为GetEntityManager()->clean();
- GameFunction.c中update() 中的Cast(player1)->update();改为GetEntityManager()->update();
- GameFunction.c中render() 中的Cast(player1)->render();改为GetEntityManager()->render();
- Entity.c中的update()取消输出
新文件知识点
- 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