主要参考:http://blog.csdn.net/kobbbb/article/details/8900974
绘制了俄罗斯方块,进行unity的入门学习。
结果如下:
基本功能实现了。
总结如下:
1.Unity和DX类似,默认左手坐标系。旋转和绘制时候为顺时针方向。
2.注意Manger、myCube、block1,block2....之间的关系
其中myCube为绘制的基本单元,block1等形状也是由myCube来组合绘制的。如图2-2中,block1属性中只是进行了逻辑上绘制的设计,并没有真正的render,在cs脚本里,最后还是有myCube进行Instance操作,进行字符串中‘1’的判断,组合绘制的Block1.....
而Manger作为一个空的GameObject,对整体进行控制,其中组合了七种形态,并加载了myCube,来进行真正的绘制。
图2-1 图2-2
3.区分静止的block绘制和动态下降的block绘制
IEnumerator Fall(){ while(true) { mYPosition--;//block下落, if (true == Manager.manager.CheckBlock(blockMatrix, mXPosition, mYPosition))//如果碰壁,下落停止 { Manager.manager.SetBlock(blockMatrix, mXPosition, mYPosition + 1);//绘制静态的block,并在SetBlock内初始化一个新的block Destroy(gameObject);//删除此次动态的block, break;//这个block消亡了,进行新的block下落 } for(float i=mYPosition+1;i>mYPosition;i-=Time.deltaTime*mFallSpeed)//平稳的下落一个单位,以时间为控制,而不受帧率的控制 { transform.position = new Vector3(transform.position.x, i - childSize, transform.position.z); yield return null;//等待下一帧进行下落... } } }
4.场景坐标系以及每个动态Block的初始化坐标
本例有本地坐标系和世界坐标系之分。
图4-1
如上图4-1,Block作为一个GameObject,需要确定一个Transform,并且为所有子集的中心。进行初始化:
blockSize = block.Length;//此次长度为3 childSize = (blockSize - 1) * 0.5f; blockMatrix = new bool[blockSize,blockSize];//建立对应元素的bool数组,来进行是否绘制myBlock的判断 for (int y = 0; y < blockSize;y++ ) { for (int x = 0; x < blockSize;x++ ) { if (block[y][x]==‘1‘)//如果element中字符为‘1‘,则clone一个myCube,实质性的绘制 { blockMatrix[y,x] = true; //每个cube相对与父结点的位置,即在本地坐标系下进行cube的绘制 var cube = (Transform)Instantiate(Manager.manager.oneCube, new Vector3(x - childSize, childSize - y, 0), Quaternion.identity); cube.parent = transform;//绑定到父结点上去 } } } mYPosition = Manager.manager.GetFieldHeight() - 1; //初始化block的位置,和左上角的位置mYPosition mXPosition; transform.position = new Vector3(Manager.manager.GetFieldWidth() / 2 + (blockSize % 2 == 0 ? 0.5f : 0), mYPosition - childSize, 0); mXPosition = (int)(transform.position.x - childSize);//如下图,代表了在整个场景中,一个动态的Block在下落时的坐标
图4-2
public void SetBlock(bool[,] blockMatrix, int posX, int posY)//在静止区域绘制相应的block { int size = blockMatrix.GetLength(0); // 判断下降时,静止,那么则进行静止绘制: for (int y = 0; y < size;y++ )// { for (int x = 0; x < size;x++ ) { if (true==blockMatrix[y,x]) { Instantiate(oneCube, new Vector3(posX+x, posY-y, 0), Quaternion.identity);//绘制此次静止的block fieldsJudge[posX + x, posY - y] = true; } } } //此block静止之后: 1.检测行是否满足消去? 2.生成新的动态block... StartCoroutine(CheckRows(posY-size,size)); }
Instantiate(oneCube, new Vector3(posX+x, posY-y, 0), Quaternion.identity);其中:
Vector3(posX+x, posY-y, 0)可有4-2可知,每个Cube的绘制都需要对应自己的坐标,这次坐标为世界坐标系下的。
5.俄罗斯方块的整体流程
1.在Manger.cs里随机初始化一个block,CreateBlock(int random)
2.对这个block,根据string的‘1‘,进行myBlock实例化,并设定这个block的transform,
3.下降...判断是否静止?...是的,则绘制静态的block,并Create新的动态block,删除先前的动态block
4.重复以上过程...
其中不好理解的是:代码中本地坐标系和子结点的关系、每个block的位置信息
下一章记录本次使用的Unity语法。
时间: 2024-10-31 23:20:06