Class 3:实体管理——EntityManager

目录

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.1415926        //定义浮点数变量PI值为3.1415926
    ​
    //定义简单函数
    #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();
   }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值