1、封装一个游戏类: 包含一个初始化函数、一个更新函数、一个处理输入函数、一个渲染函数
class Game
{
public:
//游戏状态
GameState State;
GLboolean Keys[1024];
GLuint Width,Height;
//构造函数/析构函数
Game(GLuint width,GLuint height);
~Game();
//初始化游戏状态(加载所有的着色器/纹理/关卡)
void Init();
//游戏循环
void ProcessInput(GLfloat dt);
void Update(GLfloat dt);
void Render();
};
// 代表了游戏的当前状态
enum GameState {
GAME_ACTIVE,
GAME_MENU,
GAME_WIN
};
GameState 来标记当前游戏所处的状态,一般情况下不同的状态会触发不同的动作。 在构造函数中我们通过一个Width、Height去初始化窗口、设置分辨率等操作。 Init()函数中初始化着色器、纹理等。 ProcessInput函数从Keys数组里面获取输入参数处理用户的输入。 Update()函数用来更新渲染设置。 Render()负责渲染。
2、工具类:在程序中我们会用到很多的shader,以及很多的纹理。 所以我们可以将shader以及纹理的创建过程分别封装起来。抽离出shader类和纹理类。
3、资源管理器:shader需要加载着色器代码文本,纹理需要加载纹理资源,为了符合单一功能原则, 我们可以将资源的加载逻辑抽离出来。用一个资源管理器类统一管理。
Shader shader = ResourceManager::LoadShader("vertex.vs", "fragment.vs", nullptr, "test");
// 接下来使用它shader.Use();
4、精灵类: 精灵的可以理解为纹理加上一些属性的对象,就是我们在游戏中看到的各种各样的独立的个体。就如现实中的万事万物一样我们可以将拥有相同属性的精灵抽象理解出一个个精灵类的概念,代码中用类和对象描述这种关系。
抽离出一个简单的精灵类,可以设置位置和纹理, 拥有一个shader用于渲染。
class SpriteRenderer
{
public:
SpriteRenderer(Shader &shader);
~SpriteRenderer();
void DrawSprite(Texture2D &texture,glm::vec2 position,
glm::vec2 size = glm::vec2(10,10),GLfloat rotate = 0.0f,
glm::vec3 color = glm::vec3(1.0f));
private:
Shader shader;
GLuint quadVAO;
void initRenderData();
};
私有属性quaVAO定点数组对象包含了顶点坐标和纹理坐标。shader 着色器程序。在initRenderData() 中初始化顶点数组对象,配置好着色器读取位置。DrasSprite函数中配置好了精灵的渲染指令。
网友评论