项目练习之三 抓住神经猫

总体思路:

1.创建游戏工程 (sufaceView的使用)callback方法和自定义的redraw方法

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new Playground(this));
        //setContentView(R.layout.activity_main);
    }

SurfaceHolder.Callback callback=new SurfaceHolder.Callback() {
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        redraw();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            WIDTH=width/(COL+1);
            redraw();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

    }
};

2.神经猫游戏元素的建立 Dog(此处利用到矩阵matrix 的使用)还有状态常量的定义  以及 设置路障和定义中心点为Cat  

注意:行列   X,Y 和matrix中X,Y的倒置关系

private  Dog cat;
private static final  int ROW=10;
private static final  int COL=10;
private static final  int BLOCK=15;

private  Dog matrix[][];
private void initsGame() {
    for (int i=0;i<ROW;i++){
        for (int j=0;j<COL;j++){
            matrix[i][j].setStatus(Dog.STATUS_OFF);

        }
    }
    cat=new Dog(4,5);
    getDog(4,5).setStatus(Dog.STATUS_IN);
    for (int i=0;i<BLOCK;){
        int x= (int) ((Math.random()*1000)%COL);
        int y=(int) ((Math.random()*1000)%ROW);
        if(getDog(x,y).getStatus()==Dog.STATUS_OFF){
            getDog(x,y).setStatus(Dog.STATUS_ON);
            i++;
            Log.d("HH", "BLOCK +" +i);
        }
    }

}
3.游戏场景的绘制  (Paint和Canvas)

public 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++) {
            Dog one=getDog(j,i);
            switch (one.getStatus()){
                case Dog.STATUS_OFF:
                    paint.setColor(0xFFEEEEEE);
                    break;
                case Dog.STATUS_ON:
                    paint.setColor(0xFFFFAA00);
                    break;
                case  Dog.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);

}
此处应该注意的点是  width的选择   利用callback接口中sufaceChanged的方法传入的width参数  来计算 WIDTH=width/COT;

4.定义触摸事件

public boolean onTouch(View v, MotionEvent event) {
    if(event.getAction()==MotionEvent.ACTION_UP){
        int x,y;
        y= (int) (event.getY()/WIDTH);
        if(y%2==0){
            x= (int) (event.getX()/WIDTH);
        }else{
            x= (int) ((event.getX()-WIDTH/2)/WIDTH);
        }
        if ((x+1)>COL||(y+1)>ROW){
           initsGame();

        }else if(getDog(x,y).getStatus()==Dog.STATUS_OFF){
            getDog(x,y).setStatus(Dog.STATUS_ON);

            move();

        }
            redraw();
    }

    return true;

}

注意:当发生越界情况时,应该有相应的操作,否则会系统崩溃,此处设为初始化游戏;

*5.四个功能函数的实现

 private boolean isAtEdge(Dog d){
     if(d.getX()*d.getY()==0||d.getX()+1==COL||d.getY()+1==ROW){
         return  true;

     }
     return  false;
 }
 private Dog getNeighbour(Dog one,int dir){
     switch (dir){
         case 1:
            return getDog(one.getX()-1,one.getY());

         case 2:
             if(one.getY()%2==0){
                 return getDog(one.getX()-1,one.getY()-1);
             }else{
                 return getDog(one.getX(),one.getY()-1);
             }
         case 3:
             if(one.getY()%2==0){
                 return getDog(one.getX(),one.getY()-1);
             }else{
                 return getDog(one.getX()+1,one.getY()-1);
             }
         case 4:
             return getDog(one.getX()+1,one.getY());
         case 5:
             if(one.getY()%2==0){
                 return getDog(one.getX(),one.getY()+1);
             }else{
                 return getDog(one.getX()+1,one.getY()+1);
             }
         case 6:
             if(one.getY()%2==0){
                 return getDog(one.getX()-1,one.getY()+1);
             }else{
                 return getDog(one.getX(),one.getY()+1);
             }
         default:
             break;
     }
     return  null;

 }
private int getDistance(Dog one,int dir){
     int distance=0;
     if(isAtEdge(one)){
         return 1;
     }
     Dog ori=one,next;
     while(true){
         next=getNeighbour(ori,dir);
         if (next.getStatus()==Dog.STATUS_ON){
             return distance*-1;
         }
         if(isAtEdge(next)){
             distance++;
             return  distance;
         }
         distance++;
         ori=next;
     }
 }
 private void MoveTo(Dog one){
     one.setStatus(Dog.STATUS_IN);
     getDog(cat.getX(),cat.getY()).setStatus(Dog.STATUS_OFF);
     cat.setXY(one.getX(),one.getY());

 }
6.移动策略以及优化

 private void move() {
        if(isAtEdge(cat)){
            lose();
            return;
        }
        Vector<Dog>available=new Vector<>();
        Vector<Dog>positive=new Vector<>();
        HashMap<Dog,Integer>al=new HashMap<Dog,Integer>();
        for (int i=1;i<7;i++){
            Dog n=getNeighbour(cat,i);
            if(n.getStatus()==Dog.STATUS_OFF){
                available.add(n);
                al.put(n,i);
                if(getDistance(n,i)>0){
                    positive.add(n);

                }
            }
        }
        if(available.size()==0){
            win();
        }else if (available.size()==1){
            MoveTo(available.get(0));

        }else{
            Dog best=null;
            if (positive.size()!=0) {//有可以直接到达边缘的路径
                System.out.println("找路径");
                int min=99;
                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{//所有方向都有路障
                System.out.println("躲路障");
                int max=0;
                for (int i = 0; i < available.size();i++) {
                    int k =getDistance(available.get(i),al.get(available.get(i)));
                    if (k<=max){//此处务必要<=max !!!否则当出现等于0的情况时系统将会崩溃
                        max=k;
                        best=available.get(i);
                    }
                }
                MoveTo(best);

            }

        }
    }
    private void lose(){
        Toast.makeText(getContext(),"You lose",Toast.LENGTH_SHORT).show();
    }
    private void win(){
        Toast.makeText(getContext(),"You win,业诚真帅",Toast.LENGTH_SHORT).show();

    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值