上篇文章中對開始打地鼠游戲的思路做了簡單的介紹,現在來具體的說一說開始打地鼠游戲的實現,先說說布局,用LinearLayout或TableLyout都可以。上面一行是4個TextView下面的地洞是ImageButton。游戲中打中或沒打中地鼠都更新會對應按鈕背景圖。打中地鼠的效果圖(圖1)和沒打中的效果圖(圖2)。
游戲中需要開啟一個線程來控制游戲時間,更新顯示剩余時間時,游戲0.5s更新一次,游戲時間為30s,因此更新次數是游戲時間的二倍。當游戲時間為0s時游戲停止關閉游戲界面並開啟記錄玩家信息的窗口。該線程同時產生一個隨機數(1-12)來指定地鼠出現位置,由於子線程不能更新UI,需要通過handler發送消息來更新UI。更新界面時將每一個按鈕背景都有重置為地洞,再更新地鼠出現位置的圖片,這樣會清除由於點擊出現的錘子和上一次地鼠出現位置設置的圖片。當用戶點擊屏幕是,如果打中地鼠,效果如圖1,沒打中效果如圖2,並且如果開啟了音效,會播放不同的打擊聲音。最後在游戲界面不可見是關閉線程。
代碼如下:
Java代碼
- package cn.com.cyj.mouse.services;
-
- import java.util.HashMap;
- import java.util.Random;
-
- import android.content.Intent;
- import android.os.Bundle;
- import android.os.Handler;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.ImageButton;
- import android.widget.TextView;
- import cn.com.cyj.mouse.R;
- import cn.com.cyj.mouse.ui.BaseActivity;
- import cn.com.cyj.mouse.ui.MouseStart;
-
- /**
- * 游戲開始的界面:游戲中有12個ImageButton,每個ImageButton背景設置成地鼠洞,游戲中開啟一個線程控制游戲時間
- *
- * @author cyj
- *
- */
- public class GameRun extends BaseActivity {
- /**
- * 線程睡眠時間
- */
- public static final int THREAD_SLEEP_TIME = 500;
- /**
- * 游戲時間
- */
- public static final int TIME = 30;
- private ImageButton one;
- private ImageButton two;
- private ImageButton three;
- private ImageButton four;
- private ImageButton five;
- private ImageButton six;
- private ImageButton seven;
- private ImageButton eight;
- private ImageButton nine;
- private ImageButton ten;
- private ImageButton eleven;
- private ImageButton twleve;
- // 顯示時間
- private TextView showTime;
- // 顯示分數
- private TextView score;
- MyClick click;
-
- private Random random;
- // 游戲當前時間
- private int time;
- // 游戲總時間
- private int totalTime;
- // 老鼠下一次出現位置
- private int next;
- // 游戲當前分數
- private int nowScore;
- // 游戲線程
- private Thread t;
- // 存放按鈕和next的映射
- HashMap<ImageButton, Integer> battle;
- HashMap<Integer, ImageButton> nextMap;
- public Handler handler = new Handler() {
- public void handleMessage(android.os.Message msg) {
- changeUI();
- };
- };
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_gamerun);
-
- battle = new HashMap<ImageButton, Integer>();
- nextMap = new HashMap<Integer, ImageButton>();
- initImageButton();
- initOnClick();
- initbattleMap();
- initNextMap();
- next = -1;
- random = new Random();
- totalTime = TIME;
- time = 0;
- nowScore = 0;
- showTime.setText(TIME + "");
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- if(t == null){
- // 控制游戲時間
- t = new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- while (totalTime != 0) {
- Thread.sleep(THREAD_SLEEP_TIME);
- next = random.nextInt(12) + 1;
- time++;
- handler.sendEmptyMessage(1);
- }
-
- } catch (Exception e) {
- e.printStackTrace();
- }
- if (totalTime == 0) {
- Intent intent = new Intent(GameRun.this, GameOver.class);
- // 該參數跳轉頁面不會觸發onUserLeaveHint()方法
- intent.addFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION);
- intent.putExtra("score", "" + nowScore);
- GameRun.this.startActivity(intent);
- finish();
- }
- }
- });
- }
- t.start();
- }
-
- // 初始化按鈕
- private void initImageButton() {
- one = (ImageButton) findViewById(R.id.first);
- two = (ImageButton) findViewById(R.id.second);
- three = (ImageButton) findViewById(R.id.three);
- four = (ImageButton) findViewById(R.id.four);
- five = (ImageButton) findViewById(R.id.five);
- six = (ImageButton) findViewById(R.id.six);
- seven = (ImageButton) findViewById(R.id.seven);
- eight = (ImageButton) findViewById(R.id.eight);
- nine = (ImageButton) findViewById(R.id.nine);
- ten = (ImageButton) findViewById(R.id.ten);
- eleven = (ImageButton) findViewById(R.id.eleven);
- twleve = (ImageButton) findViewById(R.id.twelve);
- showTime = (TextView) findViewById(R.id.showtime);
- score = (TextView) findViewById(R.id.score);
- }
-
- // 給按鈕添加點擊事件
- private void initOnClick() {
- click = new MyClick();
- one.setOnClickListener(click);
- two.setOnClickListener(click);
- three.setOnClickListener(click);
- four.setOnClickListener(click);
- five.setOnClickListener(click);
- six.setOnClickListener(click);
- seven.setOnClickListener(click);
- eight.setOnClickListener(click);
- nine.setOnClickListener(click);
- ten.setOnClickListener(click);
- eleven.setOnClickListener(click);
- twleve.setOnClickListener(click);
- }
-
- // 按鈕id和next映射關系
- private void initbattleMap() {
- battle.put(one, 1);
- battle.put(two, 2);
- battle.put(three, 3);
- battle.put(four, 4);
- battle.put(five, 5);
- battle.put(six, 6);
- battle.put(seven, 7);
- battle.put(eight, 8);
- battle.put(nine, 9);
- battle.put(ten, 10);
- battle.put(eleven, 11);
- battle.put(twleve, 12);
- }
-
- // next和按鈕id的映射關系
- private void initNextMap() {
- nextMap.put(1, one);
- nextMap.put(2, two);
- nextMap.put(3, three);
- nextMap.put(4, four);
- nextMap.put(5, five);
- nextMap.put(6, six);
- nextMap.put(7, seven);
- nextMap.put(8, eight);
- nextMap.put(9, nine);
- nextMap.put(10, ten);
- nextMap.put(11, eleven);
- nextMap.put(12, twleve);
- }
-
- /**
- * 更新小老鼠出現位置和顯示游戲剩余時間
- */
- private void changeUI() {
- // 更新顯示剩余時間,游戲0.5s更新一次,因此更新次數是游戲時間的二倍
- if (time % 2 == 0) {
- showTime.setText(--totalTime + "");
- }
- if (next == -1)
- return;
- // 每次出地鼠時將按鈕背景初始化
- reImageButton();
- // 獲得next對應的按鈕
- ImageButton bt = nextMap.get(next);
- // 給按鈕設置地鼠圖片
- bt.setBackgroundResource(R.drawable.end);
- }
-
- // 按鈕背景初始化
- private void reImageButton() {
- one.setBackgroundResource(R.drawable.start);
- two.setBackgroundResource(R.drawable.start);
- three.setBackgroundResource(R.drawable.start);
- four.setBackgroundResource(R.drawable.start);
- five.setBackgroundResource(R.drawable.start);
- six.setBackgroundResource(R.drawable.start);
- seven.setBackgroundResource(R.drawable.start);
- eight.setBackgroundResource(R.drawable.start);
- nine.setBackgroundResource(R.drawable.start);
- ten.setBackgroundResource(R.drawable.start);
- eleven.setBackgroundResource(R.drawable.start);
- twleve.setBackgroundResource(R.drawable.start);
- }
-
- /**
- * 點擊事件,判斷是否打中
- *
- * @author cyj
- *
- */
- class MyClick implements OnClickListener {
-
- @Override
- public void onClick(View v) {
- // 是否的分的標記
- Boolean isScore = false;
- // 獲取點擊按鈕對應next
- int battleId = battle.get(v);
- // 如果點擊按鈕為next得分
- if (battleId == next) {
- // 得分為true
- isScore = true;
- }
- if (isScore) {
- // 設置打中的圖片
- v.setBackgroundResource(R.drawable.zhong);
- if (MouseStart.controller.isPlay()) {
- // 打中的音效
- MouseStart.controller.playSound(R.raw.hathit);
- }
- // 加分
- score.setText((nowScore += 10) + "");
- } else {
- // 設置沒打中的圖片
- v.setBackgroundResource(R.drawable.meizhong);
- if (MouseStart.controller.isPlay()) {
- // 沒打中的音效
- MouseStart.controller.playSound(R.raw.dismistake);
- }
-
- }
- }
- }
- @Override
- protected void onStop() {
- // 停止線程
- super.onStop();
- if (t != null) {
- t.interrupt();
- t = null;
- }
- }
- }
小技巧:在本游戲中免不了各種判斷:在產生地鼠位置時,要通過隨機數來確定按鈕位置,例如:如果隨機數是1,則在第一個按鈕設置地鼠圖片,需要多次判斷,應該是出現隨機數1那麼直接在第一個按鈕設置;玩家點擊按鈕時,需要判斷點擊的是那個按鈕並判斷是否是有地鼠的按鈕,再設置相應的圖片。那麼應該怎麼辦呢?
答案是用HashMap來代替switch,在HashMap來映射隨機數和按鈕,更新地鼠位置時直接用隨機數來獲得按鈕設置圖片。用另一個HashMap中映射按鈕和對應的隨機數,這樣在點擊按鈕時直接獲取映射的數,該數和現在地鼠位置的隨機數比較即可判斷是否打中地鼠;這樣就完美解決了。