天天看点

软件工程作业——围住神经猫

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);

}

}

}

软件工程作业——围住神经猫
软件工程作业——围住神经猫