个性化阅读
专注于IT技术分析

如何在Ubuntu 19.04中使用现代OpenGL使用C实现自己的Minecraft游戏克隆

本文概述

《我的世界》基本上是一款关于放置带有纹理的积木并进行冒险的游戏。它在广阔无generated的地形, 冰冷的山脉, 潮湿的海湾, 广阔的牧场等众多世界中产生。该游戏最初是用Java开发的, 因此由于其性能而受到严重批评。对于开发人员而言, 创建此类游戏的副本可能是用任何其他编程语言实现的真正有趣的挑战。你可以使用多种语言(例如Python)找到该游戏的某些端口。今天, 我们想与你分享一个使用OpenGL用C语言完成的非常酷并且可以接受的实现。该项目是Craft, 是适用于Windows, Mac OS X和Linux的Minecraft克隆。使用现代OpenGL(着色器), 它仅包含几千行C。游戏特色:

  • 使用单纯形噪声生成简单但美观的地形。
  • 可以轻松添加20多种类型的块, 甚至更多。
  • 支持植物(草, 花, 树等)和透明度(玻璃)。
  • 天空中只有简单的云(它们不会移动)。
  • 日/夜循环和纹理的圆顶。
  • 标志-你可以在任何块上书写文字。
  • 灯-可以将任何块设置为光源。
  • 基本遮挡块的环境光遮挡。
  • 世界变化一直存在于sqlite3数据库中。
  • 多人支持!

在本文中, 我们将引导你逐步在Ubuntu计算机中构建该项目。

1.安装Ubuntu依赖项

在构建项目之前, 你将需要在系统中安装一些依赖项, 以便我们从头开始构建Craft项目。打开终端, 然后键入以下命令进行安装:

sudo apt-get install cmake libglew-dev xorg-dev libcurl4-openssl-dev

这些软件包是:

  • 问题:OpenGL扩展牧马人库(GLEW)是跨平台的开源C / C ++扩展加载库。 GLEW提供了有效的运行时机制, 用于确定目标平台上支持哪些OpenGL扩展。 OpenGL核心和扩展功能在单个头文件中公开。 GLEW已经在各种操作系统上进行了测试, 包括Windows, Linux, Mac OS X, FreeBSD, Irix和Solaris。
  • xorg:Xorg基本上是Linux中使用的X窗口系统。它是计算机图形环境的基础。该软件包默认安装在Ubuntu 19.04上, 但是以防万一没有安装。
  • libcurl:是一个免费且易于使用的客户端URL传输库, 支持DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP , SFTP, SMTP, SMTPS, Telnet和TFTP。 libcurl支持SSL证书, HTTP POST, HTTP PUT, FTP上传, 基于HTTP表单的上传, 代理, Cookie, 用户名和密码验证(基本, 摘要, NTLM, 协商, Kerberos), 文件传输恢复, http代理隧道等等!

有关此项目的更多信息, 请访问Github上的官方资源库。安装依赖项后, 请在下一步中继续获取项目的源。

2.克隆工艺源代码

现在, 你需要克隆Craft项目的源代码, 可以使用Git(sudo apt-get install git)在系统的某些目录中运行以下命令来轻松实现此目的:

git clone https://github.com/fogleman/Craft.git

这将创建Craft目录, 其中包含源代码。使用以下命令切换到提到的目录:

cd Craft

并继续下一步。

3.构建并运行

要继续进行构建, 你需要使用CMake生成标准的构建文件。 CMake是一个可扩展的开源系统, 它以操作系统和独立于编译器的方式管理构建过程。与许多跨平台系统不同, CMake设计为与本机构建环境结合使用。在当前目录上运行以下命令:

cmake .

生成文件准备就绪后, 使用以下命令运行构建:

make

构建过程将开始, 并且将需要一段时间, 因此请耐心等待, 直到完成。构建之后, 你可以直接从命令行运行应用程序:

./craft

可以按照以下说明控制游戏:

  • WASD向前, 向左, 向后, 向右移动。
  • 跳跃的空间。
  • 左键单击以破坏方块。
  • 右击或Cmd +左击创建一个块。
  • Ctrl +右键单击以将块切换为光源。
  • 1-9选择要创建的块类型。
  • E循环浏览块类型。
  • 标签页可在步行和飞行之间切换。
  • ZXCVBN沿XYZ轴沿精确方向移动。
  • 向左移动即可缩放。
  • F以正交模式显示场景。
  • O在主视图中观察玩家。
  • P以画中画方式观察玩家。
  • T将文本输入聊天。
  • 正斜杠(/)输入命令。
  • 反引号(`), 可在任何块(符号)上写文本。
  • 箭头键模拟鼠标移动。
  • Enter模拟鼠标单击。

关于实现逻辑(深入的技术细节)

地形生成

地形是使用Simplex噪声生成的, Simplex噪声是基于位置播种的确定性噪声函数。因此, 在给定位置始终将以相同的方式生成世界。

在XZ平面中, 世界被分成32×32的块块(Y向上)。这样可以使世界变得”无限”(在X或Z值较大时, 浮点精度目前是一个问题), 还可以更轻松地管理数据。只需要从数据库中查询可见的块。

渲染图

仅渲染暴露的面。这是一项重要的优化, 因为绝大多数图块要么完全被隐藏, 要么仅暴露一个或两个面。每个块记录每个相邻块的一个块的宽度重叠, 因此它知道沿其周边暴露了哪些块。

仅显示可见的块。天真的视锥剔除方法用于测试相机视图中是否有块。如果不是, 则不渲染。这也导致相当不错的性能改进。

当块中的块发生更改时, 块缓冲区将完全重新生成, 而不是尝试更新VBO。

使用位图地图集渲染文本。每个字符都渲染到形成2D矩形的两个三角形上。

使用”现代” OpenGL-不使用不推荐使用的固定功能管道功能。顶点缓冲对象用于位置, 法线和纹理坐标。顶点和片段着色器用于渲染。矩阵操纵函数位于matrix.c中, 用于平移, 旋转, 透视, 正射等矩阵。 3D模型由非常简单的图元组成-主要是立方体和矩形。这些模型是在cube.c中的代码中生成的。

通过丢弃片段着色器中的洋红色像素, 可以实现玻璃块和植物(植物不占据其三角形基元的完整矩形形状)的透明度。

数据库

用户对世界的更改存储在sqlite数据库中。仅存储增量, 因此将生成默认世界, 然后在加载时将用户更改应用到顶部。

主数据库表名为”块”, 并具有列p, q, x, y, z, w。 (p, q)标识块, (x, y, z)标识块位置, (w)标识块类型。 0表示一个空块(空气)。

在游戏中, 块将其块存储在哈希图中。 (x, y, z)键映射到(w)值。

块的y位置限制为0 <= y <256。上限主要是人为的限制, 以防止用户建造不必要的高大结构。禁止用户破坏y = 0的块, 以免掉入世界。

多人游戏

多人游戏模式是使用普通的套接字实现的。使用了一种简单的基于行的ASCII协议。每行由一个命令代码和零个或多个逗号分隔的参数组成。客户端使用一个简单的命令从服务器请求块:C, p, q, key。 ” C”表示”块”, (p, q)标识块。该密钥用于缓存-服务器将仅发送自客户端最后一次请求该块以来执行的块更新。块更新(实时或作为块请求的一部分)以B, p, q, x, y, z, w的格式发送到客户端。发送请求的块的所有块之后, 服务器将以以下格式发送更新的缓存键:K, p, q, key。客户端将存储此密钥, 并在下次需要该块时使用它。玩家位置以以下格式发送:P, pid, x, y, z, rx, ry。 pid是玩家ID, rx和ry值表示玩家在两个不同轴上的旋转。客户端从过去两个位置更新中插入玩家位置, 以使动画更流畅。客户端最多每0.1秒将其位置发送到服务器(如果不移动则更少)。

首次连接到服务器时, 客户端缓存到sqlite数据库可能会占用大量性能。因此, 在后台线程上执行sqlite写操作。所有写入都发生在事务中以提高性能。每5秒钟提交一次事务, 而不是逻辑上完成一些工作。环形/环形缓冲区用作将哪些数据写入数据库的队列。

在多人游戏模式下, 玩家可以在主视图或画中画视图中彼此观察。 PnP的实现非常简单, 只需更改视口并从其他玩家的角度重新渲染场景即可。

碰撞测试

命中测试(用户指向的障碍物)是通过按照玩家的视线从玩家的位置向外扫描光线来实现的。这不是一种精确的方法, 因此可以使步速变得更小而更加精确。

碰撞测试只是将玩家的位置调整到与障碍物相邻的障碍物保持一定距离。 (云和植物没有标记为障碍物, 因此你可以直通它们。)

天穹

一个织地不很细的天空圆顶用于天空。纹理的X坐标表示一天中的时间。 Y值从天空球的底部到天空球的顶部映射。玩家始终位于球体的中心。块的片段着色器还会对天空纹理进行采样, 以根据块相对于背景天空的位置来确定要混合的合适雾色。

环境光遮蔽

环境遮挡的实现方法如下页所述:

http://0fps.wordpress.com/2013/07/03/ambient-occlusion-for-minecraft-like-worlds/

依存关系

  • GLEW用于管理跨平台的OpenGL扩展。
  • GLFW用于跨平台窗口管理。
  • CURL用于HTTPS / SSL POST的身份验证过程。
  • lodepng用于加载PNG纹理。
  • sqlite3用于保存用户添加/删除的块。
  • tinycthread用于跨平台线程。

编码愉快!

赞(0)
未经允许不得转载:srcmini » 如何在Ubuntu 19.04中使用现代OpenGL使用C实现自己的Minecraft游戏克隆

评论 抢沙发

评论前必须登录!