上面的开发步骤完成后,还有几个细节问题没有处理
在onSizeChanged()方法中,startgame方法,完成最后的初始化步骤:
private void startgame() {
MainActivity.getMainActivity().ClearScore();
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
cardmap[x][y].setNum(0);
}
}
addrandomcard();
addrandomcard();
}
这就是为什么游戏开局会在不同位置上出现两张牌的原因了。
在这里就只剩下一个关键的问题:怎么判断游戏已经结束了呢?checkcompled方法这时就露面了!
我们可以思考一下,实际上,游戏结束时的逻辑是,任何一张牌的上下左右都没有一样取值的牌了。
这个逻辑接着展开,就是从最左边开始,每一张牌的右边和自己比较;从最右边开始,每一张牌的左边和自己比较....
我们使用一个标记,如果判断出现了相同值,说明游戏没有结束,就跳出标记,不用继续判断:
private void checkcompleted() {
boolean completed = true;
all: for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
if (cardmap[x][y].getNum() == 0
|| (x > 0 && cardmap[x][y].getNum() == cardmap[x - 1][y]
.getNum())
|| (x < 3 && cardmap[x][y].getNum() == cardmap[x + 1][y]
.getNum())
|| (y > 0 && cardmap[x][y].getNum() == cardmap[x][y - 1]
.getNum())
|| (y < 3 && cardmap[x][y].getNum() == cardmap[x][y + 1]
.getNum())) {
completed = false;
break all;
}
}
}
}
接着,我们为它添加上实现判断最高分的逻辑和游戏结束弹窗显示“游戏结束”逻辑。
我们先取到sharepaeference里的值,和当前分数比较。以此来判断最高分是否会被刷新:
if (completed) {
int endscore = MainActivity.getMainActivity().ShowScore();
if (endscore > MainActivity.getMainActivity().gethsfromsp()) {
MainActivity.getMainActivity().getsp(endscore);
new AlertDialog.Builder(getContext())
.setTitle("最高分!")
.setMessage(endscore + "")
.setPositiveButton("back",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
MainActivity.getMainActivity()
.sethighScore();
clearallbug();
startgame();
}
}).show();
}
else {
new AlertDialog.Builder(getContext())
.setTitle("你输了")
.setMessage("游戏结束")
.setPositiveButton("again",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
MainActivity.getMainActivity()
.sethighScore();
clearallbug();
startgame();
}
}).show();
}
}
AlertDialog方法想必大家很熟悉了,就不在赘述,根据代码都很好理解。
好了,现在游戏可以运行了。但现在我们要回过头来关注两个游戏的小bug.
大家不知道发现没有?大家可以先试着玩一玩,试着自己修改一下。如果没有发现或者没有耐心也没关系,请看下面的说明。
我们在onSizeChanged方法中使用的代码固然很好,而且游戏开始确实会调用这个方法,但是,我们每次转动手机,也会调用啊,这不是又会初始化一次?!这是很不好的。为此,我们需要做出修改。
这怎么办呢?我还是卖个关子吧,可以提示一下,方法有很多来处理这个问题,其中之一,在我以上的代码中就用现成的,可以直接来修改使用。大家想想吧!
还有一个问题,是在card类中的set方法中。label.setText(num + "");有初学者问我:“为什么要拼接字符串呢,直接使用num也不会报错啊。” 确实是的,你如果修改不要拼接,表面上是不会报错的,但是执行是不行的。因为setText方法你传入int参数,将会调用索引字符串列表查找匹配,显然没有这个匹配。settext必须是string参数。当然这样写不是特别理想,大家也可以修改一下。我的方法是在外面再用一个方法来完成字符串赋值。
OK。大功告成。现在你也有一款你自己开发的2048了。
游戏运行起来还是蛮酷的嘛,哈哈。因为我使用的颜色都是用笔缀取的!