Skip to content

0x-zeros/Craft

 
 

Repository files navigation

Craft

适用于Windows、Mac OS X和Linux的Minecraft克隆版。仅使用几千行C代码,采用现代OpenGL(着色器)实现。包含基于Python服务器的在线多人游戏支持。

http://www.michaelfogleman.com/craft/

截图

特性

  • 使用柏林/辛普森噪声生成简单但美观的地形。
  • 超过10种方块类型,可以轻松添加更多。
  • 支持植物(草、花、树等)和透明效果(玻璃)。
  • 天空中的简单云朵(不会移动)。
  • 昼夜循环和带纹理的天空穹顶。
  • 世界变化持久化存储在sqlite3数据库中。
  • 多人游戏支持!

下载

Mac和Windows二进制文件可在网站上获取。

http://www.michaelfogleman.com/craft/

从源码运行请参见下文。

安装依赖

Mac OS X

如果还没有安装CMake,请下载并安装。 您可以使用Homebrew简化安装过程:

brew install cmake 

Linux (Ubuntu)

sudo apt-get install cmake libglew-dev xorg-dev libcurl4-openssl-dev sudo apt-get build-dep glfw 

Windows

下载并安装CMakeMinGW。将C:\MinGW\bin添加到您的PATH环境变量中。

下载并安装cURL,确保 CURL/lib和CURL/include位于Program Files目录中。

使用以下命令替代下一节中描述的命令。

cmake -G "MinGW Makefiles" mingw32-make 

编译和运行

一旦您有了依赖项(见上文),在终端中运行以下命令。

git clone https://github.com/fogleman/Craft.git cd Craft cmake . make ./craft 

多人游戏

经过多年,craft.michaelfogleman.com已经下线。有关自托管的信息,请参见服务器部分。

客户端

您可以使用命令行参数连接到服务器...

./craft [主机 [端口]]

或者,在游戏中使用"/online"命令。

/online [主机 [端口]] 

服务器

您可以运行自己的服务器或连接到我的服务器。服务器用Python编写, 但需要编译的DLL,以便像客户端一样执行地形生成。

gcc -std=c99 -O3 -fPIC -shared -o world -I src -I deps/noise deps/noise/noise.c src/world.c python server.py [主机 [端口]]

控制

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

聊天命令

/goto [名称] 

传送到另一个用户。 如果未指定名称,则随机选择一个用户。

/list 

显示已连接用户的列表。

/login 名称 

切换到另一个已注册的用户名。 将重新联系登录服务器。用户名区分大小写。

/logout 

取消身份验证并成为访客用户。 在重新发出/login命令之前,不会再次自动登录。

/offline [文件] 

切换到离线模式。 文件指定要使用的保存文件,默认为"craft"。

/online 主机 [端口] 

连接到指定的服务器。

/pq P Q 

传送到指定的区块。

/spawn 

传送回出生点。

截图

截图

实现细节

地形生成

地形使用辛普森噪声生成 - 基于位置种子的确定性噪声函数。因此,在给定位置的世界总是以相同的方式生成。

世界在XZ平面(Y向上)上分为32x32方块的区块。这允许世界"无限"(目前在大X或Z值处浮点精度是个问题),也使数据管理更容易。只有可见的区块需要从数据库查询。

渲染

只渲染暴露的面。这是一个重要的优化,因为绝大多数方块要么完全隐藏,要么只暴露一两个面。每个区块为每个相邻区块记录一个方块宽度的重叠,以便知道其周边哪些方块是暴露的。

只渲染可见的区块。使用简单的视锥剔除方法来测试区块是否在相机的视野中。如果不在,则不渲染。这也带来了相当不错的性能提升。

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

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

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

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

数据库

用户对世界的更改存储在sqlite数据库中。只存储增量,所以默认世界是生成的,然后在加载时在顶部应用用户更改。

主数据库表名为"block",列名为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"表示"Chunk",(p, q)标识区块。key用于缓存 - 服务器只发送自客户端上次询问该区块以来执行的方块更新。方块更新(实时或作为区块请求的一部分)以格式发送给客户端: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用于跨平台线程。

About

A simple Minecraft clone written in C using modern OpenGL (shaders).

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C 80.9%
  • Python 16.9%
  • GLSL 1.6%
  • CMake 0.6%