feat(engine): 重构游戏引擎核心逻辑

- 重新设计了引擎的初始化和运行流程
- 引入了实体组件系统(ECS)和物理系统
- 优化了渲染系统和输入系统
- 移除了不必要的资源管理系统
- 调整了日志系统的实现
This commit is contained in:
ZZY
2025-06-29 18:46:36 +08:00
parent 5ce660e3a6
commit 89bede93a9
37 changed files with 1294 additions and 350 deletions

View File

@@ -1,12 +1,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "ge_color.h"
#define GE_VEC2I_USE_SHORT_NAMES
#define _pynic_logout_printf(...) fprintf(fp , ##__VA_ARGS__)
#include <ge_core.h>
#include "plantform/win_term/interface.h"
// #include "plantform/win_term/interface.h"
FILE* fp;
logger_t logger;
@@ -17,56 +18,96 @@ static void log_handler
fflush(fp);
}
#define MAX_BULLET 16
#define BASIC_SPEED (1 << GE_PHYSICS_VELOCITY_BIT)
typedef struct {
ge_entity_t* player;
ge_entity_t* bullet[MAX_BULLET];
ge_render_rect_t screen;
} game_ctx_t;
void init(ge_core_t* core) {
register_win_term(core);
register_win_timer(core);
fp = fopen("./log.txt", "w+");
(void)core;
fp = fopen("D:\\Git_Code\\school_stm32\\game_core\\log.txt", "w+");
init_logger_ex(&logger, "game", log_handler);
Assert(fp != NULL);
static game_ctx_t ctx = { 0 };
ge_ecs_add_entity(&core->ecs, &ctx.player);
ctx.player->component_mask = GE_COMPONENT_ACVIVE | GE_RENDERABLE_MASK;
ctx.player->position = (ge_vector2i_t){ 32, 32 };
ctx.player->renderable = (ge_render_component_t) {
.type = GE_RENDER_COMPONENT_TYPE_RECT,
.data.rect = {
.size = {8, 8},
.color = GE_COLOR_YELLOW,
}
};
for (int i = 0; i < MAX_BULLET; ++i) {
ge_ecs_add_entity(&core->ecs, &ctx.bullet[i]);
ctx.bullet[i]->component_mask = GE_RENDERABLE_MASK | GE_PHYSICS_MASK;
ctx.bullet[i]->renderable = (ge_render_component_t) {
.type = GE_RENDER_COMPONENT_TYPE_RECT,
.data.rect = {
.size = {2, 2},
.color = GE_COLOR_RED,
}
};
ctx.bullet[i]->physics_body = (ge_physics_component_t) {
.type = GE_PHYSICS_COMPONENT_TYPE_VELOCITY,
.velocity = { 0, - BASIC_SPEED / 2},
};
}
ctx.screen = (ge_render_rect_t) {
.pos = {0, 0},
.size = core->_render.screen_size,
};
core->context = &ctx;
}
void run(ge_core_t* core) {
static ge_vector2i_t pos = vec2i(0, 0);
// LOG_INFO("vec2: %d, %d", a.x, a.y);
void process(ge_core_t* core) {
game_ctx_t* ctx = (game_ctx_t*)core->context;
core->_render.func_draw_rect(&core->_render, &ctx->screen, GE_COLOR_WHITE);
ge_vector2i_t* pos = &ctx->player->position;
int key = terminal_get_key((win_term_t*)core->render.content);
switch (key) {
case 'w':
MLOG_INFO(&logger, "w");
core->render.clear(&core->render);
pos = vec2i_add(pos, GE_VEC2I_UP);
core->render.draw(&core->render, pos, "@");
break;
case 'a':
MLOG_INFO(&logger, "a");
core->render.clear(&core->render);
pos = vec2i_add(pos, GE_VEC2I_LEFT);
core->render.draw(&core->render, pos, "@");
break;
case 's':
MLOG_INFO(&logger, "s");
core->render.clear(&core->render);
pos = vec2i_add(pos, GE_VEC2I_DOWN);
core->render.draw(&core->render, pos, "@");
break;
case 'd':
MLOG_INFO(&logger, "d");
core->render.clear(&core->render);
pos = vec2i_add(pos, GE_VEC2I_RIGHT);
core->render.draw(&core->render, pos, "@");
break;
case 'q':
core->state = GE_ENGINE_STATE_EXIT;
MLOG_INFO(&logger, "exit");
break;
ge_input_event_t key;
if (!core->_input.func_recv(&core->_input, &key)) {
switch (key.num) {
case 'w':
MLOG_INFO(&logger, "w");
*pos = vec2i_add(*pos, GE_VEC2I_UP);
break;
case 'a':
MLOG_INFO(&logger, "a");
*pos = vec2i_add(*pos, GE_VEC2I_LEFT);
break;
case 's':
MLOG_INFO(&logger, "s");
*pos = vec2i_add(*pos, GE_VEC2I_DOWN);
break;
case 'd':
MLOG_INFO(&logger, "d");
*pos = vec2i_add(*pos, GE_VEC2I_RIGHT);
break;
case 'f':
ctx->bullet[0]->component_mask |= GE_COMPONENT_ACVIVE;
ctx->bullet[0]->position.x = pos->x + 4; // TODO
ctx->bullet[0]->position.y = pos->y; // TODO
break;
case 'q':
core->state = GE_ENGINE_STATE_EXIT;
MLOG_INFO(&logger, "exit");
break;
}
}
}
int main(void) {
ge_core_t core;
ge_engine_init(&core);
core.callbacks.init = init;
core.callbacks.run = run;
ge_engine_run(&core);
int ge_main(ge_core_t* core) {
core->callbacks.init = init;
core->callbacks.process = process;
ge_engine_run(core);
return 0;
}