IOS游戏开发之五子棋OC版
程序员文章站
2023-12-16 19:10:58
先上效果图
- 功能展示
- 初高级棋盘切换效果
实现思路及主要代码详解
1.绘制棋盘
利用quartz2d绘制棋盘.代码如下
- (void)...
先上效果图
- 功能展示
- 初高级棋盘切换效果
实现思路及主要代码详解
1.绘制棋盘
利用quartz2d绘制棋盘.代码如下
- (void)drawbackground:(cgsize)size{ self.gridwidth = (size.width - 2 * kboardspace) / self.gridcount; //1.开启图像上下文 uigraphicsbeginimagecontext(size); //2.获取上下文 cgcontextref ctx = uigraphicsgetcurrentcontext(); cgcontextsetlinewidth(ctx, 0.8f); //3.1 画16条竖线 for (int i = 0; i <= self.gridcount; i ++) { cgcontextmovetopoint(ctx, kboardspace + i * self.gridwidth , kboardspace); cgcontextaddlinetopoint(ctx, kboardspace + i * self.gridwidth , kboardspace + self.gridcount * self.gridwidth); } //3.1 画16条横线 for (int i = 0; i <= self.gridcount; i ++) { cgcontextmovetopoint(ctx, kboardspace, kboardspace + i * self.gridwidth ); cgcontextaddlinetopoint(ctx, kboardspace + self.gridcount * self.gridwidth , kboardspace + i * self.gridwidth); } cgcontextstrokepath(ctx); //4.获取生成的图片 uiimage *image=uigraphicsgetimagefromcurrentimagecontext(); //5.显示生成的图片到imageview uiimageview * imageview = [[uiimageview alloc]initwithimage:image]; [self addsubview:imageview]; uigraphicsendimagecontext(); }
2.点击棋盘落子
1)根据落子位置求出该棋子的行号与列号.
2)判断落子位置是否已经有棋子,有则不能下.如果没有,将棋子保存在字典中,以列号和行号组合起来的字符串为key值.
代码如下:
//点击棋盘,下棋 - (void)tapboard:(uitapgesturerecognizer *)tap{ cgpoint point = [tap locationinview:tap.view]; //计算下子的列号行号 nsinteger col = (point.x - kboardspace + 0.5 * self.gridwidth) / self.gridwidth; nsinteger row = (point.y - kboardspace + 0.5 * self.gridwidth) / self.gridwidth; nsstring * key = [nsstring stringwithformat:@"%ld-%ld",col,row]; if (![self.chessmandict.allkeys containsobject:key]) { uiview * chessman = [self chessman]; chessman.center = cgpointmake(kboardspace + col * self.gridwidth, kboardspace + row * self.gridwidth); [self addsubview:chessman]; [self.chessmandict setvalue:chessman forkey:key]; self.lastkey = key; //检查游戏结果 [self checkresult:col androw:row andcolor:self.isblack]; self.isblack = !self.isblack; } }
3.检测游戏结果
每落一个棋子就要多游戏结果进行一次检查,判断四个方向上是否有大于等于5个同色的棋子连成一线,有则提示游戏输赢结果,无则游戏继续.算法为,从当前棋子位置向前遍历,直到遇到与自己不同色的棋子,累加同色棋子的个数,再往后遍历,直到遇到与自己不同色的棋子,累加同色棋子的个数.得到该方向相连同色棋子的总个数
代码如下
//判断是否大于等于五个同色相连 - (bool)checkresult:(nsinteger)col androw:(nsinteger)row andcolor:(bool)isblack anddirection:(gmkdirection)direction{ if (self.samechessmanarray.count >= 5) { return yes; } uicolor * currentchessmancolor = [self.chessmandict[[nsstring stringwithformat:@"%ld-%ld",col,row]] backgroundcolor]; [self.samechessmanarray addobject:self.chessmandict[self.lastkey]]; switch (direction) { //水平方向检查结果 case gmkhorizontal:{ //向前遍历 for (nsinteger i = col - 1; i > 0; i --) { nsstring * key = [nsstring stringwithformat:@"%ld-%ld",i,row]; if (![self.chessmandict.allkeys containsobject:key] || [self.chessmandict[key] backgroundcolor] != currentchessmancolor) break; [self.samechessmanarray addobject:self.chessmandict[key]]; } //向后遍历 for (nsinteger i = col + 1; i < kgridcount; i ++) { nsstring * key = [nsstring stringwithformat:@"%ld-%ld",i,row]; if (![self.chessmandict.allkeys containsobject:key] || [self.chessmandict[key] backgroundcolor] != currentchessmancolor) break; [self.samechessmanarray addobject:self.chessmandict[key]]; } if (self.samechessmanarray.count >= 5) { [self alertresult]; return yes; } [self.samechessmanarray removeallobjects]; } break; case gmkvertical:{ //向前遍历 for (nsinteger i = row - 1; i > 0; i --) { nsstring * key = [nsstring stringwithformat:@"%ld-%ld",col,i]; if (![self.chessmandict.allkeys containsobject:key] || [self.chessmandict[key] backgroundcolor] != currentchessmancolor) break; [self.samechessmanarray addobject:self.chessmandict[key]]; } //向后遍历 for (nsinteger i = row + 1; i < kgridcount; i ++) { nsstring * key = [nsstring stringwithformat:@"%ld-%ld",col,i]; if (![self.chessmandict.allkeys containsobject:key] || [self.chessmandict[key] backgroundcolor] != currentchessmancolor) break; [self.samechessmanarray addobject:self.chessmandict[key]]; } if (self.samechessmanarray.count >= 5) { [self alertresult]; return yes; } [self.samechessmanarray removeallobjects]; } break; case gmkobliquedown:{ //向前遍历 nsinteger j = col - 1; for (nsinteger i = row - 1; i >= 0; i--,j--) { nsstring * key = [nsstring stringwithformat:@"%ld-%ld",j,i]; if (![self.chessmandict.allkeys containsobject:key] || [self.chessmandict[key] backgroundcolor] != currentchessmancolor || j < 0) break; [self.samechessmanarray addobject:self.chessmandict[key]]; } //向后遍历 j = col + 1; for (nsinteger i = row + 1 ; i < kgridcount; i++,j++) { nsstring * key = [nsstring stringwithformat:@"%ld-%ld",j,i]; if (![self.chessmandict.allkeys containsobject:key] || [self.chessmandict[key] backgroundcolor] != currentchessmancolor || j > kgridcount) break; [self.samechessmanarray addobject:self.chessmandict[key]]; } if (self.samechessmanarray.count >= 5) { [self alertresult]; return yes; } [self.samechessmanarray removeallobjects]; } break; case gmkobliqueup:{ //向前遍历 nsinteger j = col + 1; for (nsinteger i = row - 1; i >= 0; i--,j++) { nsstring * key = [nsstring stringwithformat:@"%ld-%ld",j,i]; if (![self.chessmandict.allkeys containsobject:key] || [self.chessmandict[key] backgroundcolor] != currentchessmancolor || j > kgridcount) break; [self.samechessmanarray addobject:self.chessmandict[key]]; } //向后遍历 j = col - 1; for (nsinteger i = row + 1 ; i < kgridcount; i++,j--) { nsstring * key = [nsstring stringwithformat:@"%ld-%ld",j,i]; if (![self.chessmandict.allkeys containsobject:key] || [self.chessmandict[key] backgroundcolor] != currentchessmancolor || j < 0) break; [self.samechessmanarray addobject:self.chessmandict[key]]; } if (self.samechessmanarray.count >= 5) { [self alertresult]; return yes; } [self.samechessmanarray removeallobjects]; } break; } return no; }
对外提供,重新开始,悔棋,切换初高级棋盘的三个接口
重新开始
- (void)newgame{ self.isover = no; self.lastkey = nil; [self.samechessmanarray removeallobjects]; self.userinteractionenabled = yes; [self.chessmandict removeallobjects]; for (uiview * view in self.subviews) { if ([view iskindofclass:[uiimageview class]]) { continue; } [view removefromsuperview]; } self.isblack = no; }
悔棋
//撤回至上一步棋 - (void)backonestep:(uibutton *)sender{ if(self.isover) return; if (self.lastkey == nil) { sender.enabled = no; cgfloat width = screen_width * 0.4 * screen_width_ratio; uiview * tip = [[uiview alloc]initwithframe:cgrectmake(0, 0, width, 0.6 * width)]; tip.backgroundcolor = [uicolor colorwithwhite:1 alpha:0.8]; tip.layer.cornerradius = 8.0f; [self addsubview:tip]; tip.center = cgpointmake(self.width * 0.5, self.height * 0.5); uilabel * label = [[uilabel alloc]init]; label.text = self.chessmandict.count > 0 ? @"只能悔一步棋!!!" : @"请先落子!!!"; label.font = [uifont systemfontofsize:15]; [label sizetofit]; label.center = cgpointmake(tip.width * 0.5, tip.height * 0.5); [tip addsubview:label]; self.userinteractionenabled = no; dispatch_after(dispatch_time(dispatch_time_now, (int64_t)(2.0 * nsec_per_sec)), dispatch_get_main_queue(), ^{ self.userinteractionenabled = yes; sender.enabled = yes; [tip removefromsuperview]; }); return; } [self.chessmandict removeobjectforkey:self.lastkey]; [self.subviews.lastobject removefromsuperview]; self.isblack = !self.isblack; self.lastkey = nil; }
切换初高级键盘
//改变键盘级别 - (void)changeboardlevel{ for (uiview * view in self.subviews) { [view removefromsuperview]; } [self newgame]; self.ishighlevel = !self.ishighlevel; [self drawbackground:self.bounds.size]; }
demo中的一个小技巧
用字典存放棋子,以棋子的列号和行号组合起来的字符串为key值,value值为棋子view.这样处理,在判断某行某列是否有棋子就非常简单了。
总结
以上就是ios游戏开发之五子棋oc版的全部内容,希望本文对大家开发ios有所帮助,如果本文有不足之处,欢迎大家提供建议和指点!
推荐阅读
-
IOS游戏开发之五子棋OC版
-
IOS游戏开发之五子棋OC版
-
Unity3D开发实战之五子棋游戏
-
iOS开发之OC与swift开发混编教程,代理的相互调用,block的实现。OC调用Swift中的代理, OC调用Swift中的Block 闭包
-
iOS开发之常用资讯类App的分类展示与编辑的完整案例实现(Swift版)
-
iOS开发之Unity游戏在iOS平台运行调研(踩坑)
-
Unity3D开发实战之五子棋游戏
-
iOS开发之常用资讯类App的分类展示与编辑的完整案例实现(Swift版)
-
iOS开发之OC与swift开发混编教程,代理的相互调用,block的实现。OC调用Swift中的代理, OC调用Swift中的Block 闭包
-
iOS开发之Unity游戏在iOS平台运行调研(踩坑)