围住神经猫 Java源码.docx
《围住神经猫 Java源码.docx》由会员分享,可在线阅读,更多相关《围住神经猫 Java源码.docx(16页珍藏版)》请在冰点文库上搜索。
围住神经猫Java源码
MainActivity
packagecom.jikexueyuan.catchcrazycat;
importandroid.app.Activity;
importandroid.os.Bundle;
publicclassMainActivityextendsActivity{
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
setContentView(newPlayground(this));//Context把MainActivity的this传递进去
}
}
Dot
packagecom.jikexueyuan.catchcrazycat;
publicclassDot{
//记录每个场景中的元素它的X,Y坐标点的状态。
并不会直接参与界面的响应和界面的绘制
intx,y;//当前点的X,Y坐标
intstatus;//记录这个点的状态
//三个表征圆点状态静态常量
publicstaticfinalintSTATUS_ON=1;//已经开启路障的状态
publicstaticfinalintSTATUS_OFF=0;//代表灰色可走路径
publicstaticfinalintSTATUS_IN=9;//猫当前的位置
//三个数字不同即可,具体用哪个数字无所谓
//指定X,Y坐标
publicDot(intx,inty){
super();
this.x=x;
this.y=y;
status=STATUS_OFF;//当前状态为STATUS_OFF
}
//指定geter和sette方法
publicintgetX(){
returnx;
}
publicvoidsetX(intx){
this.x=x;
}
publicintgetY(){
returny;
}
publicvoidsetY(inty){
this.y=y;
}
publicintgetStatus(){
returnstatus;
}
publicvoidsetStatus(intstatus){
this.status=status;
}
//同时设置X,Y坐标的方法
publicvoidsetXY(intx,inty){
this.y=y;
this.x=x;
}
}
/*每一个点都是一个抽象的对象,需要把每一个点抽象为一个类,然后让每一个圆圈继承于这个类,
或者直接把它实现为这个类的实例。
每个点有三个状态:
灰色-猫可走的路径;红色-路障且状态
无法改变;黄色-猫当前的位置。
*/
Playground
packagecom.jikexueyuan.catchcrazycat;
importjava.util.HashMap;
importjava.util.HashSet;
importjava.util.Map;
importjava.util.Vector;
importandroid.R.integer;
importandroid.content.Context;
importandroid.graphics.Canvas;
importandroid.graphics.Color;
importandroid.graphics.Paint;
importandroid.graphics.RectF;
importandroid.view.MotionEvent;
importandroid.view.SurfaceHolder;
importandroid.view.SurfaceHolder.Callback;
importandroid.view.SurfaceView;
importandroid.view.View;
importandroid.view.View.OnTouchListener;
importandroid.widget.Toast;
publicclassPlaygroundextendsSurfaceViewimplementsOnTouchListener{
//界面的响应和界面的绘制在SurfaceView完成,触摸事件的响应通过OnTouchListener接口实现
privatestaticintWIDTH=40;//元素的
privatestaticfinalintROW=10;//行高:
每行储存10个元素
privatestaticfinalintCOL=10;//列宽:
每列储存10个元素
privatestaticfinalintBLOCKS=15;//默认添加的路障数量
privateDotmatrix[][];//声明二维数组来存放点元素
privateDotcat;//声明猫这个点
publicPlayground(Contextcontext){
super(context);//使用Context创建当前类构造函数
getHolder().addCallback(callback);//将Callback对象指定给getholder
matrix=newDot[ROW][COL];//将行高,列宽传递进去,指定数组大小
for(inti=0;ifor(intj=0;j
matrix[i][j]=newDot(j,i);/*X,Y坐标值和行列值是相反的。
即通过查找列值获得X坐标,查找行值获得Y坐标*/
}
}
setOnTouchListener(this);//设定为自己的触摸监听器
initGame();//调用游戏初始化
}
//坐标反转:
封装一个getDot函数实现X,Y坐标反过来传递,所有的操作通过X,Y调用
privateDotgetDot(intx,inty){
returnmatrix[y][x];
}
//判断猫是否处于边界
privatebooleanisAtEdge(Dotd){
if(d.getX()*d.getY()==0||d.getX()+1==COL||d.getY()+1==ROW){
returntrue;//当前点的坐标无论是x或y为0,或x或y值是定义的游戏场景最大值时都处于边界
}
returnfalse;
}
//为每个点实现获取相邻点的方法
privateDotgetNeighbour(Dotone,intdir){//每个点都有6个相邻点
switch(dir){
case1:
returngetDot(one.getX()-1,one.getY());//获得中心点左边相邻点
case2:
if(one.getY()%2==0){
returngetDot(one.getX()-1,one.getY()-1);//奇数行获得中心点左上相邻点:
x-1,y-1
}else{
returngetDot(one.getX(),one.getY()-1);//偶数行获得中心点左上相邻点:
y-1
}
case3:
if(one.getY()%2==0){
returngetDot(one.getX(),one.getY()-1);//奇数行获得中心点右上相邻点:
y-1
}else{
returngetDot(one.getX()+1,one.getY()-1);//偶数行获得中心点右上相邻点:
x+1,y-1
}
case4:
returngetDot(one.getX()+1,one.getY());//获得中心点右边相邻点
case5:
if(one.getY()%2==0){
returngetDot(one.getX(),one.getY()+1);//奇数行获得中心点右下相邻点:
y+1
}else{
returngetDot(one.getX()+1,one.getY()+1);//偶数行获得中心点右下相邻点:
x+1,y+1
}
case6:
if(one.getY()%2==0){
returngetDot(one.getX()-1,one.getY()+1);//奇数行获得中心点左下相邻点:
x-1,y+1
}else{
returngetDot(one.getX(),one.getY()+1);//偶数行获得中心点左下相邻点:
y+1
}
default:
break;
}
returnnull;
}
//中心点6个方向距离的判断与获取。
路径结束点为路障用负数表示,为场景边缘用正数表示
privateintgetDistance(Dotone,intdir){
//System.out.println("X:
"+one.getX()+"Y:
"+one.getY()+"Dir:
"+dir);
intdistance=0;
if(isAtEdge(one)){
return1;//如果下一个点已在屏幕边缘,无需再判断
}
Dotori=one,next;//定义ori和next,ori指定为当前函数传入的one
while(true){
next=getNeighbour(ori,dir);
if(next.getStatus()==Dot.STATUS_ON){
returndistance*-1;//下一个点为路障的话,直接返回距离0
}
if(isAtEdge(next)){
distance++;
returndistance;//下一个点为场景边缘时,距离+1并返回
}
distance++;
ori=next;//下一个点既不是路障也不是场景边缘,距离自加并把当前的下一个点赋值成参考点ori
}
}
//实现猫移动到下一个点
privatevoidMoveTo(Dotone){
one.setStatus(Dot.STATUS_IN);//one的状态设置为猫所处的点
getDot(cat.getX(),cat.getY()).setStatus(Dot.STATUS_OFF);;//将猫当前点的状态复位
cat.setXY(one.getX(),one.getY());//将猫移动到新的点
}
//猫的移动
privatevoidmove(){
if(isAtEdge(cat)){
lose();return;//猫处于游戏边缘,失败
}
Vectoravaliable=newVector<>();//avaliable容器记录可用点
Vectorpositive=newVector<>();//positive容器记录这个方向上可以直接到达屏幕边缘的路径
HashMapal=newHashMap();//pl容器记录方向
for(inti=1;i<7;i++){//如果当前猫被6个邻点围住
Dotn=getNeighbour(cat,i);
if(n.getStatus()==Dot.STATUS_OFF){
avaliable.add(n);//如果相邻点可用,把它添加到avaliable记录器中
al.put(n,i);//为pl传入方向i
if(getDistance(n,i)>0){
positive.add(n);//当它有一个路径可以直接到达屏幕边缘,把n传递进positive中
}
}
}
//移动算法的优化
if(avaliable.size()==0){
win();//周围的6个点都不可走,没有可用点,成功围住猫
}elseif(avaliable.size()==1){
MoveTo(avaliable.get(0));//只有一个方向可走,可用点有一个,移动到这个可用点上
}else{//有多个方向可走
Dotbest=null;
if(positive.size()!
=0){//存在可以直接到达屏幕边缘的走向
System.out.println("向前进");
intmin=999;//999远大于场景中的所有可用步长,其他数也可
for(inti=0;iinta=getDistance(positive.get(i),al.get(positive.get(i)));
if(amin=a;//把最短路径长度传给min
best=positive.get(i);//选出拥有最短路径的点
}
}
}else{//所有方向都存在路障
System.out.println("躲路障");
intmax=0;
for(inti=0;iintk=getDistance(avaliable.get(i),al.get(avaliable.get(i)));
if(k<=max){//所有方向都存在路障,距离k为负数
max=k;
best=avaliable.get(i);//选出拥有最短路径的点
}
}
}
MoveTo(best);//移动到最短路径的下一点
}
}
privatevoidlose(){
Toast.makeText(getContext(),"Lose",Toast.LENGTH_SHORT).show();//失败提示
}
privatevoidwin(){
Toast.makeText(getContext(),"YouWin!
",Toast.LENGTH_SHORT).show();//成功提示
}
//实现界面绘制,在redraw方法中将所有元素以图形化显示出来,也就是将它绘制在Canvas对象上
privatevoidredraw(){
Canvasc=getHolder().lockCanvas();//锁定画布
c.drawColor(Color.LTGRAY);//设置颜色为浅灰色
Paintpaint=newPaint();//创建Paint对象
paint.setFlags(Paint.ANTI_ALIAS_FLAG);//开启抗锯齿,优化视频质量
//用两个For循环嵌套将所有的点显示到界面中来
for(inti=0;iintoffset=0;//引入偏移量
if(i%2!
=0){
offset=WIDTH/2;//对偶数行进行缩进
}
for(intj=0;j
Dotone=getDot(j,i);//将坐标赋值给内部变量one
//由于每个点对应的三种状态颜色不一样,要用一个switch语句
switch(one.getStatus()){
caseDot.STATUS_OFF:
paint.setColor(0xFFEEEEEE);//STATUS_OFF状态时设置颜色为浅灰色
break;
caseDot.STATUS_ON:
paint.setColor(0xFFFFAA00);//STATUS_ON状态时设置颜色为橙色
break;
caseDot.STATUS_IN:
paint.setColor(0xFFFF0000);//STATUS_IN状态时设置颜色为红色
break;
default:
break;
}
c.drawOval(newRectF(one.getX()*WIDTH+offset,one.getY()*WIDTH,
(one.getX()+1)*WIDTH+offset,(one.getY()+1)*WIDTH),paint);
/*在Canvas画布上画椭圆并界定它的上下左右边界宽度且有错位*/
}
}
getHolder().unlockCanvasAndPost(c);//取消Canvas的锁定,吧绘图内容更新到界面上
}
//为Surfaceview添加Callback
Callbackcallback=newCallback(){//声明并实例化一个Callback接口
@Override
publicvoidsurfaceDestroyed(SurfaceHolderarg0){
//TODOAuto-generatedmethodstub
}
@Override
publicvoidsurfaceCreated(SurfaceHolderarg0){
//TODOAuto-generatedmethodstub
redraw();//执行redraw函数,在界面第一次显示时将指定的内容显示到界面上
}
@Override
//使用surfaceChanged方法来适配不同的屏幕尺寸
publicvoidsurfaceChanged(SurfaceHolderarg0,intarg1,intarg2,intarg3){
//surfacechanged方法包含四个参数:
SurfaceHolderholder,intformat,intwidth,intheight
//TODOAuto-generatedmethodstub
WIDTH=arg2/(COL+1);//需要修改width,即arg2。
redraw();//重绘界面
}
};
//游戏初始化:
分别对可走路径位置,猫的位置和路障位置进行初始化
privatevoidinitGame(){
//用for循环将所有点设置为STATUS_OFF,即可用状态
for(inti=0;ifor(intj=0;j
matrix[i][j].setStatus(Dot.STATUS_OFF);
}
}
cat=newDot(4,5);//设置猫的起始点
getDot(4,5).setStatus(Dot.STATUS_IN);//把猫的起始点的状态设置为STATUS_IN,才能记录猫的位置
//用for循环随机的指定10个点的坐标作为路障
for(inti=0;iintx=(int)((Math.random()*1000)%COL);
inty=(int)((Math.random()*1000)%ROW);//随机获取1对坐标点
if(getDot(x,y).getStatus()==Dot.STATUS_OFF){//对当前可用路径点进行选择
getDot(x,y).setStatus(Dot.STATUS_ON);//并把这个点设置为路障
i++;//循环内自加避免当前路障被重复添加
//System.out.println("Block:
"+i);
}
}
}
@Override
//触摸事件的处理
publicbooleanonTouch(Viewarg0,MotionEvente){
if(e.getAction()==MotionEvent.ACTION_UP){
//当用户触摸之后手离开屏幕释放的瞬间才对事件进行响应
//Toast.makeText(getContext(),e.getX()+":
"+e.getY(),Toast.LENGTH_SHORT).show();
//将屏幕的坐标转换为游戏的坐标
intx,y;
y=(int)(e.getY()/WIDTH);//横向状态下,奇、偶数行有坐标偏移,而纵向的Y值是不变的,将y进行转换
if(y%2==0){
x=(int)(e.getX()/WIDTH);//奇数行直接将屏幕的X坐标转换成游戏的X坐标
}else{
x=(int)((e.getX()-WIDTH/2)/WIDTH);//偶数行偏移半个元素宽度,故需减去WIDTH/2
}
//数组越界异常时,对坐标进行保护
if(x+1>COL||y+1>ROW){//x、y:
0-9,col、row:
1-10
initGame();//触摸超出边界时初始化游戏
}elseif(getDot(x,y).getStatus()==Dot.STATUS_OFF){
getDot(x,y).se
|
|
|