Files
school_stm32/game_core/main.c
ZZY b5b2c90e75 feat(game_core): 重构游戏引擎并添加新功能
- 重构了游戏引擎的核心逻辑和架构
- 添加了新的实体组件系统(ECS)
- 实现了简单的碰撞检测和响应
- 新增了地图和子弹功能
- 优化了输入处理和渲染逻辑
- 调整了游戏控制方式
2025-07-02 12:14:57 +08:00

111 lines
3.2 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "config.h"
#include "ge_color.h"
#include "entities/entities.h"
typedef struct {
int score;
ge_entity_t* player;
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;
static game_ctx_t ctx = { 0 };
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) {
init_bullet(&core->ecs, &ctx.bullets[i]);
}
ctx.screen = (ge_render_rect_t) {
.pos = {0, 0},
.size = core->_render.screen_size,
};
core->context = &ctx;
}
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* 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 KEY_UP:
MLOG_INFO(&logger, "KEY_UP");
player_vec->y = - BASIC_SPEED;
break;
case KEY_DOWN:
MLOG_INFO(&logger, "KEY_DOWN");
player_vec->y = BASIC_SPEED;
break;
case KEY_LEFT:
MLOG_INFO(&logger, "KEY_LEFT");
player_vec->x = - BASIC_SPEED;
break;
case KEY_RIGHT:
MLOG_INFO(&logger, "KEY_RIGHT");
player_vec->x = BASIC_SPEED;
break;
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 KEY_EXIT:
core->state = GE_ENGINE_STATE_EXIT;
MLOG_INFO(&logger, "exit");
break;
}
}
}
int ge_main(ge_core_t* core) {
core->callbacks.init = init;
core->callbacks.process = process;
ge_engine_run(core);
return 0;
}