利用OpenGL设计贪吃蛇游戏

利用OpenGL设计贪吃蛇游戏

任务介绍

  • 贪吃蛇游戏:玩家控制贪吃蛇在游戏区域里驰骋,避免碰到自己或障碍物,尽可能地吃更多的食物以生长!

游戏玩法

  • WASD控制蛇的移动
  • 游戏开始,会在地图空闲位置刷新一个食物,蛇触碰到食物后食物消失,食物会重新刷新,分数增加,蛇会增加一个单位的长度
  • 当蛇触碰到自己,则游戏失败
  • 当蛇接触到地图边界,蛇会在地图另一端重新进入地图

开发环境

  • OpenGL3
  • GLFW
  • IMGUI

游戏实现

贪吃蛇游戏的框架搭建

主程序

对GLFW进行初始化,创建游戏对象,创建GUI,对用户的输入进行传递。主要是在一个 while 循环中,进行对游戏对象的更新与渲染。

//渲染
while (!glfwWindowShouldClose(window))
{
   
	// 开启深度测试
	glEnable(GL_DEPTH_TEST);
	// 清空深度缓存
	glClear(GL_DEPTH_BUFFER_BIT);
	//处理用户输入
	processInput(window);

	// Start the Dear ImGui frame
	ImGui_ImplOpenGL3_NewFrame();
	ImGui_ImplGlfw_NewFrame();
	ImGui::NewFrame();

	// 计算每一次渲染相差的时间
	GLfloat currentFrame = glfwGetTime();
	deltaTime = currentFrame - lastFrame;
	lastFrame = currentFrame;

	std::string score = "Score : " + std::to_string(Snake.score);
	const char *scorechar = score.c_str();
	// 创建gui
	ImGui::Begin("Gluttonous Snake");

	// 显示分数或者游戏结束
	if (Snake.State == GAME_WIN)
	{
   
		ImGui::Text("Game Over!!!!!!");
		ImGui::Text(scorechar);
	}
	else
	{
   
		ImGui::Text(scorechar);
	}
	ImGui::End();

	// Rendering
	ImGui::Render();

	// 游戏处理用户输入
	Snake.ProcessInput(deltaTime);

	// 更新游戏的状态
	Snake.Update(deltaTime);

	//设置清空屏幕所用的颜色
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	//清除颜色缓冲
	glClear(GL_COLOR_BUFFER_BIT);

	// 渲染游戏
	Snake.Render((float)glfwGetTime());

	//渲染gui
	ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
	//交换颜色缓冲
	glfwSwapBuffers(window);
	//检查IO事件
	glfwPollEvents();
}
游戏类

维护游戏状态,提供更新状态的接口供主程序调用,进行碰撞检测等

// 游戏的状态
enum GameState {
   
	GAME_ACTIVE,
	GAME_MENU,
	GAME_WIN
};

class Game
{
   
public:
	// 游戏状态
	GameState              State;
	GLuint                 Width, Height;
	// 游戏分数
	int score;

	Game(GLuint width, GLuint height);
	~Game();
	// 初始化游戏加载shader等
	void Init();

	void ProcessInput(GLfloat dt);
	void Update(GLfloat dt);
	void Render(float rotateRad);
	void ProcessMouseMovement(float xoffset, float yoffset, bool constrainPitch);

	// 键盘状态
	bool pressW;
	bool pressS;
	bool pressA;
	bool pressD;
	void ResetPress();

	// 移动蛇
	void MoveTheSnack();

	// 碰撞检测
	void DoCollisions();
};
游戏对象类

维护游戏对象的状态,在本次游戏中就是蛇头与蛇身、以及生成的食物

class GameObject
{
   
public:
	// 状态
	glm::vec3   Position, Size;
	GLfloat     Rotation;

	GameObject();
	// 设置位置
	void setPosition(glm::vec3 pos);
private:
	GLuint gameobjectVAO;
	
};
工具类

管理着色器、纹理的加载,本次游戏中没有用到纹理于是只有着色器的加载

class ResourceManager
{
   
public:
	// Resource storage
	static std::map<std::string, Shader*>    Shaders;

	// Loads (and generates) a shader program from file loading vertex, fragment (and geometry) shader's source code. If gShaderFile is not nullptr, it also loads a geometry shader
	static Shader *  LoadShader(const GLchar *vShaderFile, const GLchar *fShaderFile, const GLchar *gShaderFile, std::string name);
	// Retrieves a stored sader
	static Shader *  GetShader(std::string name);

	// Properly de-allocates all loaded resources
	static void      Clear();
private:
	// Private constructor, that is we do not want any actual resource manager objects. Its members and functions should be publicly available (static).
	ResourceManager() {
    }
	// Loads and generates a shader from file
	static Shader  *  loadShaderFromFile(const GLchar *vShaderFile, const GLchar *fShaderFile, const GLchar *gShaderFile = nullptr);
};
着色器类

用于对单个的着色器进行初始化,并修改里面的值

class Shader
{
   
public:
	// State
	GLuint ID;
	// Constructor
	Shader() {
    }
	// Sets the current shader as active
	Shader  &Use();
	// Compiles the shader from given source code
	void    Compile(const GLchar *vertexSource, const GLchar *fragmentSource, const GLchar *geometrySource = nullptr)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值