上篇文章中对开始打地鼠游戏的思路做了简单的介绍,现在来具体的说一说开始打地鼠游戏的实现,先说说布局,用LinearLayout或TableLyout都可以。上面一行是4个TextView下面的地洞是ImageButton。游戏中打中或没打中地鼠都更新会对应按钮背景图。打中地鼠的效果图(图1)和没打中的效果图(图2)。

Android游戏开发之打地鼠(三、打地鼠设计实现)  Android游戏开发之打地鼠(三、打地鼠设计实现)

  游戏中需要开启一个线程来控制游戏时间,更新显示剩余时间时,游戏0.5s更新一次,游戏时间为30s,因此更新次数是游戏时间的二倍。当游戏时间为0s时游戏停止关闭游戏界面并开启记录玩家信息的窗口。该线程同时产生一个随机数(1-12)来指定地鼠出现位置,由于子线程不能更新UI,需要通过handler发送消息来更新UI。更新界面时将每一个按钮背景都有重置为地洞,再更新地鼠出现位置的图片,这样会清除由于点击出现的锤子和上一次地鼠出现位置设置的图片。当用户点击屏幕是,如果打中地鼠,效果如图1,没打中效果如图2,并且如果开启了音效,会播放不同的打击声音。最后在游戏界面不可见是关闭线程。

  代码如下:

Java代码
  1. package cn.com.cyj.mouse.services;    
  2.     
  3. import java.util.HashMap;    
  4. import java.util.Random;    
  5.     
  6. import android.content.Intent;    
  7. import android.os.Bundle;    
  8. import android.os.Handler;    
  9. import android.view.View;    
  10. import android.view.View.OnClickListener;    
  11. import android.widget.Button;    
  12. import android.widget.ImageButton;    
  13. import android.widget.TextView;    
  14. import cn.com.cyj.mouse.R;    
  15. import cn.com.cyj.mouse.ui.BaseActivity;    
  16. import cn.com.cyj.mouse.ui.MouseStart;    
  17.     
  18. /**  
  19.  * 游戏开始的界面:游戏中有12个ImageButton,每个ImageButton背景设置成地鼠洞,游戏中开启一个线程控制游戏时间  
  20.  *   
  21.  * @author cyj  
  22.  *   
  23.  */    
  24. public class GameRun extends BaseActivity {    
  25.     /**  
  26.      * 线程睡眠时间  
  27.      */    
  28.     public static final int THREAD_SLEEP_TIME = 500;    
  29.     /**  
  30.      * 游戏时间  
  31.      */    
  32.     public static final int TIME = 30;    
  33.     private ImageButton one;    
  34.     private ImageButton two;    
  35.     private ImageButton three;    
  36.     private ImageButton four;    
  37.     private ImageButton five;    
  38.     private ImageButton six;    
  39.     private ImageButton seven;    
  40.     private ImageButton eight;    
  41.     private ImageButton nine;    
  42.     private ImageButton ten;    
  43.     private ImageButton eleven;    
  44.     private ImageButton twleve;    
  45.     // 显示时间    
  46.     private TextView showTime;    
  47.     // 显示分数    
  48.     private TextView score;    
  49.     MyClick click;    
  50.         
  51.     private Random random;    
  52.     // 游戏当前时间    
  53.     private int time;    
  54.     // 游戏总时间    
  55.     private int totalTime;    
  56.     // 老鼠下一次出现位置    
  57.     private int next;    
  58.     // 游戏当前分数    
  59.     private int nowScore;    
  60.     // 游戏线程    
  61.     private Thread t;    
  62.     // 存放按钮和next的映射    
  63.     HashMap<ImageButton, Integer> battle;    
  64.     HashMap<Integer, ImageButton> nextMap;    
  65.     public Handler handler = new Handler() {    
  66.         public void handleMessage(android.os.Message msg) {    
  67.             changeUI();    
  68.         };    
  69.     };    
  70.     
  71.     @Override    
  72.     protected void onCreate(Bundle savedInstanceState) {    
  73.         super.onCreate(savedInstanceState);    
  74.         setContentView(R.layout.activity_gamerun);    
  75.     
  76.         battle = new HashMap<ImageButton, Integer>();    
  77.         nextMap = new HashMap<Integer, ImageButton>();    
  78.         initImageButton();    
  79.         initOnClick();    
  80.         initbattleMap();    
  81.         initNextMap();    
  82.         next = -1;    
  83.         random = new Random();    
  84.         totalTime = TIME;    
  85.         time = 0;    
  86.         nowScore = 0;    
  87.         showTime.setText(TIME + "");    
  88.     }    
  89.     
  90.     @Override    
  91.     protected void onResume() {    
  92.         super.onResume();    
  93.         if(t == null){    
  94.             // 控制游戏时间    
  95.             t = new Thread(new Runnable() {    
  96.                 @Override    
  97.                 public void run() {    
  98.                     try {    
  99.                         while (totalTime != 0) {    
  100.                             Thread.sleep(THREAD_SLEEP_TIME);    
  101.                             next = random.nextInt(12) + 1;    
  102.                             time++;    
  103.                             handler.sendEmptyMessage(1);    
  104.                         }    
  105.         
  106.                     } catch (Exception e) {    
  107.                         e.printStackTrace();    
  108.                     }    
  109.                     if (totalTime == 0) {    
  110.                         Intent intent = new Intent(GameRun.this, GameOver.class);    
  111.                         // 该参数跳转页面不会触发onUserLeaveHint()方法    
  112.                         intent.addFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION);    
  113.                         intent.putExtra("score""" + nowScore);    
  114.                         GameRun.this.startActivity(intent);    
  115.                         finish();    
  116.                     }    
  117.                 }    
  118.             });    
  119.         }    
  120.         t.start();    
  121.     }    
  122.     
  123.     // 初始化按钮    
  124.     private void initImageButton() {    
  125.         one = (ImageButton) findViewById(R.id.first);    
  126.         two = (ImageButton) findViewById(R.id.second);    
  127.         three = (ImageButton) findViewById(R.id.three);    
  128.         four = (ImageButton) findViewById(R.id.four);    
  129.         five = (ImageButton) findViewById(R.id.five);    
  130.         six = (ImageButton) findViewById(R.id.six);    
  131.         seven = (ImageButton) findViewById(R.id.seven);    
  132.         eight = (ImageButton) findViewById(R.id.eight);    
  133.         nine = (ImageButton) findViewById(R.id.nine);    
  134.         ten = (ImageButton) findViewById(R.id.ten);    
  135.         eleven = (ImageButton) findViewById(R.id.eleven);    
  136.         twleve = (ImageButton) findViewById(R.id.twelve);    
  137.         showTime = (TextView) findViewById(R.id.showtime);    
  138.         score = (TextView) findViewById(R.id.score);    
  139.     }    
  140.     
  141.     // 给按钮添加点击事件    
  142.     private void initOnClick() {    
  143.         click = new MyClick();    
  144.         one.setOnClickListener(click);    
  145.         two.setOnClickListener(click);    
  146.         three.setOnClickListener(click);    
  147.         four.setOnClickListener(click);    
  148.         five.setOnClickListener(click);    
  149.         six.setOnClickListener(click);    
  150.         seven.setOnClickListener(click);    
  151.         eight.setOnClickListener(click);    
  152.         nine.setOnClickListener(click);    
  153.         ten.setOnClickListener(click);    
  154.         eleven.setOnClickListener(click);    
  155.         twleve.setOnClickListener(click);    
  156.     }    
  157.     
  158.     // 按钮id和next映射关系    
  159.     private void initbattleMap() {    
  160.         battle.put(one, 1);    
  161.         battle.put(two, 2);    
  162.         battle.put(three, 3);    
  163.         battle.put(four, 4);    
  164.         battle.put(five, 5);    
  165.         battle.put(six, 6);    
  166.         battle.put(seven, 7);    
  167.         battle.put(eight, 8);    
  168.         battle.put(nine, 9);    
  169.         battle.put(ten, 10);    
  170.         battle.put(eleven, 11);    
  171.         battle.put(twleve, 12);    
  172.     }    
  173.     
  174.     // next和按钮id的映射关系    
  175.     private void initNextMap() {    
  176.         nextMap.put(1, one);    
  177.         nextMap.put(2, two);    
  178.         nextMap.put(3, three);    
  179.         nextMap.put(4, four);    
  180.         nextMap.put(5, five);    
  181.         nextMap.put(6, six);    
  182.         nextMap.put(7, seven);    
  183.         nextMap.put(8, eight);    
  184.         nextMap.put(9, nine);    
  185.         nextMap.put(10, ten);    
  186.         nextMap.put(11, eleven);    
  187.         nextMap.put(12, twleve);    
  188.     }    
  189.     
  190.     /**  
  191.      * 更新小老鼠出现位置和显示游戏剩余时间  
  192.      */    
  193.     private void changeUI() {    
  194.         // 更新显示剩余时间,游戏0.5s更新一次,因此更新次数是游戏时间的二倍    
  195.         if (time % 2 == 0) {    
  196.             showTime.setText(--totalTime + "");    
  197.         }    
  198.         if (next == -1)    
  199.             return;    
  200.         // 每次出地鼠时将按钮背景初始化    
  201.         reImageButton();    
  202.         // 获得next对应的按钮    
  203.         ImageButton bt = nextMap.get(next);    
  204.         // 给按钮设置地鼠图片    
  205.         bt.setBackgroundResource(R.drawable.end);    
  206.     }    
  207.     
  208.     // 按钮背景初始化    
  209.     private void reImageButton() {    
  210.         one.setBackgroundResource(R.drawable.start);    
  211.         two.setBackgroundResource(R.drawable.start);    
  212.         three.setBackgroundResource(R.drawable.start);    
  213.         four.setBackgroundResource(R.drawable.start);    
  214.         five.setBackgroundResource(R.drawable.start);    
  215.         six.setBackgroundResource(R.drawable.start);    
  216.         seven.setBackgroundResource(R.drawable.start);    
  217.         eight.setBackgroundResource(R.drawable.start);    
  218.         nine.setBackgroundResource(R.drawable.start);    
  219.         ten.setBackgroundResource(R.drawable.start);    
  220.         eleven.setBackgroundResource(R.drawable.start);    
  221.         twleve.setBackgroundResource(R.drawable.start);    
  222.     }    
  223.     
  224.     /**  
  225.      * 点击事件,判断是否打中  
  226.      *   
  227.      * @author cyj  
  228.      *   
  229.      */    
  230.     class MyClick implements OnClickListener {    
  231.     
  232.         @Override    
  233.         public void onClick(View v) {    
  234.             // 是否的分的标记    
  235.             Boolean isScore = false;    
  236.             // 获取点击按钮对应next    
  237.             int battleId = battle.get(v);    
  238.             // 如果点击按钮为next得分    
  239.             if (battleId == next) {    
  240.                 // 得分为true    
  241.                 isScore = true;    
  242.             }    
  243.             if (isScore) {    
  244.                 // 设置打中的图片    
  245.                 v.setBackgroundResource(R.drawable.zhong);    
  246.                 if (MouseStart.controller.isPlay()) {    
  247.                     // 打中的音效    
  248.                     MouseStart.controller.playSound(R.raw.hathit);    
  249.                 }    
  250.                 // 加分    
  251.                 score.setText((nowScore += 10) + "");    
  252.             } else {    
  253.                 // 设置没打中的图片    
  254.                 v.setBackgroundResource(R.drawable.meizhong);    
  255.                 if (MouseStart.controller.isPlay()) {    
  256.                     // 没打中的音效    
  257.                     MouseStart.controller.playSound(R.raw.dismistake);    
  258.                 }    
  259.     
  260.             }    
  261.         }    
  262.     }    
  263.     @Override    
  264.     protected void onStop() {    
  265.         // 停止线程    
  266.         super.onStop();    
  267.         if (t != null) {    
  268.             t.interrupt();    
  269.             t = null;    
  270.         }    
  271.     }    
  272. }    

  小技巧:在本游戏中免不了各种判断:在产生地鼠位置时,要通过随机数来确定按钮位置,例如:如果随机数是1,则在第一个按钮设置地鼠图片,需要多次判断,应该是出现随机数1那么直接在第一个按钮设置;玩家点击按钮时,需要判断点击的是那个按钮并判断是否是有地鼠的按钮,再设置相应的图片。那么应该怎么办呢?

  答案是用HashMap来代替switch,在HashMap来映射随机数和按钮,更新地鼠位置时直接用随机数来获得按钮设置图片。用另一个HashMap中映射按钮和对应的随机数,这样在点击按钮时直接获取映射的数,该数和现在地鼠位置的随机数比较即可判断是否打中地鼠;这样就完美解决了。

本文发布:Android开发网
本文地址:http://www.jizhuomi.com/android/game/649.html
2017年2月15日
发布:鸡啄米 分类:Android游戏开发 浏览: 评论:0