IOS游戏开发之五子棋OC版_IOS

先上效果图

- 功能展示

- 初高级棋盘切换效果

实现思路及主要代码详解

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
, ios五子棋代码
, 五子棋源码
五子棋c语言代码
五子棋游戏开发、c 五子棋游戏开发、ios开发js和oc交互、ios开发用oc还是swift、ios healthkit开发 oc,以便于您获取更多的相关知识。

时间: 2024-08-30 21:30:36

IOS游戏开发之五子棋OC版_IOS的相关文章

当 iOS 游戏开发像做份沙拉那么简单

写在所有之前:这个工具更适合没有编码基础又喜欢折腾的设计师们,并不一定适合开发者. 当你有一个好的游戏创意却因没有代码基础而搁浅时,是不是很期待一款这样的软件,让iOS游戏开发变得像做份沙拉那么简单?现在GameSaladInc.就为我们提供了这样一个便利的开发工具GameSalad.   简单介绍一下GameSalad:这是一款可视化编程的游戏引擎,使用者无需编码就能为iPhone, iPad, Mac和Web来设计,发布和分销原创游戏,简单易上手,很适合交互和视觉.开发完成的游戏可以通过云端

开发者经验谈:如何一天时间搞定iOS游戏开发?

开发者经验谈:如何一天时间搞定iOS游戏开发? 在一天时间里将完成iPhone游戏开发由梦想变为现实? 本文作者给出了从创意转变成现实的详细答案.使用苹果原生游戏引擎SpriteKit,遵循一定的原则可以保证开发顺利进行,最大程度避免意外情况的发生. CSDN移动将持续为您优选移动开发的精华内容,共同探讨移动开发的技术热点话题,涵盖移动应用.开发工具.移动游戏及引擎.智能硬件.物联网等方方面面.如果您想投稿.参与内容翻译工作,或寻求近匠报道,请发送邮件至tangxy#csdn.net(请把#改成

《Android 游戏开发大全(第二版)》——6.5节闯关动作类游戏

6.5 闯关动作类游戏 Android 游戏开发大全(第二版) 这里要介绍的闯关动作类游戏,是区别于射击类游戏和格斗游戏的,闯关动作类游戏的节奏一般比较轻快,玩家的成就感主要来源于完成一个个关卡的挑战胜利,更具趣味性.闯关类动作游戏的设计重点不在战斗,而是在闯关,这样适应的玩家人群会更广,比较经典的闯关类动作游戏有"超级玛丽"(如图6-8所示)和冒险岛(如图6-9所示)等. 6.5.1 游戏玩法 玩家人数 玩家玩闯关动作类游戏的主要目标一般都在于过关斩将,并不十分需要别的玩家的阻挠或协

《Android 游戏开发大全(第二版)》——6.3节益智类游戏

6.3 益智类游戏 Android 游戏开发大全(第二版) 益智游戏(Puzzle Game)是另外一种深受用户欢迎的游戏类型,很多人把益智游戏称作休闲游戏,但实际上很多益智游戏玩起来并不会很"休闲",如一些需要频繁思考的诸如数独之类的游戏.而休闲游戏中很大一部分游戏并不属于"益智"的范畴,如后面会提到的养成类游戏一般也划为休闲游戏. 益智类游戏的特色就是,游戏中会更多地依靠智力去解决问题,而现实生活中能够锻炼智力的游戏有很多,如纸牌类游戏.棋类游戏等都属于益智类游

《Android 游戏开发大全(第二版)》——6.1节射击类游戏

6.1 射击类游戏 Android 游戏开发大全(第二版) 射击类游戏(Shooting Game)是一种比较古老的游戏类型,手机游戏中的射击游戏也很流行,目前市面上的射击类游戏最多的是飞行射击游戏,比较著名的有雷电系列,还有一些是诸如坦克大战之类的操作性要求较高的射击游戏,本小节就来简单介绍一下射击类手机游戏的相关知识. 6.1.1 游戏玩法 下面从玩家人数.操作方式和取胜条件等几个方面分析射击类游戏的玩法. 玩家人数 射击类游戏通常为单人游戏,很少以二人对战或多人在线的方式进行,而且一般来说

《Android 游戏开发大全(第二版)》——6.4节角色扮演游戏

6.4 角色扮演游戏 Android 游戏开发大全(第二版) 角色扮演游戏(Role Playing Game)是手机游戏中的另外一个大阵营,不同于益智游戏等即时性的游戏,角色扮演游戏一般要求玩家投入较多的注意力和较长的关注时间,同时一款优秀的角色扮演游戏的开发投入也相对较高. 6.4.1 游戏玩法 玩家人数 电脑平台下的角色扮演游戏即有单机版的,也有局域网对战版和网络多人在线形式的,手机平台下角色扮演游戏也不局限于单人模式,很多的大型网络在线手机游戏都是角色扮演性质的,但是论数量,还是单击模式

《Android 游戏开发大全(第二版)》——6.7节策略游戏

6.7 策略游戏 Android 游戏开发大全(第二版) 手机平台下的策略游戏来源于电脑端的策略游戏,其最初是模拟类游戏的一个分支.随着策略游戏的不断发展,其也衍生出了很多其他不同的形式,如回合制策略游戏和即时策略游戏.通常,即时战略游(Real-Time Strategy)也被认为是从策略游戏发展而来. 6.7.1 游戏玩法 玩家个数 在其他游戏中,玩家往往通过在游戏中控制一个角色来参与游戏,而在策略游戏中,玩家常常没有具体的角色,或者说玩家控制不止一个角色.在策略游戏中玩家扮演的角色是统筹各

《Android 游戏开发大全(第二版)》——6.10节体育类游戏

6.10 体育类游戏Android 游戏开发大全(第二版)体育类游戏是面向体育爱好者的一类游戏,虽然拥有的玩家群体不如角色扮演或益智类游戏多,但是体育类游戏还是在众多的手机游戏种类中因独特的内容题材占有一席之地. 6.10.1 游戏玩法玩家人数由于手机平台下的局限性,一般的体育类游戏都为单机模式,即玩家进行体育竞技的对象是电脑AI,这时游戏的可玩性很大程度上取决于AI的真实程度. 取胜方式体育类游戏主要是模仿现实中体育竞技运动,所以取胜方式就是赢得比赛的胜利,或根据剧情需要赢得一系列比赛的胜利,

《Android 游戏开发大全(第二版)》——6.2节竞速类游戏

6.2 竞速类游戏Android 游戏开发大全(第二版)竞速类游戏不同于其他类型的游戏,竞速类游戏的内容比较单一,就是驾驶一种交通工具进行比赛.竞速游戏主要吸引玩家的地方在于令玩家体会到高速移动时所带来的视觉和听觉上的享受,以及冲破重重障碍到达终点的成就感. 对于目前手机平台下的竞速游戏来说,大部分使用的比赛交通工具为赛车,很少有竞速游戏会采用宇宙飞船或是舰艇等作为比赛工具. 6.2.1 游戏玩法玩家个数手机平台下的竞速游戏不能像电脑游戏那样方便地进行局域网互联,所以主要以单机版的竞速游戏为主,