feat(game_core): 重构游戏引擎并添加新功能
- 重构了游戏引擎的核心逻辑和架构 - 添加了新的实体组件系统(ECS) - 实现了简单的碰撞检测和响应 - 新增了地图和子弹功能 - 优化了输入处理和渲染逻辑 - 调整了游戏控制方式
This commit is contained in:
33
game_core/entities/bullet.c
Normal file
33
game_core/entities/bullet.c
Normal file
@@ -0,0 +1,33 @@
|
||||
#include "entities.h"
|
||||
|
||||
void init_bullet(ge_ecs_t* ecs, ge_entity_t **_bullet) {
|
||||
Assert(ecs != NULL && _bullet != NULL);
|
||||
ge_ecs_add_entity(ecs, _bullet);
|
||||
ge_entity_t* bullet = *_bullet;
|
||||
Assert(bullet != NULL);
|
||||
|
||||
*bullet = (ge_entity_t) {
|
||||
.user_type = BULLET,
|
||||
.component_mask = GE_RENDERABLE_MASK | GE_PHYSICS_MASK | GE_COLLIDER_MASK,
|
||||
.renderable = (ge_render_component_t) {
|
||||
.type = GE_RENDER_COMP_TYPE_RECT,
|
||||
.data.rect = {
|
||||
.size = { 2, 2 },
|
||||
.color = GE_COLOR_RED,
|
||||
}
|
||||
},
|
||||
.physics_body = (ge_physics_component_t) {
|
||||
.type = GE_PHYSICS_COMP_TYPE_VELOCITY,
|
||||
.velocity = { 0, 0 },
|
||||
},
|
||||
.collision = (ge_collision_component_t) {
|
||||
.type = GE_COLLISION_COMP_TYPE_BOX,
|
||||
.layers = LAYER_PLAYER_PROJECTILE,
|
||||
.mask = LAYER_WALL | LAYER_ENEMY_HITBOX,
|
||||
.collider.box = {
|
||||
.relative_pos = { 0, 0 },
|
||||
.size = { 2, 2 },
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
0
game_core/entities/enemy.c
Normal file
0
game_core/entities/enemy.c
Normal file
19
game_core/entities/entities.h
Normal file
19
game_core/entities/entities.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef __ENTITY_H__
|
||||
#define __ENTITY_H__
|
||||
|
||||
#include "tilemap.h"
|
||||
#include "layer.h"
|
||||
|
||||
enum {
|
||||
PLAYER,
|
||||
ENEMY,
|
||||
BULLET,
|
||||
};
|
||||
|
||||
void init_player(ge_ecs_t* ecs, ge_entity_t **_player);
|
||||
|
||||
#define MAX_BULLET 16
|
||||
#define BASIC_SPEED (1 << GE_PHYSICS_VELOCITY_BIT)
|
||||
void init_bullet(ge_ecs_t* ecs, ge_entity_t **_bullet);
|
||||
|
||||
#endif
|
||||
13
game_core/entities/layer.h
Normal file
13
game_core/entities/layer.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef __LAYER_H__
|
||||
#define __LAYER_H__
|
||||
|
||||
enum {
|
||||
LAYER_WALL = 1 << 0,
|
||||
LAYER_PLAYER_HITBOX = 1 << 1,
|
||||
LAYER_ENEMY_HITBOX = 1 << 2,
|
||||
LAYER_PLAYER_PROJECTILE = 1 << 3,
|
||||
LAYER_ENEMY_PROJECTILE = 1 << 4,
|
||||
LAYER_POWERUP = 1 << 5,
|
||||
};
|
||||
|
||||
#endif /* __LAYER_H__ */
|
||||
32
game_core/entities/player.c
Normal file
32
game_core/entities/player.c
Normal file
@@ -0,0 +1,32 @@
|
||||
#include "entities.h"
|
||||
|
||||
void init_player(ge_ecs_t* ecs, ge_entity_t **_player) {
|
||||
Assert(ecs != NULL && _player != NULL);
|
||||
ge_ecs_add_entity(ecs, _player);
|
||||
ge_entity_t* player = *_player;
|
||||
Assert(player != NULL);
|
||||
|
||||
player->user_type = PLAYER;
|
||||
player->component_mask = GE_COMPONENT_ACVIVE | GE_RENDERABLE_MASK | GE_PHYSICS_MASK | GE_COLLIDER_MASK;
|
||||
player->position = (ge_vector2i_t){ TILEMAP_SIZE * 8, TILEMAP_SIZE * 8 };
|
||||
player->renderable = (ge_render_component_t) {
|
||||
.type = GE_RENDER_COMP_TYPE_RECT,
|
||||
.data.rect = {
|
||||
.size = {TILEMAP_SIZE, TILEMAP_SIZE},
|
||||
.color = GE_COLOR_BLUE,
|
||||
}
|
||||
};
|
||||
player->physics_body = (ge_physics_component_t) {
|
||||
.type = GE_PHYSICS_COMP_TYPE_VELOCITY,
|
||||
.velocity = {0, 0},
|
||||
};
|
||||
player->collision = (ge_collision_component_t) {
|
||||
.type = GE_COLLISION_COMP_TYPE_BOX,
|
||||
.layers = LAYER_PLAYER_HITBOX,
|
||||
.mask = LAYER_WALL,
|
||||
.collider.box = {
|
||||
.relative_pos = {0, 0},
|
||||
.size = {TILEMAP_SIZE, TILEMAP_SIZE},
|
||||
}
|
||||
};
|
||||
}
|
||||
81
game_core/entities/tilemap.c
Normal file
81
game_core/entities/tilemap.c
Normal file
@@ -0,0 +1,81 @@
|
||||
#include "tilemap.h"
|
||||
#include <ecs/ge_render_component.h>
|
||||
#include <ecs/ge_collision_component.h>
|
||||
|
||||
static ge_render_component_t* tilemap_render[TILEMAP_Y_HEIGHT][TILEMAP_X_WIDTH];
|
||||
static ge_layers_t tilemap_layers[TILEMAP_Y_HEIGHT][TILEMAP_X_WIDTH];
|
||||
static int real_map[TILEMAP_Y_HEIGHT][TILEMAP_X_WIDTH] = {
|
||||
{2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, // 第0行: 顶部边界
|
||||
{2,0,0,1,1,0,0,0,0,0,0,1,1,0,0,2}, // 第1行: 敌方出生点预留
|
||||
{2,0,0,1,1,0,0,0,0,0,0,1,1,0,0,2}, // 第2行
|
||||
{2,0,0,0,0,0,0,1,1,0,0,0,0,0,0,2},
|
||||
{2,0,0,0,0,0,0,1,1,0,0,0,0,0,0,2},
|
||||
{2,0,1,1,0,0,0,0,0,0,0,0,1,1,0,2},
|
||||
{2,0,1,1,0,0,0,0,0,0,0,0,1,1,0,2},
|
||||
{2,0,0,0,0,0,1,1,1,1,0,0,0,0,0,2}, // 中央障碍
|
||||
{2,0,0,0,0,0,1,0,0,1,0,0,0,0,0,2}, // 中央基地区域
|
||||
{2,0,1,1,0,0,1,0,0,1,0,0,1,1,0,2},
|
||||
{2,0,1,1,0,0,0,0,0,0,0,0,1,1,0,2},
|
||||
{2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2},
|
||||
{2,0,0,1,1,0,0,0,0,0,0,1,1,0,0,2}, // 第12行: 玩家出生点预留
|
||||
{2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, // 第13行: 底部边界
|
||||
};
|
||||
|
||||
static inline void fill_render(void) {
|
||||
// FIXME you can using ecs to store the entity
|
||||
static ge_render_component_t render_wall = {
|
||||
.type = GE_RENDER_COMP_TYPE_RECT,
|
||||
.data.rect.size.x = TILEMAP_SIZE,
|
||||
.data.rect.size.y = TILEMAP_SIZE,
|
||||
.data.rect.color = GE_COLOR_GRAY,
|
||||
};
|
||||
for (int y = 0; y < TILEMAP_Y_HEIGHT; y++) {
|
||||
for (int x = 0; x < TILEMAP_X_WIDTH; x++) {
|
||||
if (real_map[y][x] == 0) {
|
||||
continue;
|
||||
}
|
||||
tilemap_render[y][x] = &render_wall;
|
||||
tilemap_layers[y][x] = LAYER_WALL;
|
||||
/**
|
||||
* the global variable default value is NULL
|
||||
* tilemap_render[y][x] = NULL;
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void init_tilemap(ge_ecs_t* ecs, ge_entity_t **_tilemap) {
|
||||
Assert(ecs != NULL && _tilemap != NULL);
|
||||
ge_ecs_add_entity(ecs, _tilemap);
|
||||
ge_entity_t* tilemap = *_tilemap;
|
||||
Assert(tilemap != NULL);
|
||||
|
||||
tilemap->component_mask = (
|
||||
GE_COMPONENT_ACVIVE |
|
||||
GE_COMPONENT_POSITION |
|
||||
GE_COMPONENT_RENDERABLE |
|
||||
GE_COMPONENT_COLLIDER
|
||||
);
|
||||
/**
|
||||
* y = 16
|
||||
*/
|
||||
tilemap->position = (ge_vector2i_t) {.x = 0, .y = 16};
|
||||
tilemap->renderable = (ge_render_component_t) {
|
||||
.type = GE_RENDER_COMP_TYPE_TILEMAP,
|
||||
.data.tilemap.tile_size = TILEMAP_SIZE,
|
||||
.data.tilemap.map_size.x = TILEMAP_X_WIDTH,
|
||||
.data.tilemap.map_size.y = TILEMAP_Y_HEIGHT,
|
||||
.data.tilemap.components = (ge_render_component_t**)tilemap_render,
|
||||
};
|
||||
tilemap->collision = (ge_collision_component_t) {
|
||||
.type = GE_COLLISION_COMP_TYPE_TILEMAP,
|
||||
.layers = LAYER_WALL,
|
||||
.collider.tilemap = {
|
||||
.tile_size = TILEMAP_SIZE,
|
||||
.map_size = { TILEMAP_X_WIDTH, TILEMAP_Y_HEIGHT },
|
||||
.layers = (ge_layers_t*)tilemap_layers,
|
||||
},
|
||||
};
|
||||
|
||||
fill_render();
|
||||
}
|
||||
15
game_core/entities/tilemap.h
Normal file
15
game_core/entities/tilemap.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef __TILEMAP_H__
|
||||
#define __TILEMAP_H__
|
||||
|
||||
#include "../ge_color.h"
|
||||
#include "layer.h"
|
||||
#include <ecs/ge_entity.h>
|
||||
#include <pynic_log/pynic_log.h>
|
||||
|
||||
#define TILEMAP_SIZE 8
|
||||
#define TILEMAP_X_WIDTH 16
|
||||
#define TILEMAP_Y_HEIGHT 14
|
||||
|
||||
void init_tilemap(ge_ecs_t* ecs, ge_entity_t **_tilemap);
|
||||
|
||||
#endif // __TILEMAP_H__
|
||||
Reference in New Issue
Block a user