编写推箱子游戏程序(第六步)——搬运工推着箱子走1
叶常春(iamdouble@163.com)
本文目标
本文描述如何实现搬运工推着箱子走的功能。如图 1-a 所示,在游戏界面上,当玩家用
手指按下搬运工右侧单元格时,搬运工将推着箱子往右走动一步。走一步之后的效果如 1-b
所示。
图 1-a 玩家用手指按下搬运工右侧单元格
图 1-b 搬运工推着箱子往右走动一步
本文用到的 Android 知识内容在前面都已经介绍过了。我们将复习:
1. 绘制图片的方法。
2. 矩形类 Rect 的用法。
实现思路和步骤
思路
什么时候会发生搬运工推着箱子走呢?答案是,玩家指挥搬运工向上(下、左、右)走
一步,而上方(下方、左侧、右侧)正好放着一个箱子。要注意的是,箱子在移动后不能出
界。
1本文遵循 Apache License 2.0 协议。你可以修改和再发布本文档,但须保留原著者和采用 Apache License 2.0
协议。
《编写推箱子游戏程序(第五步)》一文讲到,玩家在游戏界面上用手指触摸的方式指
挥搬运工走动。这个时候,Android 系统将调用 onTouchEvent()回调函数,在该回调函数内
执行搬运工走动的功能。以向下走一步为例,回调函数内执行的代码逻辑是:
if (触摸点落在搬运工下方单元格内) {
if (搬运工向下走一步没有出界)
搬运工向下走一步;
}
我们将在上述代码逻辑内加入推着箱子走的功能。继续以向下走一步为例,回调函数内执行
的代码逻辑变为:
if (触摸点落在搬运工下方单元格内) {
if (箱子处在搬运工正下方){
if (箱子向下移动一步没有出界){
箱子向下移动一步;
搬运工向下走一步;
}
}
else if (搬运工向下走一步没有出界)
搬运工向下走一步;
}
//箱子没有在搬运工正下方的情形
上述修改后的代码逻辑分两种情形来处理,一种是箱子在搬运工正下方的情形,另一种是箱
子不在搬运工正下方的情形。
步骤
1. 实现搬运工推着箱子向下走一步的功能。
2. 搬运工推着箱子向上、向左、向右走一步的功能实现,留作作业。
实现搬运工推着箱子向下走一步
实现搬运工推着箱子向下走一步的思路见前一章。我们要回答以下问题:
1. 如何知道箱子是否处在搬运工正下方?
2. 如何判别箱子向下移动后会不会出界?
3. 对于箱子向下走一步,代码该怎么写?
记住箱子的位置
上述问题的关键点是记住箱子的位置。记住箱子的位置的做法与记住搬运工位置的做法
是一模一样的。我们用 GameView 类的成员变量 mBoxRow, mBoxColumn 来记录箱子所在单
元格的行号和列号。这两个成员变量定义如下:
private int mBoxRow = 5;
private int mBoxColumn = 5;
//箱子一开始处在游戏区域中间位置
这两个变量初始化为 5,意味着第一次显示游戏界面的时候,箱子落在第 6 行第 6 列。
判断箱子是否在搬运工下方
我们用 GameView 类的 isBoxBlowMan()方法来实现判断箱子是否在搬运工下方。它的定
义如表 1 所示。
com.yescorp.moveboxgame.GameView.java
private boolean isBoxBlowMan() {
return mBoxColumn == mManColumn && mBoxRow == mManRow + 1;
}
1
2
3
写成一个方法的原因在于使得代码可读性更好。
判断箱子向下移动后会不会出界
判断箱子向下移动后会不会出界的代码是:
if (mBoxRow + 1 < CELL_NUM_PER_LINE) {
}
上述代码和判断搬运工向下走一步会不会出界的代码是类似的。
箱子向下移动一步
箱子向下移动一步的代码是:
mBoxRow++;
这与搬运工向下走一步的代码是类似的。
合在一起
搬运工向下走一步有两种情形:
若搬运工下方有箱子,搬运工推着箱子向下移动;
若搬运工下方没有箱子,搬运工向下走一步。
实现以上两种情形的思路见本文第二章,代码如下所示。这段代码放在 GameView 类的
onTouchEvent 方法内。
if (touch_blow_to_man(touch_x, touch_y, mManRow, mManColumn)) //触摸搬运工下方
if (isBoxBlowToMan()) {
if (mBoxRow + 1 < CELL_NUM_PER_LINE) {
mBoxRow++;
mManRow++;
}
} else if (mManRow + 1 < CELL_NUM_PER_LINE)
mManRow++;
为增加可读性,采用子函数来解决这一问题。做法是编写函数 handleDown 来实现搬运工和
箱子向下移动的功能。
以下两行代码放在 GameView 类的 onTouchEvent 方法内。
if (touch_blow_to_man(touch_x, touch_y, mManRow, mManColumn)) //触摸搬运工下方
handleDown();
下面的 handleDown 方法是 GameView 类的成员函数。
private void handleDown() {
if (isBoxBlowToMan()) {
if (mBoxRow + 1 < CELL_NUM_PER_LINE) {
mBoxRow++;
mManRow++;
}
} else if (mManRow + 1 < CELL_NUM_PER_LINE)
mManRow++;
}
作业
1. 实现搬运工推着箱子向上、向左、向右走一步的功能。