feat(game_core): 重构游戏引擎并添加新功能
- 重构了游戏引擎的核心逻辑和架构 - 添加了新的实体组件系统(ECS) - 实现了简单的碰撞检测和响应 - 新增了地图和子弹功能 - 优化了输入处理和渲染逻辑 - 调整了游戏控制方式
This commit is contained in:
123
game_core/main.c
123
game_core/main.c
@@ -1,64 +1,54 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "config.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"
|
||||
FILE* fp;
|
||||
logger_t logger;
|
||||
|
||||
static void log_handler
|
||||
(log_level_t level, const char* module, const char* file, int line, const char* message) {
|
||||
fprintf(fp, "[%s] %s:%d | %s: %s\n",
|
||||
pynic_level_str(level), file, line, module, message);
|
||||
fflush(fp);
|
||||
}
|
||||
|
||||
#define MAX_BULLET 16
|
||||
#define BASIC_SPEED (1 << GE_PHYSICS_VELOCITY_BIT)
|
||||
#include "entities/entities.h"
|
||||
|
||||
typedef struct {
|
||||
int score;
|
||||
ge_entity_t* player;
|
||||
ge_entity_t* bullet[MAX_BULLET];
|
||||
ge_entity_t* bullets[MAX_BULLET];
|
||||
ge_render_rect_t screen;
|
||||
ge_entity_t* tilemap;
|
||||
} game_ctx_t;
|
||||
|
||||
void collision_response(
|
||||
void* _ctx,
|
||||
ge_entity_t* entity_from,
|
||||
ge_entity_t* entity_to,
|
||||
const ge_vector2i_t* vector // 反向推荐速度
|
||||
) {
|
||||
game_ctx_t* ctx = _ctx;
|
||||
(void) ctx;
|
||||
(void) entity_to;
|
||||
// For box to box collision
|
||||
if (vector == NULL) return;
|
||||
|
||||
switch (entity_from->user_type) {
|
||||
case PLAYER:
|
||||
case ENEMY:
|
||||
entity_from->position = vec2i_add(entity_from->position, *vector);
|
||||
break;
|
||||
case BULLET:
|
||||
entity_from->component_mask &= ~GE_COMPONENT_ACVIVE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void init(ge_core_t* core) {
|
||||
(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,
|
||||
}
|
||||
};
|
||||
core->_systems.collision.ctx = &ctx;
|
||||
core->_systems.collision.callback = collision_response;
|
||||
|
||||
init_tilemap(&core->ecs, &ctx.tilemap);
|
||||
init_player(&core->ecs, &ctx.player);
|
||||
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},
|
||||
};
|
||||
init_bullet(&core->ecs, &ctx.bullets[i]);
|
||||
}
|
||||
|
||||
ctx.screen = (ge_render_rect_t) {
|
||||
@@ -71,33 +61,40 @@ void init(ge_core_t* core) {
|
||||
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;
|
||||
ge_vector2i_t* player_pos = &ctx->player->position;
|
||||
ge_vector2i_t* player_vec = &ctx->player->physics_body.velocity;
|
||||
player_vec->x = 0;
|
||||
player_vec->y = 0;
|
||||
|
||||
core->_render.func_draw_text(&core->_render, &ctx->screen, "Press 'p' to exit", player_pos, GE_COLOR_BLACK);
|
||||
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);
|
||||
case KEY_UP:
|
||||
MLOG_INFO(&logger, "KEY_UP");
|
||||
player_vec->y = - BASIC_SPEED;
|
||||
break;
|
||||
case 'a':
|
||||
MLOG_INFO(&logger, "a");
|
||||
*pos = vec2i_add(*pos, GE_VEC2I_LEFT);
|
||||
case KEY_DOWN:
|
||||
MLOG_INFO(&logger, "KEY_DOWN");
|
||||
player_vec->y = BASIC_SPEED;
|
||||
break;
|
||||
case 's':
|
||||
MLOG_INFO(&logger, "s");
|
||||
*pos = vec2i_add(*pos, GE_VEC2I_DOWN);
|
||||
case KEY_LEFT:
|
||||
MLOG_INFO(&logger, "KEY_LEFT");
|
||||
player_vec->x = - BASIC_SPEED;
|
||||
break;
|
||||
case 'd':
|
||||
MLOG_INFO(&logger, "d");
|
||||
*pos = vec2i_add(*pos, GE_VEC2I_RIGHT);
|
||||
case KEY_RIGHT:
|
||||
MLOG_INFO(&logger, "KEY_RIGHT");
|
||||
player_vec->x = BASIC_SPEED;
|
||||
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
|
||||
case KEY_ATTACK:
|
||||
ge_entity_t* bullet = ctx->bullets[0];
|
||||
bullet->component_mask |= GE_COMPONENT_ACVIVE;
|
||||
bullet->position.x = player_pos->x + 4; // TODO
|
||||
bullet->position.y = player_pos->y; // TODO
|
||||
bullet->physics_body.velocity.x = 0;
|
||||
bullet->physics_body.velocity.y = - BASIC_SPEED / 2;
|
||||
break;
|
||||
case 'q':
|
||||
case KEY_EXIT:
|
||||
core->state = GE_ENGINE_STATE_EXIT;
|
||||
MLOG_INFO(&logger, "exit");
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user