這一期給大家帶來我自己添加的功能,最近還搞了個播放背景音樂和下棋音效,與這個一起講了
開筆之前,忽然響起還有一個保存游戲沒講,真是失誤。
保存游戲呢,就是將當前棋子的位置都保存下來,我們可以設想一個情景,玩家玩着游戲的時候,忽然一個電話過來,就會跳轉到打電話的界面,或者一條QQ消息要處理,玩家跳轉到了QQ的界面處理消息,待他處理完之后,就會返回游戲,如果我們沒有設置保存游戲的這個方法的話,那么玩家再次進入的時候就是跟開始的一樣,這樣的體驗非常糟糕,所以保存游戲這個方法是必須要有的。
首先在Panel類中聲明四個靜態變量
private static final String INSTANCE = "instance"; private static final String INSTANCE_GAME_OVER = "instance_game_over" ;//游戲狀態 private static final String INSTANCE_WHITE_ARRAY = "instance_white_array";//白棋坐標 private static final String INSTANCE_BLACK_ARRAY = "instance_black_array";//黑棋坐標
之后,復寫onSaveInstanceState()和onRestoreInstanceState()這兩個方法
@Override protected Parcelable onSaveInstanceState() {//存儲當前下棋狀態 Bundle bundle = new Bundle(); bundle.putParcelable(INSTANCE, super.onSaveInstanceState()); bundle.putBoolean(INSTANCE_GAME_OVER, IsGameOver); bundle.putParcelableArrayList(INSTANCE_WHITE_ARRAY, Whitearray); bundle.putParcelableArrayList(INSTANCE_BLACK_ARRAY, Blackarray); return bundle; } @Override protected void onRestoreInstanceState(Parcelable state) {//恢復下棋狀態 if(state instanceof Bundle){ Bundle bundle = (Bundle) state; IsGameOver = bundle.getBoolean(INSTANCE_GAME_OVER); Whitearray = bundle.getParcelable(INSTANCE_WHITE_ARRAY); Blackarray = bundle.getParcelable(INSTANCE_BLACK_ARRAY); super.onRestoreInstanceState(bundle.getParcelable(INSTANCE)); return; }
這里簡單的解釋一下,當用戶跳轉到其他的界面的時候,onSaveInstanceState()這個方法就會執行,將當前游戲狀態,白棋坐標與黑棋坐標儲存,返回bundle,這個bundle我個人理解成一個鑰匙或者是令牌,用戶回到游戲,判斷語句判斷是否有鑰匙或令牌,若有,就開門,恢復已儲存的東西
接下來就是關於界面及相關功能的介紹詳細講解
,給大家上張圖片
首先,我們要定義一個xml界面,如圖,可以知道有着七個控件
xml代碼如下
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/main" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/bsd" tools:context=".MainActivity" > <com.wan.wuziqi.Panel android:id="@+id/wuziqi" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerInParent="true" android:visibility="gone" /> <Button android:id="@+id/gamestart" android:layout_width="120dp" android:layout_height="60dp" android:background="@drawable/bgcolor" android:visibility="visible" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="131dp" android:text="@string/gamestart" /> <Button android:id="@+id/changebackground" android:visibility="visible" android:layout_width="120dp" android:layout_height="60dp" android:layout_alignLeft="@+id/gamestart" android:layout_below="@+id/gamestart" android:layout_marginTop="14dp" android:background="@drawable/bgcolor" android:text="@string/changebackground" /> <Button android:id="@+id/about" android:visibility="visible" android:layout_width="120dp" android:layout_height="60dp" android:layout_alignLeft="@+id/quit" android:layout_below="@+id/quit" android:layout_marginTop="14dp" android:background="@drawable/bgcolor" android:text="@string/about" /> <Button android:id="@+id/quit" android:visibility="visible" android:layout_width="120dp" android:layout_height="60dp" android:layout_alignLeft="@+id/changebackground" android:layout_below="@+id/changebackground" android:layout_marginTop="16dp" android:background="@drawable/bgcolor" android:text="@string/quit" /> <ImageView android:id="@+id/title" android:layout_width="200dp" android:layout_height="80dp" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:src="@drawable/title" android:visibility="visible" /> <Button android:id="@+id/luozisound" android:layout_width="25dp" android:layout_height="25dp" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:background="@drawable/yx1" /> <Button android:id="@+id/bgmsound" android:layout_width="25dp" android:layout_height="25dp" android:layout_alignBottom="@+id/luozisound" android:layout_toRightOf="@+id/luozisound" android:background="@drawable/bgm1" /> </RelativeLayout>
標題上的污子棋是一個ImageView,其余的都是button按鈕
背景直接在relativeLayout中設置背景就好,其余的也是簡簡單單的設置一下圖片,位置的話直接用拖動就好,所見即所得,這倒是很方便。
值得一提的是,button中我用的背景是圓角矩形,上面的文字都是調用string中的字符,寫在string中也是方便管理,左上角的兩個button是我用來實現控制背景音樂和音效的控制開關,點擊就是關閉
接下來就是到java代碼部分了
在MainActiviity 的onCreate()方法上方聲明變量
Panel p; Button gamestart,changebackground,quit,about,bgmsound,luozisound; View imageview; RelativeLayout relativelayout;//更換背景需要調用此對象
private MediaPlayer bgmsoundPlayer;//背景音樂對象 int i=0;
之后,在onCreate()方法之中使用findViewbyID()方法
p = (Panel)findViewById(R.id.wuziqi);
gamestart = (Button)findViewById(R.id.gamestart);
changebackground = (Button)findViewById(R.id.changebackground);
quit = (Button)findViewById(R.id.quit);
about = (Button)findViewById(R.id.about);
imageview = (View)findViewById(R.id.title);
bgmsound = (Button)findViewById(R.id.bgmsound);
luozisound = (Button)findViewById(R.id.luozisound);
relativelayout = (RelativeLayout)findViewById(R.id.main);
之后,初始化背景音樂的文件
bgmsoundPlayer = MediaPlayer.create(this, R.raw.bgm);//加載背景音樂文件資源,准備狀態,start()方法才可以成功播放 bgmsoundPlayer.setLooping(true);//設置循環播放 bgmsoundPlayer.start();
背景音樂文件放在res/raw的文件夾中,若沒有可以新建一個
在之后,就是為button按鈕綁定監聽器,重寫onClick()事件方法
ButtonListener buttonlistener = new ButtonListener(); gamestart.setOnClickListener(buttonlistener); changebackground.setOnClickListener(buttonlistener); quit.setOnClickListener(buttonlistener); about.setOnClickListener(buttonlistener); bgmsound.setOnClickListener(buttonlistener); luozisound.setOnClickListener(buttonlistener);
class ButtonListener implements OnClickListener{ @Override public void onClick(View v) { switch (v.getId()) { case R.id.gamestart: conceal(); p.setVisibility(View.VISIBLE); break; case R.id.changebackground: changebackground(); break; case R.id.quit: quit(); break; case R.id.about: AlertDialog.Builder builder1 = new AlertDialog.Builder(MainActivity.this);//參數里面注意!!! builder1.setTitle("關於"); builder1.setMessage("作者:柯興新一\n說明:本軟件純屬娛樂,勿作商業用途!!"); builder1.setPositiveButton("確定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface arg0, int arg1) { arg0.cancel(); }}); builder1.create().show(); break; case R.id.luozisound: luoziButtonChange(p.luozisoundOn); p.luozisoundOn = !p.luozisoundOn; case R.id.bgmsound: bgmButtonChange(p.bgmsoundOn); p.bgmsoundOn = !p.bgmsoundOn; default: break; } }
這里使用了switch語句,調用View里的getId()方法獲得當前觸摸控件的ID,之后由case語句為不同ID分配不同的方法
這里首先要說明的是,除了左上角的那兩個button按鈕不用隱藏,其余的都應該是點擊一下之后便是隱藏起來,由於代碼相同,為了使代碼簡潔,我就把設置button按鈕隱藏的代碼寫進了conceal()方法之中
private void conceal(){ imageview.setVisibility(View.INVISIBLE); gamestart.setVisibility(View.INVISIBLE); changebackground.setVisibility(View.INVISIBLE); quit.setVisibility(View.INVISIBLE); about.setVisibility(View.INVISIBLE); }
改變背景的方法
private void changebackground(){ switch (i){ case 0: relativelayout.setBackgroundResource(R.drawable.bsd2); i++; break; case 1: relativelayout.setBackgroundResource(R.drawable.bsd3); i++; break; case 2: relativelayout.setBackgroundResource(R.drawable.bsd4); i++; break; case 3: relativelayout.setBackgroundResource(R.drawable.bsd5); i++; break; case 4: relativelayout.setBackgroundResource(R.drawable.bsd6); i++; break; case 5: relativelayout.setBackgroundResource(R.drawable.bsd7); i++; break; case 6: relativelayout.setBackgroundResource(R.drawable.bsd8); i++; break; case 7: relativelayout.setBackgroundResource(R.drawable.bsd); i=0; break; } } }
這里說明一下,在之前的聲明有聲明了一個int型的變量i,它的目的就是用在改變背景的這里,就相當於一個定時器,還是由switch()語句,由i的值改變從而換成不同的背景,當然,若果你想的話,這里還可以弄成一個隨機更換背景圖片的,在case 末尾給i 隨機賦值就可以達到隨機的更換背景圖片的效果了,具體的請各位自己去嘗試。
quit()方法
private void quit(){ AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);//參數里面注意!!! builder.setMessage("是否退出?"); builder.setPositiveButton("是", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.cancel(); onDestroy(); } }).setNegativeButton("否", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.cancel(); } }); builder.create().show();
}
點擊退出游戲按鈕時,會彈出一個對話框,由用戶選擇是否退出
第一行代碼一直搞了半天,發現是里面參數的問題,所以一定要注意參數
builder.setPositiveButton("是",新建監聽器).setNegativeButton("否", 新建監聽器);
positive是消極的,negative是積極的,不過這兩個按鈕監聽器里的onClick事件不分消極還是積極的
quit()里的onDestroy()方法
@Override protected void onDestroy() { super.onDestroy(); System.exit(0); } }
System.exit(0)為完全退出
關於背景音樂和音效,我還設置了點擊變色的功能
我定義了兩個方法,luoziButtonChange()和bgmButtonChange()方法,參數里面傳入一個boolean值
PS:bgmsoundOn和luozisoundOn這兩個是在Panel類中定義的boolean值,默認是true
點擊之后就會進行邏輯計算,由!邏輯運算符轉換數值
private void luoziButtonChange(boolean a){ if(a){ luozisound.setBackgroundResource(R.drawable.yx2); }else{ luozisound.setBackgroundResource(R.drawable.yx1); } } private void bgmButtonChange(boolean a){ if(a){ bgmsound.setBackgroundResource(R.drawable.bgm2); bgmsoundPlayer.stop(); }else{ bgmsound.setBackgroundResource(R.drawable.bgm1); try { bgmsoundPlayer.prepare();//停止之后需要進入准備狀態,下一次start()方法才可以成功播放 } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } bgmsoundPlayer.start(); } }
改變圖片調用setBackgroundResource()方法,音效使用的是soundpool,還有個play()方法用來播放聲音,每畫一個棋子,就播放一次聲音,所以我將play()方法放在了Panel類中的畫棋子方法中了
luozisoundCheck()方法
public void luozisoundCheck(){ if(luozisoundOn){ luozisound.play(1,1, 1, 0, 0, 1); }else{ luozisound.stop(1); } }
if語句判斷luozisoundOn的值是否為true,為true執行播放,為fasle停止播放
關於soundpool相關,我整理了一下,請點擊
講完音效,到背景音樂了。
這背景音樂我其實找了好久的資料,但是總是實現不了,最后發現了問題,網上找的都是用對象new的一個對象,不知道為什么用不了,我的是直接聲明才可以使用的,不太懂前面為什么不能用,找到了答案再補上吧


寫在尾聲:
五子棋作為android開發的簡單項目,特別適合新手入門,還可以在五子棋中添加自己能夠想象到功能,既可以學習,又可以從中得到樂趣。
我的五子棋還沒有實現藍牙對戰,自創熱點對戰,AI對戰,還有悔棋的功能,所以,我這系列還是沒有結束的~~O(∩_∩)O哈哈~
最近因為學習側滑菜單,eclipse上搞個Android5.0的SDK搞了半天都是不行的,所以轉到了Android Studio平台,這環境也是搞了兩天,真是累,不過可以用了,慢慢習慣Android Studio
感覺我的方法都是寫在了Panel類中,有些影響可讀性,之后有時間得優化一些項目,當然,用的是Android Studio
