这是在CSDN的第一篇博客,写博客的目的是记录学习C#和Unity引擎的经验。
已经在北京学习了2周多了,期间做过2次周作业:
第一次做了一个文字游戏Survive,技术含量不高,主要是用心做了剧情。
第二次做的是4人飞行棋,这篇博客主要总结做飞行棋的经验和教训。
总结分为: 教训、思路、代码三个部分。
一.教训
第二周的周二就开始着手画棋盘,经历下面阶段:
1.用做习题打印图形的办法,在控制台做了棋盘外圈,内圈一个个找点画出来(只想先画出来);
2.因为不知道外圈每个点坐标,又全部用手一个一个点画出来(想知道每个点的坐标);
3.设置一个起始点,以地图每个边的数量按不同方向走出一个地图,存入一维数组(if里有很长的判断条件);
4.周五听了老师用算法画回形地图,然后才发现一直没弄清楚标准的地图是怎样的,其实标准的地图是有规律的每个能被3整除的边是5格,其他都是4格,方向的改变也是有规律的,完全可以用算法解决,于是又研究算法寸入一维数组;
5.画完一维数组才发现没办法让4个玩家在不同起点开始,不同终点结束,咨询过李老师发现必须用2维数组画地图,然后用4个一维数组记录玩家的路径,于是周日上午一直在想二维数组怎么实现,时间就1天很焦虑,中午的时候和同学交流这个疑问时,发现可以先用EXCEL表格形象的画出二维数组再去研究算法,于是下午用之前算法的变体画出了地图。
在画棋盘的过程中真是把能踩的坑都踩了,造成这样的原因是一开头没有想明白结构和做法就埋头写代码,造成时间的浪费,同时也没有和同学老师及时交流设计思路,今后要先着眼于总体结构,然后再做好细节,勤于交流。
除了画地图,写代码中也有很多教训,其中最费时间找BUG的错误是写if else时忘记了写else,还有就是处理超过索引最大值得方法没有放在使用索引的第一个位置之前。这2个问题归根结底还是写代码的时候脑子里对逻辑结构没有清晰的思路。于是这个游戏很多想做的功能没有做出来,只做了跳步,一步一步走,越过终点退回三个功能,不过最重要的是有4个玩家可以一起玩。
还有一个重点,以后遇到问题一定要拆分问题,寻找规律,而且不能懒,以图形化的方式来帮助理解,这条真的挺重要。
二.思路
设计思路是先用一个算法走出地图并存入一个二维数组,然后通过不同4个切入点和起始方向记录4个玩家的行走路线,存入一维数组。用枚举做状态,都存在地图上,同一个状态按颜色名区分属于哪个玩家,以便后面判断玩家到达此位置该做什么操作。采用回合制让4个玩家轮流丢筛子前进,用一个每个回合加1的count记录回合数字,在最开始判断count%4,如果等于0是玩家1,以此类推。在所有判断结束后使用for循环来一步一步打印玩家的位置,for循环的次数是增加的步数。返回循环的开始用2个for循环打印地图和玩家位置。
三.代码
做完这个游戏最大的收获是对算法和二维数组的进一步理解。
下面是方向的算法,根据不同的起始方向进行判断。
newLoopCount是画地图框的次数,这里是12次。
startDirection是一个结构体,包含x和y轴。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public void CalDirection(int newLoopCount,Vector2 startDirection)//根据起始方向,画的次数来计算方向
{
if (newLoopCount <= 6 && newLoopCount % 2 != 0)
{
direction.x = startDirection.x;//1 0
direction.y = startDirection.y;//0 1
}
else if (newLoopCount <= 6 && newLoopCount != 2 && newLoopCount % 2 == 0 || newLoopCount > 6 && newLoopCount != 10 && newLoopCount != 12 && newLoopCount % 2 == 0)
{
direction.x = -startDirection.y;//0 -1
direction.y = startDirection.x;//1 0
}
else if (newLoopCount > 6 && newLoopCount % 2 != 0)
{
direction.x = -startDirection.x;//-1 0
direction.y = -startDirection.y;//0 -1
}
else if (newLoopCount == 2 || newLoopCount == 10|| newLoopCount == 12)
{
direction.x = startDirection.y;//0 1
direction.y = -startDirection.x;//-1 0
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
下面是设置地图数据的算法:
map是二维数组,存地图数据;
a,b是屏幕打印的起始点坐标;
indexX,indexY是起始点对应的二维数组的位置坐标;
startDirection是起始方向,可以是4个方向,例如从左至右是x=1,y=0;从上至下是x=0,y=1,从下至上是x=0,y=-1,从右至左是x=-1,y=0;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public void SetMapData(MapCell[,] map, int a, int b, int indexX, int indexY, Vector2 startDirection)//设置二维数组数据
{
int index = 0;
map[indexX, indexY].mapPosition.x = a;
map[indexX, indexY].mapPosition.y = b;
for (int i = 1; i <= loopCount; i++)
{
this.CalDirection(i, startDirection);
if (i % 3 == 0)//如果路径数能被3整除则画5个地图格
{
for (int j = 0; j < 5; j++)
{
int calState = index % 4;
switch (calState.ToString())
{
case "0":
map[indexX, indexY].mapState = MapState.GreenJump;
map[indexX, indexY].mapColor = Color.ForeGroundGreen;
break;
case "1":
map[indexX, indexY].mapState = MapState.YellowJump;
map[indexX, indexY].mapColor = Color.ForeGroundYellow;
break;
case "2":
map[indexX, indexY].mapState = MapState.BlueJump;
map[indexX, indexY].mapColor = Color.ForeGroundBlue;
break;
case "3":
map[indexX, indexY].mapState = MapState.RedJump;
map[indexX, indexY].mapColor = Color.ForeGroundRed;
break;
}
if (!(i == loopCount && j == 4))//当是最后一次循环的时候,索引不能再增加
{
index++;
indexX += direction.y;
indexY += direction.x;
map[indexX, indexY].mapPosition.x = map[indexX - direction.y, indexY - direction.x].mapPosition.x + direction.x;
map[indexX, indexY].mapPosition.y = map[indexX - direction.y, indexY - direction.x].mapPosition.y + direction.y;
}
}
}
else
{
for (int k = 0; k < 4; k++)
{
int calState = index % 4;
switch (calState.ToString())
{
case "0":
map[indexX, indexY].mapState = MapState.GreenJump;
map[indexX, indexY].mapColor = Color.ForeGroundGreen;
break;
case "1":
map[indexX, indexY].mapState = MapState.YellowJump;
map[indexX, indexY].mapColor = Color.ForeGroundYellow;
break;
case "2":
map[indexX, indexY].mapState = MapState.BlueJump;
map[indexX, indexY].mapColor = Color.ForeGroundBlue;
break;
case "3":
map[indexX, indexY].mapState = MapState.RedJump;
map[indexX, indexY].mapColor = Color.ForeGroundRed;
break;
}
index++;
indexX += direction.y;
indexY += direction.x;
map[indexX, indexY].mapPosition.x = map[indexX - direction.y, indexY - direction.x].mapPosition.x + direction.x;
map[indexX, indexY].mapPosition.y = map[indexX - direction.y, indexY - direction.x].mapPosition.y + direction.y;
}
}