2012211850 2012211466
一 开发过程
1)工程创建 这是一款基于android的手机游戏,所采用的开发工具为eclipse,语言为java。 打开adt创建空白的android application project,删除多余代码,创建Playground类,继承于surfaceview,在mainactivity调用setcontentview()方法加载这个surfaceview,完成基本的工程创建。
2)游戏元素创建 新建dot类,此类为游戏场景中的点。需要成员x,y来确定坐标位置,status来表示当前状态。编写带参数的构造函数对x,y在初始化的时候进行复制,status默认为不可通行,添加get()/set()方法。 在playground类中创建dot二维数组用来表示所有屏幕上的点元素。添加initGame()方法初始化所有的点,并随机设点15个点为初始路障。初始化神经猫的所在位置。 private void initGame() {
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++) {
matrix[i][j].setStatus(Dot.STATUS_OFF);
}
}
cat = new Dot(4, 5);
getDot(4, 5).setStatus(Dot.STATUS_IN);
for (int i = 0; i < BLOCKS;) {
int x = (int) ((Math.random() * 1000) % COL);
int y = (int) ((Math.random() * 1000) % ROW);
if (getDot(x, y).getStatus() == Dot.STATUS_OFF) {
getDot(x, y).setStatus(Dot.STATUS_ON);
i++;
}
}
}
3)游戏场景绘制 使用paint和canvas进行图像场景的绘制。 通过判断dot对象的status来决定点的颜色,采用switch选择语句为不同状态的点绘制不同的颜色,调用canvas中drawoval()方法将点绘制到画布上。注意点的上下左右点边界以及单双数行的错位。 private void redraw() {
Canvas c = getHolder().lockCanvas();
c.drawColor(Color.LTGRAY);
Paint paint = new Paint();
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
for (int i = 0; i < ROW; i++) {
int offset = 0;
if (i % 2 != 0) {
offset = WIDTH / 2;
}
for (int j = 0; j < COL; j++) {
Dot one = getDot(j, i);
switch (one.getStatus()) {
case Dot.STATUS_OFF:
paint.setColor(0xFFEEEEEE);
break;
case Dot.STATUS_ON:
paint.setColor(0xFFFFAA00);
break;
case Dot.STATUS_IN:
paint.setColor(0xFFFF0000);
break;
default:
break;
}
c.drawOval(new RectF(one.getX() * WIDTH + offset, one.getY()
* WIDTH, (one.getX() + 1) * WIDTH + offset,
(one.getY() + 1) * WIDTH), paint);
}
}
getHolder().unlockCanvasAndPost(c);
}
4)游戏触摸事件的处理 使playground类实现ontouchlistener接口。重写ontouch()方法。 仅需判断ACTION.UP即用户手里开屏幕的点进行判断即可。判断x,y所属的点,注意x的奇偶行的错位以及数组的越界。设置所属的点的status,重新调用绘制方法更新ui。 @Override
public boolean onTouch(View arg0, MotionEvent e) {
if (e.getAction() == MotionEvent.ACTION_UP) {
int x, y;
y = (int) (e.getY() / WIDTH);
if (y % 2 == 0) {
x = (int) (e.getX() / WIDTH);
} else {
x = (int) ((e.getX() - WIDTH / 2) / WIDTH);
}
if (x + 1 > COL || y + 1 > ROW) {
initGame();
} else if (getDot(x, y).getStatus() == Dot.STATUS_OFF) {
getDot(x, y).setStatus(Dot.STATUS_ON);
move();
}
redraw();
}
return true;
}
5)游戏逻辑的实现 a.添加dot的判断方法,判断次dot是否处于游戏边界。 private boolean isAtEdge(Dot d) {
if (d.getX() * d.getY() == 0 || d.getX() + 1 == COL
|| d.getY() + 1 == ROW) {
return true;
}
return false;
}
b.添加获取dot相邻点的方法,总共6个相邻点,设为1,2,3,4,5,6,注意边界点不足6个,返回null。 private Dot getNeighbour(Dot one, int dir) {
switch (dir) {
case 1:
return getDot(one.getX() - 1, one.getY());
case 2:
if (one.getY() % 2 == 0) {
return getDot(one.getX() - 1, one.getY() - 1);
} else {
return getDot(one.getX(), one.getY() - 1);
}
case 3:
if (one.getY() % 2 == 0) {
return getDot(one.getX(), one.getY() - 1);
} else {
return getDot(one.getX() + 1, one.getY() - 1);
}
case 4:
return getDot(one.getX() + 1, one.getY());
case 5:
if (one.getY() % 2 == 0) {
return getDot(one.getX(), one.getY() + 1);
} else {
return getDot(one.getX() + 1, one.getY() + 1);
}
case 6:
if (one.getY() % 2 == 0) {
return getDot(one.getX() - 1, one.getY() + 1);
} else {
return getDot(one.getX(), one.getY() + 1);
}
default:
break;
}
return null;
}
c.添加获取6个方向上的路径距离的方法。 private int getDistance(Dot one, int dir) {
int distance = 0;
if (isAtEdge(one)) {
return 1;
}
Dot ori = one, next;
while (true) {
next = getNeighbour(ori, dir);
if (next.getStatus() == Dot.STATUS_ON) {
return distance * -1;
}
if (isAtEdge(next)) {
distance++;
return distance;
}
distance++;
ori = next;
}
}
d.添加点(猫)移动的方法,注意设置移动上与离开的点的status设置。 private void MoveTo(Dot one) {
one.setStatus(Dot.STATUS_IN);
getDot(cat.getX(), cat.getY()).setStatus(Dot.STATUS_OFF);
;
cat.setXY(one.getX(), one.getY());
}
e.添加游戏成功失败判断方法即猫已在游戏边界,游戏结束,猫周围的点都为路障,游戏成功。并在此方法中对猫的逃离路径选择进行优化。 private void move() {
if (isAtEdge(cat)) {
lose();
return;
}
Vector<Dot> avaliable = new Vector<>();
Vector<Dot> positive = new Vector<>();
HashMap<Dot, Integer> al = new HashMap<Dot, Integer>();
for (int i = 1; i < 7; i++) {
Dot n = getNeighbour(cat, i);
if (n.getStatus() == Dot.STATUS_OFF) {
avaliable.add(n);
al.put(n, i);
if (getDistance(n, i) > 0) {
positive.add(n);
}
}
}
if (avaliable.size() == 0) {
win();
} else if (avaliable.size() == 1) {
MoveTo(avaliable.get(0));
} else {
Dot best = null;
if (positive.size() != 0) {
int min = 999;
for (int i = 0; i < positive.size(); i++) {
int a = getDistance(positive.get(i),
al.get(positive.get(i)));
if (a < min) {
min = a;
best = positive.get(i);
}
}
MoveTo(best);
} else {
int max = 0;
for (int i = 0; i < avaliable.size(); i++) {
int k = getDistance(avaliable.get(i),
al.get(avaliable.get(i)));
if (k <= max) {
max = k;
best = avaliable.get(i);
}
}
MoveTo(best);
}
}
}