Stack Game
Intro
写这个是因为自己和同学尝试用unity实现这个游戏。 核心的算法就在与动态的生成方块,并且在点击时即时的断裂。
实现方法
我借鉴了Procedural Generation中的地图的mesh随机产生的方法,使用mesh filter即时的根据长宽来计算mesh。
类
顶点
1 | public class Node{ |
这2个结构体,第一个是基本的顶点,然而即时生成的cube拥有8个顶点,我们并不想使用8个node去计算,因此使用了controlNode来记录cube的上表面(y轴正方向),其余的顶点使用bottom来记录。
面
1 | public class Square{//面包含4个顶点 |
按照顺时针的顺序来将每4个顶点构成一个面。
Triangles
1 | struct Triangle{ |
三角形面在通过meshfilter生成具体的模型的时候使用,将Square按照一定的顺序来生成。由于直接用于filter的triangles,故其内部的点的类型并非Node而是int,类似一种索引。
ControlNode
1 | public class controlNode:Node{ |
继承自node类,多出一个bottom用来记录下方的点。此子类主要用于游戏的实时生成断开的cube的时候记录位置使用。
具体的算法
生成Cube
1 | void createCube(float length, float width){ |
squares是一个定义好的储存Square的List。
Triangles的生成
1 | void CreateTriangles(Node a,Node b,Node c){ |
分为3个部分
- 直接将node类型作为参数传入,将Node类中的vertexindex加入triangles的List。
- 通过判定传入的Node参数数量,按照一定的顺序将Square转化为triangles,这里写了如果不是正方形面之后的顺序,顺序可以自定,按照一定的方向不要有反向和重复即可。可以看出triangles和vertices的关系,其在list中的顺序即是点和其所在面的关系。
- 直接在Generate中调用的方法,传入Square类型即可。
UV的生成
1 | void caculateUV(Square square){ |
uv的生成就非常的简单了,直接按照自定的顺序将一个面的4个点的坐标加入list即可。
GenerateCube
1 | public void GenerateCube(float length,float width){//x dir -> length,z dir -> width |
最初的判断忽略,后期为了提高难度加的一个变速,加上之后速度受长宽的影响,只是简单的测试,并不一定难度合理。 Generate的顺序也是非常明显,即先生成Square之后再按照list中的顺序存在vertices和triangles里,最后生成uv即可。调用meshfilter生成,并将rigid body 加上。
游戏逻辑
- 主要就是一些方向的判断,具体的生成直接调用cubemeshGenerator的方法即可。其次是一些游戏效果的实现,相机正交这个肯定不用多说,其次是一个combo的记录和背景颜色和cube颜色的渐变。这里使用rgba效果不好,故采用HSV来实现,在unity,ps里都能通过调色板来看hsv的特点。
- 其次一点是cube的断裂效果,我采用的方式是记录上次cube的controlNode的位置来实现的,去判定接受到点击指令时的当前的cube的controlNode和记录的cube的controlNode,通过cube的移动方向来生成新的8个点(这里我采用的记录长宽,即是坐标的差值),再次调用GenerateCube并确定生成的位置(y轴不变,x、z由分开的8个点计算)。如图所示,红色和蓝色的点进行计算即可。
- 对于cube位置的矫正,如果完全重合才能触发combo,游戏难度过于高,因此通过在断开cube的时候来判定2个cube在运动方向上的距离是否小于设置的临界值(superposition)即可,如果小于即算是触发了combo,在显示效果即是不断开即可。