遊戲的基本功能都已經實現了,最後來說一說排行榜的顯示和遊戲音效的添加。
排行榜的顯示主要用的Android中一個比較重要的控件ListView。ListView的使用還是比較簡單的,第一步在佈局文件中建立一個ListView的節點,在代碼中通過ID得到該控件。第二步給該控件設置一個適配器,適配器寫一個類,該類繼承BaseAdapter並實現未實現的方法,一共有4個爲實現的方法,getCount()獲得數據總數,getIten(int position)根據位置獲得某條數據,getItemId(int position)根據位置獲得某條數據id,getView(),得到相應位置的Item視圖。可以通過contentView對ListView進行優化,如果contentView爲空,通過inflate填充view,否則不填充,這樣減少了填充次數,提高了效率。代碼如下:
package cn.com.cyj.mouse.ui;
import java.util.ArrayList;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import cn.com.cyj.mouse.R;
import cn.com.cyj.mouse.enity.Gamer;
/**
* 顯示玩家排行榜
*
* @author cyj
*
*/
public class ShowRank extends BaseActivity {
ListView lv;
ArrayList<Gamer> gamerList;
TextView gamerName;
TextView gamerScore;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_showrank);
gamerList = new ArrayList<Gamer>();
Intent intent = getIntent();
gamerList = (ArrayList<Gamer>) intent.getSerializableExtra("gamerlist");
// 初始化listview對象
lv = (ListView) findViewById(R.id.lv);
// 給listview對象添加適配器
lv.setAdapter(new MyAdapter());
}
class MyAdapter extends BaseAdapter {
// 獲得數據總數
@Override
public int getCount() {
return gamerList.size();
}
// 根據位置獲得某條數據
@Override
public Object getItem(int position) {
return null;
}
// 根據位置獲得某條數據id
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int position, View contentView, ViewGroup parent) {
View v = contentView;
if (v == null) {
// 通過inflate填充view
v = View.inflate(ShowRank.this, R.layout.list_item, null);
gamerName = (TextView) v.findViewById(R.id.gamername);
gamerScore = (TextView) v.findViewById(R.id.gamerscore);
}
Gamer gamer = gamerList.get(position);
gamerName.setText(gamer.getName());
gamerScore.setText(gamer.getScore() + "");
return v;
}
}
}
一個遊戲沒有音效無可厚非,但是有了音效會更有樂趣。本遊戲採用了MediaPlayer+SoundPool的形式,前者播放背景音樂,後者播放遊戲的打擊音效,關於MediaPlayer的使用,沒有什麼比官方的圖來的更簡單粗暴了,這裏不再贅述。SoundPool的使用,第一步new SoundPool();第二步load(),通常用一個HashMap存放音樂文件id和load的映射;第三步play()。代碼如下:
package cn.com.cyj.mouse.services;
import java.util.HashMap;
import java.util.Map;
import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.SoundPool;
import cn.com.cyj.mouse.R;
/**
* 處理遊戲的背景音樂和音效
* @author cyj
*
*/
public class MusicService {
// 用來播放背景音樂
MediaPlayer player;
// 用來播放音效
SoundPool pool;
Context context;
// 存放音效
Map<Integer, Integer> soundMap;
public MusicService(Context context) {
this.context = context;
initMedia();
initSound();
}
private void initSound() {
pool = new SoundPool(3, AudioManager.STREAM_MUSIC, 0);
soundMap = new HashMap<Integer, Integer>();
// 加載音效文件並放入hashmap中
soundMap.put(R.raw.dismistake, pool.load(context, R.raw.dismistake, 1));
soundMap.put(R.raw.hathit, pool.load(context, R.raw.hathit, 1));
}
/**
* 通過resId播放在hashmap中對應的要播放的音效
* @param resId hashMap的key
*/
public void playSound(int resId){
// 獲得map的value即對應音效
Integer soundId = soundMap.get(resId);
if(soundId != null){
pool.play(soundId, 1, 1, 1, 0, 1);
}
}
private void initMedia(){
// 第一次播放不用prepare
player = MediaPlayer.create(context, R.raw.bg);
// 循環播放
player.setLooping(true);
}
public void play() {
// 播放背景音樂
player.start();
}
/**
* 停止播放
*/
public void stop() {
if (player.isPlaying()) {
player.stop();
try {
player.prepare();
// stop後再次start會繼續播放,設置從0開始播放
player.seekTo(0);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 暫停播放
*/
public void pause(){
if(player.isPlaying()){
player.pause();
}
}
/**
* 遊戲退出釋放資源
*/
public void close() {
if(player == null)
return ;
if(player.isPlaying()){
// 停止播放
player.stop();
}
// 釋放資源,無法使用。mediaPlayer引用還在
player.release();
player = null;
}
/**
* 繼續播放音樂
*/
public void continuePlay() {
player.start();
}
/**
* 判斷背景音樂是否在播放
* @return
*/
public Boolean isNowPlay(){
if(player.isPlaying()){
return true;
}
return false;
}
}
遊戲中的控制類,該類處理玩家對界面的操作和遊戲響應,把界面操作和遊戲邏輯分開設計,降低耦合性。代碼如下:
package cn.com.cyj.mouse.controller;
import java.util.ArrayList;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import cn.com.cyj.mouse.database.GamerDatabase;
import cn.com.cyj.mouse.enity.Gamer;
import cn.com.cyj.mouse.services.MusicService;
import cn.com.cyj.mouse.ui.ShowRank;
/**
* 遊戲中的控制類
* @author cyj
*
*/
public class Controller {
ArrayList<Gamer> gamerList;
GamerDatabase gamerDatabase;
Context context;
MusicService musicService;
public Controller(Context context) {
this.context = context;
gamerDatabase = new GamerDatabase(context);
musicService = new MusicService(context);
gamerList = new ArrayList<Gamer>();
}
/**
* 插入數據
*
* @param gamer
* 玩家對象
* @return true 插入玩家成功;false 插入玩家失敗
*/
public Boolean insert(Gamer gamer) {
if (gamerDatabase.insertGamer(gamer))
return true;
return false;
}
/**
* 查詢所有玩家信息
*
* @return true 有玩家信息; false 沒有玩家信息
*/
public Boolean query() {
gamerList = gamerDatabase.queryGamerAll();
if (gamerList.size() == 0)
return false;
Intent intent = new Intent(context, ShowRank.class);
Bundle bundle = new Bundle();
// 裝入被序列化的玩家信息列表,將數據傳到新的Activity
bundle.putSerializable("gamerlist", gamerList);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION);
context.startActivity(intent);
return true;
}
/**
* 播放音樂
*/
public void play() {
musicService.play();
}
/**
* 關閉音樂
*/
public void stop() {
musicService.stop();
}
/**
* 暫停音樂
*/
public void pauseMusic() {
musicService.pause();
}
/**
* 繼續播放
*/
public void continuePlay() {
musicService.continuePlay();
}
/**
* 遊戲結束釋放資源
*/
public void close() {
musicService.close();
}
/**
* 播放音效
* @param resId 音樂文件資源id
*/
public void playSound(int resId) {
musicService.playSound(resId);
}
/**
* 判斷音樂是否在播放
* @return true音樂正在播放,false音樂已經停止
*/
public Boolean isPlay(){
if(musicService.isNowPlay()){
return true;
}
return false;
}
}