【qboy】原创 2013年3月10日
最近有一个想法就是把以前做过我东西都把他以博客的形式写出来,不管对不对,让各位大牛们指点指点。本来想先写”水管猫“的,后来想想先写”宝石迷阵“吧。
一、游戏背景
玩过《宝石迷阵》游戏的人都知道,这其实是一款很简单的游戏。通过交换相临的两个元素(或者叫宝石,以下统一为元素),以便实现在行或者列中达到相同元素在3个或者3个以上,从迷阵中消去,并补充消去元素,这就是《宝石迷阵》类游戏的核心玩法。所有的该类游戏的玩法都是以上的变形,例如增加道具消去一行一纵、消去相同类元素等,这就看各个游戏策划人员如何去策划了。
下图就是一个简单的《宝石迷阵》,用数字代表不同的元素。
二、游戏中的算法
我不是一个游戏的策划人员,游戏的外围在此我就不多说了。
整个游戏的流程应该如下图所示:
整个游戏的核心都在那几次判断中。接下去我一把这几次的判断方法进行描述:
1、是否在在可消去元素
这只要在游戏地图中(用二维数组表示),遍历每行和每列是否存在相邻元素达到三个或者三个以上的。为了避免重复,我们规定只向右和向下判断。代码如下:
-(NSMutableArray *)getWinStoneInMap
{
NSMutableArray *arr=[NSMutableArray array];
for (int i = 0; i<hCount; i++) {
for (int j = 0; j<wCount;j++) {
StoneSprite * curStone = stoneArr[i][j];
StoneType curType =curStone.StoneType;
//向右
int k = j+1;
if (k<wCount) {
for (; k<wCount; k++) {
if (curType != stoneArr[i][k].StoneType) {
break;
}
}
if (k-j>=3) {//相同的元素是否大于3个
for (int m = j; m<k; m++) {
if (![arr containsObject:stoneArr[i][m]]) {
[arr addObject:stoneArr[i][m]];
}
}
}
}
//向下
k = i+1;
if(k<hCount)
{
for (; k<hCount; k++) {
if (curType !=stoneArr[k][j].StoneType) {
break;
}
}
if (k-i>=3) {
for (int n = i; n<k; n++) {
if (![arr containsObject:stoneArr[n][j]]) {
[arr addObject:stoneArr[n][j]];
}
}
}
}
}
}
return arr;
}
2、判断是否存在可移动元素
在这个方法中,当初为了简单,只是对上面的方法进行了一下调用。首先交换一下相邻元素,再调用上面的方法,有则返回true,无则继续。
-(bool)checkHasMove
{
StoneSprite *temp;
bool hasmove = false;
for (int i = 0; i<hCount && !hasmove; i++) {
for (int j = 0; j<wCount &&!hasmove; j++) {
if (j<wCount-1) {//与右边的进行交换
temp = stoneArr[i][j];
stoneArr[i][j]=stoneArr[i][j+1];
stoneArr[i][j+1] = temp;
NSMutableArray *arr = [self getWinStoneInMap];
temp = stoneArr[i][j];
stoneArr[i][j]=stoneArr[i][j+1];
stoneArr[i][j+1] = temp;
if ([arr count] > 0) {
hasmove = YES;
break;
}
}
if (i<hCount-1) {//与下面的进行交换
temp = stoneArr[i][j];
stoneArr[i][j]=stoneArr[i+1][j];
stoneArr[i+1][j] = temp;
NSMutableArray *arr = [self getWinStoneInMap];
temp = stoneArr[i][j];
stoneArr[i][j]=stoneArr[i+1][j];
stoneArr[i+1][j] = temp;
if ([arr count] > 0) {
hasmove = YES;
break;
}
}
}
}
return hasmove;
}
三、不完善之处
在整个游戏中,很多地方都进行了整个游戏地图的遍历。但是这有些时候并没有必要这么做,比如在交换之后,我们只需要判断交换元素所在的行与列,这对游戏的遍历效率应该会有很大的提高。