二十一點可能是大家都玩過的遊戲,但是不同的地方有不同的遊戲規則。在這裏有必要具體說下我採用的遊戲規則,免得引起分歧,這也是我們做好這個遊戲的基礎。
我採用的二十一點遊戲規則:
1.每位玩家最多隻能拿五張撲克牌。也就是說,整個遊戲最多需要10張撲克牌,這一點非常重要。
2.整副撲克去掉大小王,由52張組成。
3. J,Q,K這些花牌在計算點數的時候都按10點來計算。
*****************************************
說完了遊戲規則,下面來說一說遊戲的設計思路吧。個人感覺只要把思路理清了,寫起代碼來就很快了。當然,我是初學者,大家可能有更好的思路,歡迎大家分享。
(1)首先想一下整個遊戲的界面。
a.用來顯示撲克圖片的Imageview,至少需要十張。
b.按鈕兩個(這裏先考慮最簡單的功能實現),分別是“要牌”和“開牌”按鈕。
c.用來顯示文本的Textview。需要三個,分別用來顯示玩家點數,電腦點數和遊戲結果。
其實組件很簡單,只要在草紙上畫明白了,程序界面的設計就差不多了。
(2)其次想一下采用何種佈局來佈置我們需要的組件。
android爲我們提供的佈局有:FrameLayout 佈局, LinearLayout 佈局,
RelativeLayout 佈局,AbsoluteLayout佈局 和 TableLayout 佈局。
那麼我們需要用什麼佈局呢?可以想一下我們平時玩的“二十一點”小遊戲,撲克牌都是以層疊的形式出現的,第二張撲克會把第一張的一部分遮住,同樣的第三張會把第二張的一部分遮住,這樣我們就很容易作出選擇,當然是採用AbsoluteLayout佈局最方便。
Main.xml
(3) 做完上面的工作,我們就需要找一些撲克牌的素材。
大家可以在以下網址http://download.csdn.net/source/2793071下載撲克牌的素材。
其次大家注意:在把撲克牌素材放入drawable時一定要注意圖片的命名方式,我也是在編程序的過程中發現這個問題,一點一點改過來的。android
對圖片的命名要求比較嚴格,不能使用純數字命名,不能用大寫字母命名,我在這裏使用的是“p+數字”的命名方式,而且數字也是按照1.....K每個數字
的每個花色有規律遞增的,只有這樣才能準確找到每個數字代表的
牌面數字,從而計算出玩家和電腦的點數。
drawable文件列表
*****************************************
做完這些界面,佈局和素材的準備,我們就要考慮我們的程序了。
首先,我的想法是:既然每次最多用到十張撲克牌,那麼我就聲明一個Imageview[10]數組,用來存儲這十張撲克牌,而且順序已經確定了。
那麼我們如何得到這十張撲克牌圖片信息呢?圖片在android中都是以十六進制(例:“0x7f020002”)形式保存的,我們只需要把這個數值得到並傳遞給Imageview[]就可以了。
R.java
問題又出現了:我們如何得到這個數值呢?android爲我們提供了getResources().getIdentifier(String
name, String defType, String
defPackage)這麼一個函數,後面兩個參數很好解決,就是"drawable"和我們使用的包的名字,第一個參數需要傳遞的是圖片的名稱,而且我
們須要得到的是隨機產生的一個圖片的名稱。這個問題怎麼解決呢?這就體現出我們撲克牌命名的優勢了,這些名稱除了後面的數字不同之外,其他的都是相同的。
沒錯,我們只要從1-52中產生十個不相同的數字,我們就得到了十個不相同的圖片的名稱,也就得到了十個十六進制的數值(也就是圖片在android中的
存儲數值),最後就得到了我們想要的十張圖片了!
好吧說了這麼多,我們寫程序的步驟是:
1.從1-52中隨機得到十個不相同(這點非常重要,否則你可能會看到系統發出同樣的撲克牌)的數。
2.通過getResources().getIdentifier(String name, String defType, String defPackage) 函數得到十個圖片在android中的存儲數值。
3.調用Imageview類中的setImageResource(int resId)函數,顯示得到的圖片。
*****************************************
其次我們要想一下我們對按鈕的監聽。
這時候需要 重寫onclick()函數,函數應該實現什麼內容呢?
“要牌”按鈕肯定是點擊一下會給玩家發一張撲克牌,也就是調用setImageResource(int
resId)函數,然後計算玩家的點數並顯示。如何計算玩家的點數呢?這時候又體現出我們照片命名方法的優勢了,照片p1-p4肯定是“1”的四種花色,
同理p37-p40肯定是“10”的四種花色。那麼我們根據剛纔得到的十個隨機數就可以計算出每張圖片的真實數值了,一定注意41-52代表的都是
“10”。
“要牌”按鈕點擊後,我們的電腦應該有什麼動作呢?作爲一個AI,肯定有自己一套固定的算法,我們來設計下我們的AI——電腦的發牌機制。
a.給電腦的第一張牌我們是能看到的。
b.從電腦的第二張撲克牌我們只能看到背面。
c.點擊“要牌”按鈕後,先給玩家發一張撲克牌,一個延遲之後纔給電腦發牌。
d.點擊“要牌”按鈕後,電腦不一定再需要撲克牌了(如果玩家已經爆掉或者自己已經爆掉肯定就不需要了)。
好吧,一個一個來實現吧!
首先肯定要延遲之後再發牌,就用到android中handler的相關知識了,需要和JAVA中的Timer類結合使用。
有關handler這個網址上面講的比較清楚:http://weizhulin.blog.51cto.com/1556324/323922
它用到的是Timer中的scheduleAtFixedRate(TimerTask task, Date
firstTime, long period)函數,這個函數是一段時間更新一次,也就是會一直顯示
。我們需要用到的是schedule(TimerTask task, long delay) 函數,就可以實現延遲的效果了。
然後要判斷是第幾次給電腦發牌,第2-5次時需加載我們的背面圖像,當然需要記錄當前給電腦發的是第幾張牌,方便我們計算電腦的點數和“開牌”時顯示電腦
的撲克牌圖片。我們需要做的還有比較當前玩家點數和電腦點數是否已經爆掉,判斷是否需要給電腦發牌。
“開牌”按鈕點擊後會有一些什麼動作呢?
a.“叫牌”按鈕設置爲不可用。
b.判斷是否應該給電腦發牌。爲什麼還要有這一步呢?因爲電腦的牌不一定會比玩家的少,而在“叫牌”按鈕的實現中我們可以清楚的看到電腦的牌數是小於等於
玩家的牌數的。如果在開牌的時候電腦發現自己的點數比玩家的小(在玩家未爆掉的前提下),即便是自己爆掉它也會接着要牌的,因爲如果不要牌的話肯定會輸
掉,而接着要牌可能有贏的可能(電腦知道玩家的點數,而玩家卻不知道電腦的點數,是不是有點不公平呢?沒辦法,誰讓人是電腦呢?呵呵)。
c.顯示電腦使用的撲克牌和點數。實現方法和玩家的相同。
d.比較玩家和電腦的點數,得到遊戲結果。
**********************************************************************************************************
這樣整個程序就結束了,最後再加點動畫效果就ok了!
遊戲界面:
整個程序的源碼已經上傳,還帶有清晰的註釋,大家多提意見!
大家也可以直接安裝apk文件看下效果。
程序下載:
http://download.csdn.net/source/2805888