Android打地鼠游戏的修改和优化

作者: dsx | 来源:发表于2017-06-26 20:12 被阅读698次

最近在研究android原生的游戏,主要是打地鼠这款经典小游戏的熟悉和修改,因为直接copy的是开源的代码,不过因为年代久远,再加上要修改的符合需求,所以做了一些调整,先看界面:

1.打地鼠的实现图

这个界面是用自定义View来实现的,所以可扩展性比较强,HP是血量,总共20ms,进行倒计时操作,Grade是分数,每打中一次地鼠,则增加100分,首先,我们先看看这两个是如何绘制的:

2.HP和Grade的绘制

也就五行代码,利用Paint画笔,设置字体颜色为红色,字体大小为30sp,利用Canva的drawText()方法进行字体文本的绘制,同时GameAgrs这个类是游戏属性的封装类,里面的HP_X和HP_Y,Grade_X和Grade_Y分别对应着各自的横坐标和纵坐标。

接下来,我们来仔细讲解一下这九个老鼠窝的绘制,因为老鼠窝有九个,但是其中的每个属性都是一样的,我们先来看看其中一个鼠窝究竟有哪些元素和属性构成的:

3.每个方块的属性页方法

因为是直接拿源码直接来改的,所以这里面的倒计时有一点问题,利用的是自减而非传统的CountDownTime等倒计时的方式,所以会倒计时会出现一点问题,这个未来会做相应的修改。

得到每个方块的属性和方法之后,我们虽然可以绘制鼠窝,但是为了给老鼠一个美丽的家,所以我们设置一下背景和老鼠弹出、撤退的图片。

4.鼠窝背景和老鼠的三个状态的设置

利用Map存储老鼠的三个状态,暴露出一个getBitmap的方法让外界进行调用,获取鼠窝的背景和老鼠的三个状态。

到目前为止,我们完成了单个鼠窝的属性,背景和老鼠的绘制,接下来我们需要对九个鼠窝进行绘制,由于代码太多,就不截图了,直接看代码

public classGameViewextendsView {

public static intspeed=100;//刷新速度

private static final intsHeight=298;

private booleanisCancel=false;

publicGameView(Context context) {

     super(context);

     initView(context);

     GameView.this.post(updatePaint);//刷新画面线程

      GameView.this.postDelayed(setMouse,1000);//增加地鼠的线程,1s后执行

}

publicGameView(Context context,@NullableAttributeSet attrs) {

     super(context,attrs);

     initView(context);

    GameView.this.post(updatePaint);//刷新画面线程

    GameView.this.postDelayed(setMouse,1000);//增加地鼠的线程,1s后执行

    Log.i("GameViewThread:",Thread.currentThread() +"");

}

publicGameView(Context context,@NullableAttributeSet attrs, intdefStyleAttr) {

     super(context,attrs,defStyleAttr);

    initView(context);

    GameView.this.post(updatePaint);//刷新画面线程

   GameView.this.postDelayed(setMouse,1000);//增加地鼠的线程,1s后执行

}

public static voidinitView(Context context){

     DisplayMetrics dMetrics =newDisplayMetrics();

     //获取屏幕分辨率

     dMetrics = context.getResources().getDisplayMetrics();

     GameAgrs.InitArgs(dMetrics);

    MainMapManager.Init(context);

    VolumsPlayer.init(context);

}

intstart_X= GameAgrs.start_X;//开始画方块的X坐标

intstart_Y= GameAgrs.start_Y;//开始画方块的Y坐标

privateRandomrandom=newRandom();//定义一个随机函数

//初始化每块方块的信息

privateListmainList=newArrayList(GameAgrs.Total_Count);

{

     for(inti =0;i < GameAgrs.Total_Count;i++) {

        mainList.add(newEpicture());

    }

}

RunnableupdatePaint=newRunnable() {

@Override

public voidrun() {

        GameView.this.invalidate();

       GameView.this.postDelayed(this,speed);//每100ms刷新一次

}

};

Runnable setMouse=new  Runnable() {

@Override

public void run() {

       LinkedList  tempList =new  LinkedList();

      for(inti =0;i

           Epicture epicture =mainList.get(i);

           if(epicture.getCurrenty() == GameAgrs.Hole_Empty) {

          tempList.add(epicture);

}

}

inttempSize = tempList.size();

if(tempSize ==1) {

tempList.poll().toShow();

}else if(tempSize >1) {

//随机出一个或者两个地鼠

for(inti =0;i

tempList.remove(random.nextInt(tempList.size())).toShow();

}

GameView.this.invalidate();

}

GameView.this.postDelayed(this,800- GameAgrs.Grade/20);

}

};

private void  drawMessage(Canvas canvas) {

Paint paint =new  Paint();

paint.setColor(Color.RED);

paint.setTextSize(GameAgrs.text_size);

canvas.drawText("HP:"+ GameAgrs.HP,GameAgrs.HP_X,GameAgrs.HP_Y,paint);

canvas.drawText("\nGrade:  "+ GameAgrs.Grade,GameAgrs.Grade_X,GameAgrs.Grade_Y,paint);

}

//游戏结束处理

private void   doGameOver() {

AlertDialog.Builder builder =new  AlertDialog.Builder(getContext());

if(GameAgrs.Grade<2500)

builder.setTitle("继续努力O(∩_∩)O");

else if(GameAgrs.Grade<3500)

builder.setTitle("那你很棒棒呦(。^▽^)");

else

builder.setTitle("哇!你坠棒(๑•̀ㅂ•́)و✧");

builder.setMessage("得分:"+ GameAgrs.Grade+",是否重新开始游戏?");

builder.setPositiveButton("确定", newDialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, intwhich) {

GameAgrs.Reset();//用户信息重置

isCancel=false;

initView(getContext());

GameView.this.post(updatePaint);//刷新画面线程

GameView.this.postDelayed(setMouse,1000);

}

});

builder.setNegativeButton("取消", newDialogInterface.OnClickListener() {

@Override

public voidonClick(DialogInterface dialog, intwhich) {

isCancel=true;

GameAgrs.Reset();//用户信息重置

initView(getContext());

GameView.this.invalidate();

}

});

builder.setCancelable(false);

AlertDialog dialog = builder.create();

dialog.show();

}

@Override

protected void  onMeasure(intwidthMeasureSpec, intheightMeasureSpec) {

super.onMeasure(widthMeasureSpec,heightMeasureSpec);

setMeasuredDimension(ViewGroup.LayoutParams.MATCH_PARENT,sHeight);

}

@Override

protected void  onDraw(Canvas canvas) {

super.onDraw(canvas);

if(GameAgrs.HP<=0) {

getHandler().removeCallbacks(updatePaint);

getHandler().removeCallbacks(setMouse);

doGameOver();

return;

}

canvas.drawColor(Color.WHITE);//将背景设置为白色

drawMessage(canvas);//显示用户信息

if(isCancel) {

for(inti =0;i

Epicture epicture =mainList.get(i);

intx = i % GameAgrs.Colums_Count;//获得所在列

inty = i / GameAgrs.Colums_Count;//获得所在行

canvas.drawBitmap(MainMapManager.getBitmap(epicture.getEmpty()),

start_X+ x * GameAgrs.EpicSize,start_Y+ y

* GameAgrs.EpicSize, null);

}

return;

}

for(inti =0;i

Epicture epicture =mainList.get(i);

intx = i % GameAgrs.Colums_Count;//获得所在列

inty = i / GameAgrs.Colums_Count;//获得所在行

canvas.drawBitmap(MainMapManager.getBitmap(epicture.getCurrenty()),

start_X+ x * GameAgrs.EpicSize,start_Y+ y

* GameAgrs.EpicSize, null);

epicture.toNext();//进入下一个状态

}

}

//触摸事件

@Override

public boolean  onTouchEvent(MotionEvent event) {

if(event.getAction() != MotionEvent.ACTION_DOWN) {

return true;

}

floatx = event.getX();

floaty = event.getY();

intX = (int) ((x -start_X) / GameAgrs.EpicSize);

intY = (int) ((y -start_Y) / GameAgrs.EpicSize);

if(X <0|| Y <0|| X >=3|| Y >=4) {//如果打击不在方块范围内则不响应

//点击外围的时候,则开始游戏

startGame();

return true;

}

intnum = Y * GameAgrs.Colums_Count+ X;

Log.i("game-----------",num +"");

if(num <9){//暂时先解决数组出界的问题

Epicture epicture =mainList.get(num);

epicture.beHited();

}

return true;

}

private void  startGame() {

GameAgrs.Reset();//用户信息重置

initView(getContext());

isCancel=false;

GameView.this.post(updatePaint);//刷新画面线程

GameView.this.postDelayed(setMouse,1000);

}

}

代码不长,但是有几个方法,首先定义了updatePaint和setMouse的两个runnable,分别用来更新UI界面和老鼠动作,onDraw()方法用来绘制九个鼠窝和背景和老鼠的动作状态,onTouchEvent主要用来处理点击事件,具体的可以看看代码,都有注释,并不难理解,doGameOver(),则定义了一个弹窗,点击确定则继续开始,点击取消,则重置页面初始状态。

以上就是打地鼠的代码了,虽然不全,但是精华已经全都交代出来了,另外这个还只是最初的修改版本,未来工作中还有更多的修改,包括页面的重绘,逻辑的修改等等。

相关文章

  • Android打地鼠游戏的修改和优化

    最近在研究android原生的游戏,主要是打地鼠这款经典小游戏的熟悉和修改,因为直接copy的是开源的代码,不过因...

  • 苏大人和三宝的日常(打地鼠)

    除了磨牙棒和球,三宝最喜欢的游戏,就是打地鼠了,但此打地鼠非寻常打地鼠,具体游戏规则由苏大人详细介绍。 游戏道具只...

  • 【编程】零基础Pygame小游戏开发-03

    欢迎关注我的专栏( つ•̀ω•́)つ【人工智能通识】 打地鼠游戏 我们可以把经典的打地鼠游戏简化概括为: 地图和道...

  • 产品剖析 | 如何制作出一款好玩的打地鼠游戏?

    打地鼠这款游戏大家小时候都玩过,对于零编程基础的人,是否有机会自己亲手制作一款好玩又有新意的打地鼠游戏呢?在打地鼠...

  • 城管打地鼠

    打地鼠的游戏相信大家都玩过,成群的地鼠从地鼠洞里钻出来,玩家要做的就是把钻出来的地鼠打掉。但是地鼠可以不断的从地鼠...

  • 【三年五班】打地鼠后续

    文/刘嘉琪 要知道打地鼠会产生这样的“影响”我坚决不带孩子们玩打地鼠游戏! ...

  • 亲子游戏|打地鼠

    昨天晚上小啾准备去洗澡。经过我坐的椅子时,她在我身后,调皮地把头伸到我左边,在脸上亲一下,马上又窜到右边亲一下。我...

  • 自制打地鼠游戏

    首先准备一个箱子,画一些圈圈,年龄小的,可以画大点。 然后剪成这样,年龄越大的可以多剪几个圈,我的孩子三岁多一点,...

  • Android简易打地鼠

    先看看基本的效果(背景图片及老鼠图片来源于网络) 上面贴出的这几张就是该APP的游戏界面,下面谈谈一开始设计的基本...

  • egret制作打地鼠类游戏

    iceBucketChallenge 项目介绍 iceBucketChallenge:类似打地鼠类的冰桶挑战游戏(...

网友评论

    本文标题:Android打地鼠游戏的修改和优化

    本文链接:https://www.haomeiwen.com/subject/usijcxtx.html