Android學習 遊戲開發之打地鼠(三,打地鼠設計實現)

上篇文章中對開始打地鼠遊戲的思路做了簡單的介紹,現在來具體的說一說開始打地鼠遊戲的實現,先說說佈局,用LinearLayout或TableLyout都可以。上面一行是4個TextView下面的地洞是ImageButton。遊戲中打中或沒打中地鼠都更新會對應按鈕背景圖。打中地鼠的效果圖(圖1)和沒打中的效果圖(圖2)。

遊戲中需要開啓一個線程來控制遊戲時間,更新顯示剩餘時間時,遊戲0.5s更新一次,遊戲時間爲30s,因此更新次數是遊戲時間的二倍。當遊戲時間爲0s時遊戲停止關閉遊戲界面並開啓記錄玩家信息的窗口。該線程同時產生一個隨機數(1-12)來指定地鼠出現位置,由於子線程不能更新UI,需要通過handler發送消息來更新UI。更新界面時將每一個按鈕背景都有重置爲地洞,再更新地鼠出現位置的圖片,這樣會清除由於點擊出現的錘子和上一次地鼠出現位置設置的圖片。當用戶點擊屏幕是,如果打中地鼠,效果如圖1,沒打中效果如圖2,並且如果開啓了音效,會播放不同的打擊聲音。最後在遊戲界面不可見是關閉線程。

代碼如下:

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;
		}
	}
}
小技巧:記得有位大神說過switch是小白專用(我也是一個小白),在本遊戲中免不了各種判斷:在產生地鼠位置時,要通過隨機數來確定按鈕位置,例如:如果隨機數是1,則在第一個按鈕設置地鼠圖片,需要多次判斷,應該是出現隨機數1那麼直接在第一個按鈕設置;玩家點擊按鈕時,需要判斷點擊的是那個按鈕並判斷是否是有地鼠的按鈕,再設置相應的圖片。那麼應該怎麼辦呢?

答案是用HashMap來代替switch,在HashMap來映射隨機數和按鈕,更新地鼠位置時直接用隨機數來獲得按鈕設置圖片。用另一個HashMap中映射按鈕和對應的隨機數,這樣在點擊按鈕時直接獲取映射的數,該數和現在地鼠位置的隨機數比較即可判斷是否打中地鼠;這樣就完美解決了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章