发布日期 :2022-05-08 23:03
内部版本号:v0.00.00.10
变更概要
| 类别 | 内容 |
|---|---|
| 删除文件 | Tanxl_GameEvent.h、Tanxl_GameEvent.cpp、Tanxl_InitBase.h |
| 文件合并 | GameEvent 模块整体并入 GameState 模块 |
| 输入集成 | InsertEventBase 正式接入主循环,支持 WASD + 方向键 |
| 组件系统 | GameObjectBase 新增组件添加功能,含同名去重检查 |
| 渲染调整 | 玩家方块与地图方块分离,网格尺寸固定化 |
| 头文件清理 | Tanxl_OpenGL_Draw.h 移除冗余的外部库包含 |
一、GameEvent 模块并入 GameState
背景
Build-7 中 GameEvent 和 GameEventBase 定义在独立的 Tanxl_GameEvent.h/.cpp 文件中。Build-8 将这两个类的定义和实现分别合并到 Tanxl_GameState.h 和 Tanxl_GameState.cpp。
合并后的 GameState.h 结构
cpp
//_VERSION_0_2_
// LAST_UPDATE 2022-05-08 22:40
// 以下内容原属于 Tanxl_GameEvent.h
class GameEvent { ... };
class GameEventBase { ... };
// 原有内容
class StateUnit { ... };
class GameStateBase { ... };
GameState.cpp 新增内容
cpp
// ============ GameEvent 实现(原在 Tanxl_GameEvent.cpp)============
GameEvent::GameEvent(std::string Name) : EventName(Name) {}
std::string GameEvent::GetEventName() { return this->EventName; }
void GameEventBase::RegistEvent(GameEvent* Event) { ... }
GameEvent* GameEventBase::GetGameEvent(std::string EventName) { ... }
GameEventBase& GameEventBase::GetEventBase() { ... }
// 构造/析构/拷贝控制函数实现...
// ================================================================
// 原有的 StateUnit / GameStateBase 实现保持不变
影响范围
| 项目 | Build-7 | Build-8 |
|---|---|---|
Tanxl_GameEvent.h |
存在 | 已删除 |
Tanxl_GameEvent.cpp |
存在 | 已删除 |
Tanxl_GameState.h |
仅含 StateUnit/GameStateBase | 含 GameEvent + StateUnit + GameStateBase |
Tanxl_GameState.cpp |
仅含 StateUnit/GameStateBase 实现 | 含全部三个类实现 |
二、输入系统接入主循环
这是 Build-8 最实质性的功能改动------InsertEventBase 从独立模块正式成为渲染循环的一部分。
Tanxl_OpenGL_Draw.h 变更
2.1 头文件精简
cpp
// Build-7 --- 包含了这些:
#include <GL\glew.h> // ← 移除
#include <GLFW\glfw3.h> // ↓ 全部移除
#include <iostream>
#include <string>
#include <math.h>
// Build-8 --- 仅保留引擎内部头文件和必要系统头文件
#include "Tanxl_DataBase.h"
#include "Tanxl_GameState.h"
#include "Tanxl_InsertAction.h"
#include <math.h>
#include "Utils.h"
被移除的五个头文件(GLEW、GLFW、IOSTREAM、STRING、MATH_H)实际上已被上述引擎头文件间接包含或不再需要。
2.2 全局输入对象
cpp
InsertEventBase* IEB = &InsertEventBase::GetInsertBase();
在全局作用域创建 InsertEventBase 单例指针,供 init() 和 mainLoop() 共同使用。
2.3 init() 注册 8 个按键
这一部分的代码来源于我近期在嵌入式方面的学习。按键的初始化采用了类似STM32库函数GPIO初始化的方式。
cpp
void init(GLFWwindow* window, GameStateBase* State) {
// 上: UP + W
Key_Unit MOVE_UP;
MOVE_UP.GLFW_KEY = GLFW_KEY_UP; MOVE_UP.MoveLen = 0.01f; MOVE_UP.MoveToY = true;
IEB->RegistEvent(MOVE_UP);
MOVE_UP.GLFW_KEY = GLFW_KEY_W;
IEB->RegistEvent(MOVE_UP);
// 左: LEFT + A (MoveLen 为负值)
Key_Unit MOVE_LEFT;
MOVE_LEFT.GLFW_KEY = GLFW_KEY_LEFT; MOVE_LEFT.MoveLen = -0.01f; MOVE_LEFT.MoveToX = true;
IEB->RegistEvent(MOVE_LEFT);
MOVE_LEFT.GLFW_KEY = GLFW_KEY_A;
IEB->RegistEvent(MOVE_LEFT);
// 右: RIGHT + D
Key_Unit MOVE_RIGHT;
MOVE_RIGHT.GLFW_KEY = GLFW_KEY_RIGHT; MOVE_RIGHT.MoveLen = 0.01f; MOVE_RIGHT.MoveToX = true;
IEB->RegistEvent(MOVE_RIGHT);
MOVE_RIGHT.GLFW_KEY = GLFW_KEY_D;
IEB->RegistEvent(MOVE_RIGHT);
// 下: DOWN + S (MoveLen 为负值)
Key_Unit MOVE_DOWN;
MOVE_DOWN.GLFW_KEY = GLFW_KEY_DOWN; MOVE_DOWN.MoveLen = -0.01f; MOVE_DOWN.MoveToY = true;
IEB->RegistEvent(MOVE_DOWN);
MOVE_DOWN.GLFW_KEY = GLFW_KEY_S;
IEB->RegistEvent(MOVE_DOWN);
// ... 其余初始化代码不变
}
按键映射表:
| 方向 | 主按键 | 备用键 | 轴 | 步长 |
|---|---|---|---|---|
| 上 | ↑ | W | Y | +0.01 |
| 下 | ↓ | S | Y | -0.01 |
| 左 | ← | A | X | -0.01 |
| 右 | → | D | X | +0.01 |
2.4 mainLoop() 简化
cpp
// Build-7 的主循环(约50行手动按键处理代码)
while (!glfwWindowShouldClose(window)) {
// ... 设置 uniform ...
if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS) {
std::cout << "LEFT_PUSHED! ..." << endl;
movex -= movespeed;
// ... 重复4次方向键 + Z/X/C 键 ...
}
display(...);
}
// Build-8 的主循环
while (!glfwWindowShouldClose(window)) {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // 新增:每帧清屏
glClear(GL_COLOR_BUFFER_BIT); // 新增
PosX = glGetUniformLocation(renderingProgram, "MoveX");
glProgramUniform1f(renderingProgram, PosX, movex);
PosY = glGetUniformLocation(renderingProgram, "MoveY");
glProgramUniform1f(renderingProgram, PosY, movey);
IEB->GetInsert(window, &movex, &movey); // 替代所有手动按键检测
display(window, glfwGetTime());
glfwSwapBuffers(window);
glfwPollEvents();
}
变化量 :优化后的代码量大幅减少:主循环代码从约60行精简至约16行核心逻辑,同时移除了冗余的SpeedFlag变量,并优化了方向键及Z/X/C键的手动判断逻辑。
三、游戏对象组件系统完善
Tanxl_GameObject.h 变更
3.1 ComponmentBase 类
cpp
// Build-7 --- 仅一个纯虚函数占位
class ComponmentBase
{
virtual void SpecialAbility() = 0;
};
// Build-8 --- 增加了实际内容 但是还未正式应用
class ComponmentBase
{
public:
ComponmentBase(std::string Name) :ComponmentName(Name) {}
std::string GetName() { return this->ComponmentName; }
virtual void Special() = 0; // 重命名:SpecialAbility → Special
private:
std::string ComponmentName; // 新增:组件名称字段
};
3.2 GameObjectBase 类
cpp
// Build-7 --- 空类体
class GameObjectBase
{
private:
std::vector<ComponmentBase*> CMB;
};
// Build-8 --- 提供公共接口
class GameObjectBase
{
bool AppendComponment(ComponmentBase* CM); // 新增方法声明
private:
std::vector<ComponmentBase*> CMB;
};
// 方法实现(内联在头文件中)
bool GameObjectBase::AppendComponment(ComponmentBase* CM)
{
for (int i = 0; i < CMB.size(); i++)
if (CMB.at(i)->GetName() == CM->GetName())
return false; // 同名组件拒绝添加
CMB.push_back(CM);
return true;
}
四、着色器改动:玩家方块分离
StatevertShader.glsl 核心变化
| 项目 | Build-7 | Build-8 |
|---|---|---|
| 网格尺寸 | 动态计算 (2.0f / SHeight) |
固定值 0.2f |
| 循环起点 | i = 0 |
i = 1 |
| VertexID 0~5 | 在循环内统一处理 | 循环外单独处理(玩家方块) |
| 玩家方块 | 无 | 有,受 MoveX/MoveY 控制 |
| 第二顶点颜色 | 黄色 (1,1,0,1) |
绿色 (0,1,0,1) |
cpp
// Build-8 关键结构
float Height = 0.2f; // 固定尺寸
float Width = 0.2f;
for(int i = 1; i < SHeight * SWidth; i++) // 从1开始,跳过前6个顶点
{
// 地图方块的网格排列逻辑(与 Build-7 相同)
}
// 玩家方块 ------ 独立于网格,可自由移动
if (gl_VertexID == 0)
{ gl_Position = vec4(Width/2 + MoveX, -Height/2 + MoveY, 0.1, 1.0); vs_color = vec4(1.0, 0.8, 0.0, 1.0);}
else if (gl_VertexID == 1)
{ gl_Position = vec4(-Width/2 + MoveX, -Height/2 + MoveY, 0.1, 1.0); vs_color = vec4(1.0, 1.0, 0.0, 1.0);}
// ... 2~5 同理
玩家方块的 z 坐标设为 0.1(地图方块为 0.0),确保绘制在最上层。
五、其他变更
| 文件 | 变更内容 |
|---|---|
main.cpp |
SetState(10, 10) → SetState(1, 1) |
Tanxl_InitBase.h |
整个文件删除 |
TANXL_ENGINE.vcxproj |
移除已删除文件的编译项引用 |
Wild_Chicken_Programing /// 2022-05-08 23:03