【V0.1B8】从零开始的2D游戏引擎开发之路

发布日期 :2022-05-08 23:03
内部版本号:v0.00.00.10


变更概要

类别 内容
删除文件 Tanxl_GameEvent.hTanxl_GameEvent.cppTanxl_InitBase.h
文件合并 GameEvent 模块整体并入 GameState 模块
输入集成 InsertEventBase 正式接入主循环,支持 WASD + 方向键
组件系统 GameObjectBase 新增组件添加功能,含同名去重检查
渲染调整 玩家方块与地图方块分离,网格尺寸固定化
头文件清理 Tanxl_OpenGL_Draw.h 移除冗余的外部库包含

一、GameEvent 模块并入 GameState

背景

Build-7 中 GameEventGameEventBase 定义在独立的 Tanxl_GameEvent.h/.cpp 文件中。Build-8 将这两个类的定义和实现分别合并到 Tanxl_GameState.hTanxl_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

相关推荐
米粒12 小时前
力扣算法刷题 Day 63 Bellman_ford 算法
数据库·算法·leetcode
楼田莉子2 小时前
仿Muduo的高并发服务器:Http协议模块
linux·服务器·c++·后端·学习
杨云龙UP10 小时前
SQL Server2022部署:Windows Server 2016下安装、SSMS配置、备份还原与1433端口放通全流程_20260508
运维·服务器·数据库·sql·sqlserver·2022
墨染天姬12 小时前
【AI】cursor提示词小技巧
前端·数据库·人工智能
fish_xk12 小时前
Linux开方工具
linux·运维·服务器
古月-一个C++方向的小白12 小时前
MySQL数据库——数据类型
android·数据库·mysql
qq_4135020213 小时前
如何创建CDB公共用户_C##前缀强制规则与CONTAINER=ALL
jvm·数据库·python
逸Y 仙X13 小时前
文章二十七:ElasticSearch ES查询模板(Search Template)高效复用实战
java·大数据·数据库·elasticsearch·搜索引擎·全文检索