android连连看开发技巧(12)
判断两个方块是否可以相连
在上一篇文章《android开发—连连看开发技巧(11)》我们讲解了如何获取触.碰.点的方块,那么当获取了触.碰.点之后我们要判断两个方块是否可以相连,下面来为大家讲解。
判断两个方块是否可以相连是本程序需要处理的最繁琐的地方:因为两个方块可以相连的情形比较多,大致可分为:
1、两个方块位于同一条水平线,可以直接相连。
2、两个方块位于同一条竖直线,可以直接相连。
3、两个方块的以两条线段相连,也就是有1个拐角。
4、两个方块的以三条线段相连,也就是有2个拐角。
下面link(Piece p1, Piece p2)方法把这四种情况分开进行处理,方法代码如下:
程序清单:codes18LinksrcorgcrazyitlinkoardimplGameServiceImpl.java
// 实现接口的link方法
@Override
public LinkInfo link(Piece p1, Piece p2)
{
// 两个Piece是同一个, 即选中了同一个方块, 返回null
if (p1.equals(p2))
return null;
// 如果p1的图片与p2的图片不相同, 则返回null
if (!p1.isSameImage(p2))
return null;
// 如果p2在p1的左边, 则需要重新执行本方法, 两个参数互换
if (p2.getIndexX() < p1.getIndexX())
return link(p2, p1);
// 获取p1的中心点
Point p1Point = p1.getCenter();
// 获取p2的中心点
Point p2Point = p2.getCenter();
// 如果两个Piece在同一行
if (p1.getIndexY() ==
p2.getIndexY()) //①
{
// 它们在同一行并可以相连
if (!isXBlock(p1Point, p2Point, GameConf.PIECE_WIDTH))
{
return new LinkInfo(p1Point, p2Point);
}
}
// 如果两个Piece在同一列
if (p1.getIndexX() ==
p2.getIndexX()) //②
{
if (!isYBlock(p1Point, p2Point, GameConf.PIECE_HEIGHT))
{
// 它们之间没有真接障碍, 没有转折点
return new LinkInfo(p1Point, p2Point);
}
}
// 有一个转折点的情况
// 获取两个点的直角相连的点, 即只有一个转折点
Point cornerPoint = getCornerPoint(p1Point,
p2Point,
GameConf.PIECE_WIDTH,
GameConf.PIECE_HEIGHT); //③
if (cornerPoint != null)
{
return new LinkInfo(p1Point, cornerPoint, p2Point);
}
// 该map的key存放第一个转折点, value存放第二个转折点,
// map的size()说明有多少种可以连的方式
Map turns =
getLinkPoints(p1Point,
p2Point, //④
GameConf.PIECE_WIDTH, GameConf.PIECE_WIDTH);
if (turns.size() != 0)
{
return getShortcut(p1Point, p2Point, turns,
getDistance(p1Point, p2Point));
}
return null;
}
上面程序中四条粗体字代码分别代表了两个方块位于同一个水平线可直接相连,两个方块位于同一个竖直线可直接相连,两个方块需要两条线相连,两个方块需要3条线相连等四种情况。上面方法分别考虑了这四种情况,但程序还需要为这4个方法提供实现。
为了实现上面4个方法,可以对两个Piece的位置关系进行归纳,两个Piece的位置关系可分为:
1、p1与p2在同一行(indexY值相同)。
2、p1与p2在同一列(indexX值相同)。
3、p2在p1的右上角(p2的indexX > p1的indexX,p2的indexY
< p1的indexY)。
4、p2在p1的右下角(p2的indexX > p1的indexX,p2的indexY
> p1的indexY)。
至于p2在p1的左上角、以及p2在p1的左下角这两种情况,程序可以重新执行link方法,将p1和p2两个参数的位置互换即可。(未完.摘自[疯狂android讲义].李刚)