思想:每一个点看做一个单独的对象, status有三个属性值,分为障碍,猫,可行点。用一个二维数组存放这些点,
Dot类
public class Dot {
int x;
int y;
public int status;
public static final int STATUS_on=1;
public static final int STATUS_off=0;
public static final int STATUS_in=9;
public Dot(int x, int y) {
super();
this.x = x;
this.y = y;
status=STATUS_off;//把所有点status属性默认设置为STATUS_off
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
//创建一个直接设置X,Y的方法
public void setXY(int x,int y)
{
this.x=x;
this.y=y;
}
}
创建一个PlayGround类,让其继承 SurfaceView,用其作为游戏的主类,实现逻辑,操作以及绘图等功能。
public class PlayGround extends SurfaceView implements OnTouchListener{
private static int WIDTH =20;//球半径
private static final int ROW = 10;
private static final int COL = 10;
private static final int BLOCKS = 15;
private Dot matrix[][];
private Dot cat;
//先实习构造方法---1
public PlayGround(Context context) {
super(context);
getHolder().addCallback(callback);
matrix = new Dot[ROW][COL];
//创建所有游戏对象,并存入二维数组matrix中
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++) {
matrix[i][j] = new Dot(j, i);
}
}
initGame();//初始化游戏
setOnTouchListener(this);
}
private Dot getDot(int x,int y) {
return matrix[y][x];
}
//判读猫是否处于边界
private boolean isAtEdge(Dot d) {
if (d.getX()*d.getY() == 0 || d.getX()+1 == COL || d.getY()+1 == ROW) {
return true;
}
return false;
}
//获取领边点元素
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;
}
//计算出每个方向与障碍物的距离,有障碍物为负数,没障碍物就算取到领边的距离,为正数
private int getDistance(Dot one,int dir) {
// System.out.println("X:"+one.getX()+" Y:"+one.getY()+" Dir:"+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;
}
}
//移动猫
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());
if (isAtEdge(cat)) {
lose();
}
}
private void move()
{
//创建Dot的泛型
Vector<Dot> avaliable=new Vector<Dot>();
Vector<Dot> positive = new Vector<Dot>();
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);
//判断有没有线路没有障碍可供直接到达边界,将有的cat(getNeighbour的)加入positive
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);
}
}
}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);
}
}
private void lose() {
Toast.makeText(getContext(), "Lose", Toast.LENGTH_SHORT).show();
}
private void win() {
Toast.makeText(getContext(), "You Win!", Toast.LENGTH_SHORT).show();
}
//实习绘图方法---2
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);
}
//定义一个callback---3
Callback callback=new Callback() {
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
}
@Override
public void surfaceCreated(SurfaceHolder arg0) {
// TODO Auto-generated method stub
redraw();
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
WIDTH = arg2/(COL+1);
redraw();
}
};
//初始化游戏属性的方法
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++;
//System.out.println("Block:"+i);
}
}
}
@Override
//监听操作
public boolean onTouch(View arg0, MotionEvent e) {
// TODO Auto-generated method stub
if(e.getAction()==MotionEvent.ACTION_UP)
{
// Toast.makeText(getContext(), e.getX()+":"+e.getY(),Toast.LENGTH_SHORT ).show();
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;
}
}
最后将PlayGround加载至游戏界面中
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
setContentView(new PlayGround(this));
}
}