安卓項目五子棋代碼詳解(五)


 

 

這一期給大家帶來我自己添加的功能,最近還搞了個播放背景音樂和下棋音效,與這個一起講了

 開筆之前,忽然響起還有一個保存游戲沒講,真是失誤。

保存游戲呢,就是將當前棋子的位置都保存下來,我們可以設想一個情景,玩家玩着游戲的時候,忽然一個電話過來,就會跳轉到打電話的界面,或者一條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相關,我整理了一下,請點擊

Android開發之SoundPool使用詳解

 

講完音效,到背景音樂了。

這背景音樂我其實找了好久的資料,但是總是實現不了,最后發現了問題,網上找的都是用對象new的一個對象,不知道為什么用不了,我的是直接聲明才可以使用的,不太懂前面為什么不能用,找到了答案再補上吧

 

 寫在尾聲:

五子棋作為android開發的簡單項目,特別適合新手入門,還可以在五子棋中添加自己能夠想象到功能,既可以學習,又可以從中得到樂趣。

我的五子棋還沒有實現藍牙對戰,自創熱點對戰,AI對戰,還有悔棋的功能,所以,我這系列還是沒有結束的~~O(∩_∩)O哈哈~

最近因為學習側滑菜單,eclipse上搞個Android5.0的SDK搞了半天都是不行的,所以轉到了Android Studio平台,這環境也是搞了兩天,真是累,不過可以用了,慢慢習慣Android Studio

感覺我的方法都是寫在了Panel類中,有些影響可讀性,之后有時間得優化一些項目,當然,用的是Android Studio

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM