FKGameService类是整个游戏逻辑实现的核心它是一个可以复用的业务逻辑类它与游戏实现平台无关其实现原理与《疯狂Android讲义》书中Android版《疯狂连连看》游戏中GameService的实现原理相同。

13.6.1 定义FKGameService的接口代码


根据前面程序对FKGameService对象的依赖程序需要FKGameService对象包含如下方法。

start初始化游戏状态开始游戏的方法。

hasPieces判断FKPiece二维数组中是否还剩下FKPiece对象如果所有的FKPiece都被消除了游戏就算胜利。

(FKPiece*) findPieceAtTouchX:(CGFloat) touchX touchY:(CGFloat)touchY根据触碰点的XY坐标来获取FKPiece

(FKLinkInfo*) linkWithBeginPiece:(FKPiece*)p1 endPiece: (FKPiece*)p2判断p1p2两个方块是否可以相连。

FKGameService类定义的接口部分代码如下。

程序清单codes/13/Link/Link/sources/board/FKGameService.h

wKiom1MEB87Rnm-rAANz6s29T5A547.jpg


13.6.2 实现FKGameService


FKGameService组件的前两个方法实现起来都比较简单。

程序清单codes/13/Link/Link/sources/board/FKGameService.m

wKioL1MEB8Og96kVAANKG1EQxEA375.jpg

面三个方法的实现都很简单相信读者很容易理解。下面详细介绍剩下的两个方法的实现。


13.6.3 获取触碰点的方块


当用户触碰游戏界面时事件监听器获取的是该触碰点在游戏界面上的XY坐标但程序需要获取用户触碰的到底是哪个方块。因此程序必须把界面上的XY坐标换算成在FKPiece二维数组中的两个索引值。

考虑到游戏界面上每个方块的宽度、高度都是相同的因此想将界面上的XY坐标换算成FKPiece二维数组中的索引也比较简单只要用XY坐标值除以图片的宽、高即可。下面的方法是根据触碰点XY坐标获取对应方块的代码。

程序清单codes/13/Link/Link/sources/board/FKGameService.m

wKiom1MEB_7Az6PTAAQNSEwos4k173.jpg

上面的方法中两行粗体字代码用于根据触碰点XY坐标来计算它在FKPiece二维数组中的索引值。该方法调用了getIndexWithRelateive:size:进行计算。

getIndexWithRelateive:size:方法的实现就是用relative除以size只是程序需要判断可以整除和不能整除两种情况如果可以整除说明还在前一个方块内如果不能整除则对应于下一个方块。下面是getIndexWithRelateive:size:方法的代码。

程序清单codes/13/Link/Link/sources/board/FKGameService.m

wKioL1MEB-nhUO2OAAJN6VOARJc572.jpg


13.6.4 判断两个方块是否可以相连


判断两个方块是否可以相连是本程序需要处理的最烦琐的地方因为两个方块可以相连的情形比较多大致可分为如下情况。

两个方块位于同一条水平线可以直接相连。

两个方块位于同一条竖直线可以直接相连。

两个方块以两条线段相连也就是有1个拐角。

两个方块以三条线段相连也就是有2个拐角。

- (FKLinkInfo*)linkWithBeginPiece:(FKPiece*)p1 endPiece:(FKPiece*)p2方法把这4种情况分开进行处理代码如下。

程序清单codes/13/Link/Link/sources/board/FKGameService.m

wKiom1MECCmAuAebAAL7f25PgsU219.jpg

wKiom1MECDHwe1l8AAO316Ilo9I405.jpg

程序中的4处粗体字代码分别代表两个方块位于同一条水平线可直接相连、两个方块位于同一条竖直线可直接相连、两个方块需要两条线相连、两个方块需要3条线相连。上面的方法分别考虑了这4种情况但程序还需要为这4个方法提供实现。

为了实现上面4个方法可以对两个Piece的位置关系进行归纳。

p1p2在同一行indexY值相同。

p1p2在同一列indexX值相同。

p2p1的右上角p2indexX >p1indexXp2indexY < p1indexY

p2p1的右下角p2indexX >p1indexXp2indexY > p1indexY

至于p2p1的左上角以及p2p1的左下角这两种情况程序可以重新执行linkWithBeginPiece: endPiece:方法将p1p2两个参数的位置互换即可。


——————本文节选自《疯狂ios讲义上》
090911_mzHb_262659.jpg