天天看點

android 桌面鬥地主

發一個鬥地主遊戲的牌桌實作。

為了節約記憶體資源,每張撲克牌都是剪切形成的,當然這也是目前程式設計的主流方法。

 1、主Activity

[java]

<span style="font-size:18px;color:#3333ff;">package com.bison; 

import android.app.Activity; 

import android.content.pm.ActivityInfo; 

import android.os.Bundle; 

import android.view.Window; 

import android.view.WindowManager; 

/**

 * 求某公司包養

 * 

 * @author Bison

 */ 

public class PukeActivity extends Activity { 

    /** Called when the activity is first created. */ 

    @Override 

    public void onCreate(Bundle savedInstanceState) { 

        super.onCreate(savedInstanceState); 

        // 這個事隐藏标題欄,不解釋 

        requestWindowFeature(Window.FEATURE_NO_TITLE); 

        // 隐藏狀态欄,你懂的 

        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 

                WindowManager.LayoutParams.FLAG_FULLSCREEN); 

        /*

         * 開始有考慮使螢幕上撲克的排列随螢幕的分辨率變動 結果貌似不好做,注釋掉了 Display display =

         * getWindowManager().getDefaultDisplay(); int screenWidth =

         * display.getWidth(); int screenHeight = display.getHeight();

         */ 

        // 使用代碼鎖定橫屏 

        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 

        // setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);這個是豎屏 

        setContentView(new GameView(this)); 

    } 

}</span> 

2、牌桌頁面

<span style="color:#3333ff;">package com.bison; 

import android.content.Context; 

import android.graphics.Bitmap; 

import android.graphics.BitmapFactory; 

import android.graphics.Canvas; 

import android.graphics.Rect; 

import android.view.MotionEvent; 

import android.view.SurfaceHolder; 

import android.view.SurfaceView; 

import com.bison.utils.Person; 

 * 牌桌,會被老婆罵,最好不要上去,你懂的

 * 撲克圖檔來源,和牌桌背景在文章的下面。 撲克背面圖等我沒上傳,玩家自行百度

public class GameView extends SurfaceView implements SurfaceHolder.Callback { 

    private FlushThread thread = null;// 刷幀線程 

    private Bitmap sourceBitmap = null;// 撲克圖檔來源 

    private Bitmap backgroundDesk = null;// 牌桌背景 

    private Bitmap backgroundPuke = null;// 撲克背面 

    private final Person person; 

    private int pukeWidth = 0;// 撲克的寬 

    private int pukeHeight = 0;// 撲克的高 

    private int deskWidth = 0;// 牌桌的寬 

    private int deskHeight = 0;// 牌桌的高 

    private int left = 0;// 我自己首張牌左距離 

    public GameView(Context context) { 

        super(context); 

        getHolder().addCallback(this); 

        this.thread = new FlushThread(getHolder(), this);// 執行個體化線程 

        initBitmap();// 執行個體化圖檔 

        this.person = new Person();// 執行個體化Person類 

        this.left = deskWidth / 2 - (16 * 25 + pukeWidth) / 2;// 左距開始時指派 

    private void initBitmap() {// 初始化圖檔 

        sourceBitmap = BitmapFactory.decodeResource(getResources(), 

                R.drawable.smallcard); 

        pukeWidth = sourceBitmap.getWidth() / 14;// 每張撲克的寬高 

        pukeHeight = sourceBitmap.getHeight() / 4; 

        backgroundDesk = BitmapFactory.decodeResource(getResources(), 

                R.drawable.gameback2); 

        deskWidth = backgroundDesk.getWidth();// 牌桌的寬高 

        deskHeight = backgroundDesk.getHeight(); 

        backgroundPuke = BitmapFactory.decodeResource(getResources(), 

                R.drawable.cardback); 

    protected void onDraw(Canvas canvas) { 

        // 繪制牌桌 

        canvas.drawBitmap(backgroundDesk, 0, 0, null); 

        personPaint(canvas, pukeWidth, pukeHeight); 

        deskthreePukes(canvas, pukeWidth, pukeHeight); 

    /** 繪制每個玩家手裡的牌 */ 

    public void personPaint(Canvas c, int pukeWidth, int pukeHeight) { 

        Rect src = new Rect(); 

        Rect dst = new Rect(); 

        // 周遊數組 

        for (int i = 0; i < 3; i++) { 

            for (int j = 0; j < 17; j++) { 

                if (i == 0) {// 左手邊玩家,不用繪出正面 

                    // src = person.cardRect(person.person1[j], pukeWidth, 

                    // pukeHeight); 

                    // dst.set(10, j * 20, 10 + pukeWidth, j * 20 + pukeHeight); 

                    c.drawBitmap(backgroundPuke, 35, 85, null); 

                } 

                if (i == 1) {// 自己 

                    src = person.cardRect(person.person2[j], pukeWidth, 

                            pukeHeight); 

                    dst.set(left + j * 25, this.deskHeight - 20 - pukeHeight, 

                            left + j * 25 + pukeWidth, deskHeight - 20); 

                    c.drawBitmap(sourceBitmap, src, dst, null); 

                if (i == 2) {// 右手邊玩家,同樣不用繪出正面 

                    // src = person.cardRect(person.person3[j], pukeWidth, 

                    // dst.set(this.screenWidth - 10 - pukeWidth, j * 20, 

                    // this.screenWidth - 10, j * 20 + pukeHeight); 

                    c.drawBitmap(backgroundPuke, deskWidth - 35 - pukeWidth, 

                            85, null); 

            } 

        } 

    /** 繪制三張底牌 */ 

    private void deskthreePukes(Canvas c, int pukeWidth, int pukeHeight) { 

            src = person.cardRect(person.threePukes[i], pukeWidth, pukeHeight); 

            dst.set(280 + i * pukeWidth, 12, 280 + (i + 1) * pukeWidth, 

                    12 + pukeHeight); 

            c.drawBitmap(sourceBitmap, src, dst, null); 

    public boolean onTouchEvent(MotionEvent event) { 

        return super.onTouchEvent(event); 

    public void surfaceChanged(SurfaceHolder holder, int format, int width, 

            int height) { 

    public void surfaceCreated(SurfaceHolder holder) { 

        this.thread.setFlag(true); 

        this.thread.start(); 

    public void surfaceDestroyed(SurfaceHolder holder) { 

        boolean retry = true; 

        this.thread.setFlag(false); 

        while (retry) { 

            try { 

                thread.join(); 

                retry = false; 

            } catch (InterruptedException e) { 

                e.printStackTrace(); 

    class FlushThread extends Thread { 

        private boolean flag = false; 

        private final int span = 500; 

        private final GameView gameView; 

        private final SurfaceHolder holder; 

        public FlushThread(SurfaceHolder holder, GameView gameView) { 

            this.gameView = gameView; 

            this.holder = holder; 

        @Override 

        public void run() { 

            Canvas canvas; 

            while (this.flag) { 

                canvas = null; 

                try { 

                    canvas = this.holder.lockCanvas(null); 

                    synchronized (this.holder) { 

                        this.gameView.onDraw(canvas); 

                    } 

                } finally { 

                    if (canvas != null) { 

                        this.holder.unlockCanvasAndPost(canvas); 

                    Thread.sleep(span); 

                } catch (InterruptedException e) { 

                    e.printStackTrace(); 

        public boolean isFlag() { 

            return flag; 

        public void setFlag(boolean flag) { 

            this.flag = flag; 

</span> 

3、相關實體類

撲克牌類:

<span style="font-size:18px;color:#3333ff;">package com.bison.utils; 

import java.util.Random; 

 * 生成一副洗好的牌,并且 設計為單例模式

public class Cards { 

    // 聲明一副撲克牌 

    public int[] pukes = new int[54]; 

    private static Cards cardsInstance = null; 

    private Cards() { 

        setPuke(); 

        shuffle(); 

    public static Cards getInstance() { 

        if (cardsInstance == null) { 

            cardsInstance = new Cards(); 

        return cardsInstance; 

    /** 給54張撲克牌指派 :1~54 */ 

    private void setPuke() { 

        for (int i = 0; i < 54; i++) { 

            pukes[i] = i + 1; 

    /** 洗牌 */ 

    private void shuffle() { 

        Random rdm = new Random(); 

            // random.nextInt();是個前閉後開的方法:0~53 

            int rdmNo = rdm.nextInt(54); 

            int temp = pukes[i]; 

            pukes[i] = pukes[rdmNo]; 

            pukes[rdmNo] = temp; 

玩家類:

 * 這個是玩家的實體類

public class Person { 

    private final Cards mCards = Cards.getInstance(); 

    public int[] person1 = new int[17]; 

    public int[] person2 = new int[17]; 

    public int[] person3 = new int[17]; 

    // 餘下三張屬于地主的 

    public int[] threePukes = new int[3]; 

    public Person() { 

        personHold(mCards.pukes); 

    /** 分牌 */ 

    private void personHold(int[] pukes) { 

        int k = 0; 

            if (i == 0) { 

                for (int j = 0; j < 17; j++) { 

                    person1[j] = pukes[k++]; 

                // 将其排序 

                sort(person1); 

            if (i == 1) { 

                    person2[j] = pukes[k++]; 

                sort(person2); 

            if (i == 2) { 

                    person3[j] = pukes[k++]; 

                sort(person3); 

        threePukes[0] = pukes[51]; 

        threePukes[1] = pukes[52]; 

        threePukes[2] = pukes[53]; 

    /** 對每個玩家手裡的牌排序:使用冒泡排序 */ 

    private void sort(int[] ary) { 

        for (int i = 0; i < ary.length; i++) { 

            for (int j = 0; j < ary.length - i - 1; j++) { 

                if (ary[j] > ary[j + 1]) { 

                    int temp = ary[j]; 

                    ary[j] = ary[j + 1]; 

                    ary[j + 1] = temp; 

    /**

     * 對應撲克所在圖檔上的位置 

     * 1 5 9 ………… 53 

     * 2 6 10 ………… 54 

     * 3 7 11 

     * 4 8 12

     */ 

    public Rect cardRect(int cardValue, int width, int height) { 

        int x = 0, y = 0; 

        if (cardValue % 4 == 0) { 

            x = cardValue / 4 - 1; 

            y = 4; 

        } else { 

            x = cardValue / 4; 

            y = cardValue % 4; 

        int left = x * width; 

        int top = (y - 1) * height; 

        int right = (x + 1) * width; 

        int bottom = (y) * height; 

        return new Rect(left, top, right, bottom); 

PS:鬥地主還是可以做成很複雜的。相關圖檔

繼續閱讀