发一个Android斗地主游戏的牌桌实现。

为了节约内存资源,每张扑克牌都是剪切形成的,当然这也是当前编程的主流方法。

1、主Activity


1. package com.bison;  
2.  
3. import android.app.Activity;  
4. import android.content.pm.ActivityInfo;  
5. import android.os.Bundle;  
6. import android.view.Window;  
7. import android.view.WindowManager;  
8.  
9.  
10. public class PukeActivity extends Activity {  
11.      
12.    @Override  
13.    public void onCreate(Bundle savedInstanceState) {  
14.        super.onCreate(savedInstanceState);  
15.        // 这个事隐藏标题栏,不解释   
16.        requestWindowFeature(Window.FEATURE_NO_TITLE);  
17.        // 隐藏状态栏,你懂的   
18.        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  
19.                WindowManager.LayoutParams.FLAG_FULLSCREEN);  
20.          
21.  
22.        // 使用代码锁定横屏   
23.        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);  
24.        // setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);这个是竖屏   
25.        setContentView(new GameView(this));  
26.    }  
27. }

2、牌桌页面


1. package com.bison;  
2.  
3. import android.content.Context;  
4. import android.graphics.Bitmap;  
5. import android.graphics.BitmapFactory;  
6. import android.graphics.Canvas;  
7. import android.graphics.Rect;  
8. import android.view.MotionEvent;  
9. import android.view.SurfaceHolder;  
10. import android.view.SurfaceView;  
11.  
12. import com.bison.utils.Person;  
13.  
14.  
15. public class GameView extends SurfaceView implements SurfaceHolder.Callback {  
16.    private FlushThread thread = null;// 刷帧线程   
17.    private Bitmap sourceBitmap = null;// 扑克图片来源   
18.    private Bitmap backgroundDesk = null;// 牌桌背景   
19.    private Bitmap backgroundPuke = null;// 扑克背面   
20.  
21.    private final Person person;  
22.    private int pukeWidth = 0;// 扑克的宽   
23.    private int pukeHeight = 0;// 扑克的高   
24.    private int deskWidth = 0;// 牌桌的宽   
25.    private int deskHeight = 0;// 牌桌的高   
26.    private int left = 0;// 我自己首张牌左距离   
27.  
28.    public GameView(Context context) {  
29.        super(context);  
30.        getHolder().addCallback(this);  
31.        this.thread = new FlushThread(getHolder(), this);// 实例化线程   
32.        initBitmap();// 实例化图片   
33.        this.person = new Person();// 实例化Person类   
34.        this.left = deskWidth / 2 - (16 * 25 + pukeWidth) / 2;// 左距开始时赋值   
35.    }  
36.  
37.    private void initBitmap() {// 初始化图片   
38.        sourceBitmap = BitmapFactory.decodeResource(getResources(),  
39.                R.drawable.smallcard);  
40.        pukeWidth = sourceBitmap.getWidth() / 14;// 每张扑克的宽高   
41.        pukeHeight = sourceBitmap.getHeight() / 4;  
42.  
43.        backgroundDesk = BitmapFactory.decodeResource(getResources(),  
44.                R.drawable.gameback2);  
45.  
46.        deskWidth = backgroundDesk.getWidth();// 牌桌的宽高   
47.        deskHeight = backgroundDesk.getHeight();  
48.  
49.        backgroundPuke = BitmapFactory.decodeResource(getResources(),  
50.                R.drawable.cardback);  
51.    }  
52.  
53.    @Override  
54.    protected void onDraw(Canvas canvas) {  
55.        // 绘制牌桌   
56.        canvas.drawBitmap(backgroundDesk, 0, 0, null);  
57.        personPaint(canvas, pukeWidth, pukeHeight);  
58.        deskthreePukes(canvas, pukeWidth, pukeHeight);  
59.    }  
60.  
61.      
62.    public void personPaint(Canvas c, int pukeWidth, int pukeHeight) {  
63.        Rect src = new Rect();  
64.        Rect dst = new Rect();  
65.  
66.        // 遍历数组   
67.        for (int i = 0; i < 3; i++) {  
68.            for (int j = 0; j < 17; j++) {  
69.                if (i == 0) {// 左手边玩家,不用绘出正面   
70.                    // src = person.cardRect(person.person1[j], pukeWidth,   
71.                    // pukeHeight);   
72.                    // dst.set(10, j * 20, 10 + pukeWidth, j * 20 + pukeHeight);   
73.                    c.drawBitmap(backgroundPuke, 35, 85, null);  
74.                }  
75.                if (i == 1) {// 自己   
76.                    src = person.cardRect(person.person2[j], pukeWidth,  
77.                            pukeHeight);  
78.                    dst.set(left + j * 25, this.deskHeight - 20 - pukeHeight,  
79.                            left + j * 25 + pukeWidth, deskHeight - 20);  
80.                    c.drawBitmap(sourceBitmap, src, dst, null);  
81.                }  
82.                if (i == 2) {// 右手边玩家,同样不用绘出正面   
83.                    // src = person.cardRect(person.person3[j], pukeWidth,   
84.                    // pukeHeight);   
85.                    // dst.set(this.screenWidth - 10 - pukeWidth, j * 20,   
86.                    // this.screenWidth - 10, j * 20 + pukeHeight);   
87.                    c.drawBitmap(backgroundPuke, deskWidth - 35 - pukeWidth,  
88.                            85, null);  
89.                }  
90.            }  
91.        }  
92.    }  
93.  
94.      
95.    private void deskthreePukes(Canvas c, int pukeWidth, int pukeHeight) {  
96.        Rect src = new Rect();  
97.        Rect dst = new Rect();  
98.        for (int i = 0; i < 3; i++) {  
99.            src = person.cardRect(person.threePukes[i], pukeWidth, pukeHeight);  
100.            dst.set(280 + i * pukeWidth, 12, 280 + (i + 1) * pukeWidth,  
101.                    12 + pukeHeight);  
102.            c.drawBitmap(sourceBitmap, src, dst, null);  
103.        }  
104.    }  
105.  
106.    @Override  
107.    public boolean onTouchEvent(MotionEvent event) {  
108.        // 正在研究点击弹出相应的扑克   
109.        return super.onTouchEvent(event);  
110.    }  
111.  
112.    @Override  
113.    public void surfaceChanged(SurfaceHolder holder, int format, int width,  
114.            int height) {  
115.    }  
116.  
117.    @Override  
118.    public void surfaceCreated(SurfaceHolder holder) {  
119.        this.thread.setFlag(true);  
120.        this.thread.start();  
121.    }  
122.  
123.    @Override  
124.    public void surfaceDestroyed(SurfaceHolder holder) {  
125.        boolean retry = true;  
126.        this.thread.setFlag(false);  
127.        while (retry) {  
128.            try {  
129.                thread.join();  
130.                retry = false;  
131.            } catch (InterruptedException e) {  
132.                e.printStackTrace();  
133.            }  
134.        }  
135.  
136.    }  
137.  
138.    // 刷帧线程,这个不解释
139.    class FlushThread extends Thread {  
140.        private boolean flag = false;  
141.        private final int span = 500;  
142.        private final GameView gameView;  
143.        private final SurfaceHolder holder;  
144.  
145.        public FlushThread(SurfaceHolder holder, GameView gameView) {  
146.            this.gameView = gameView;  
147.            this.holder = holder;  
148.        }  
149.  
150.        @Override  
151.        public void run() {  
152.            Canvas canvas;  
153.            while (this.flag) {  
154.                canvas = null;  
155.                try {  
156.                    canvas = this.holder.lockCanvas(null);  
157.                    synchronized (this.holder) {  
158.                        this.gameView.onDraw(canvas);  
159.                    }  
160.                } finally {  
161.                    if (canvas != null) {  
162.                        this.holder.unlockCanvasAndPost(canvas);  
163.                    }  
164.                }  
165.  
166.                try {  
167.                    Thread.sleep(span);  
168.                } catch (InterruptedException e) {  
169.                    e.printStackTrace();  
170.                }  
171.            }  
172.        }  
173.  
174.        public boolean isFlag() {  
175.            return flag;  
176.        }  
177.  
178.        public void setFlag(boolean flag) {  
179.            this.flag = flag;  
180.        }  
181.  
182.    }  
183.  
184. }
1. package com.bison;  
2.  
3. import android.content.Context;  
4. import android.graphics.Bitmap;  
5. import android.graphics.BitmapFactory;  
6. import android.graphics.Canvas;  
7. import android.graphics.Rect;  
8. import android.view.MotionEvent;  
9. import android.view.SurfaceHolder;  
10. import android.view.SurfaceView;  
11.  
12. import com.bison.utils.Person;  
13.  
14.  
15. public class GameView extends SurfaceView implements SurfaceHolder.Callback {  
16.    private FlushThread thread = null;// 刷帧线程   
17.    private Bitmap sourceBitmap = null;// 扑克图片来源   
18.    private Bitmap backgroundDesk = null;// 牌桌背景   
19.    private Bitmap backgroundPuke = null;// 扑克背面   
20.  
21.    private final Person person;  
22.    private int pukeWidth = 0;// 扑克的宽   
23.    private int pukeHeight = 0;// 扑克的高   
24.    private int deskWidth = 0;// 牌桌的宽   
25.    private int deskHeight = 0;// 牌桌的高   
26.    private int left = 0;// 我自己首张牌左距离   
27.  
28.    public GameView(Context context) {  
29.        super(context);  
30.        getHolder().addCallback(this);  
31.        this.thread = new FlushThread(getHolder(), this);// 实例化线程   
32.        initBitmap();// 实例化图片   
33.        this.person = new Person();// 实例化Person类   
34.        this.left = deskWidth / 2 - (16 * 25 + pukeWidth) / 2;// 左距开始时赋值   
35.    }  
36.  
37.    private void initBitmap() {// 初始化图片   
38.        sourceBitmap = BitmapFactory.decodeResource(getResources(),  
39.                R.drawable.smallcard);  
40.        pukeWidth = sourceBitmap.getWidth() / 14;// 每张扑克的宽高   
41.        pukeHeight = sourceBitmap.getHeight() / 4;  
42.  
43.        backgroundDesk = BitmapFactory.decodeResource(getResources(),  
44.                R.drawable.gameback2);  
45.  
46.        deskWidth = backgroundDesk.getWidth();// 牌桌的宽高   
47.        deskHeight = backgroundDesk.getHeight();  
48.  
49.        backgroundPuke = BitmapFactory.decodeResource(getResources(),  
50.                R.drawable.cardback);  
51.    }  
52.  
53.    @Override  
54.    protected void onDraw(Canvas canvas) {  
55.        // 绘制牌桌   
56.        canvas.drawBitmap(backgroundDesk, 0, 0, null);  
57.        personPaint(canvas, pukeWidth, pukeHeight);  
58.        deskthreePukes(canvas, pukeWidth, pukeHeight);  
59.    }  
60.  
61.      
62.    public void personPaint(Canvas c, int pukeWidth, int pukeHeight) {  
63.        Rect src = new Rect();  
64.        Rect dst = new Rect();  
65.  
66.        // 遍历数组   
67.        for (int i = 0; i < 3; i++) {  
68.            for (int j = 0; j < 17; j++) {  
69.                if (i == 0) {// 左手边玩家,不用绘出正面   
70.                    // src = person.cardRect(person.person1[j], pukeWidth,   
71.                    // pukeHeight);   
72.                    // dst.set(10, j * 20, 10 + pukeWidth, j * 20 + pukeHeight);   
73.                    c.drawBitmap(backgroundPuke, 35, 85, null);  
74.                }  
75.                if (i == 1) {// 自己   
76.                    src = person.cardRect(person.person2[j], pukeWidth,  
77.                            pukeHeight);  
78.                    dst.set(left + j * 25, this.deskHeight - 20 - pukeHeight,  
79.                            left + j * 25 + pukeWidth, deskHeight - 20);  
80.                    c.drawBitmap(sourceBitmap, src, dst, null);  
81.                }  
82.                if (i == 2) {// 右手边玩家,同样不用绘出正面   
83.                    // src = person.cardRect(person.person3[j], pukeWidth,   
84.                    // pukeHeight);   
85.                    // dst.set(this.screenWidth - 10 - pukeWidth, j * 20,   
86.                    // this.screenWidth - 10, j * 20 + pukeHeight);   
87.                    c.drawBitmap(backgroundPuke, deskWidth - 35 - pukeWidth,  
88.                            85, null);  
89.                }  
90.            }  
91.        }  
92.    }  
93.  
94.      
95.    private void deskthreePukes(Canvas c, int pukeWidth, int pukeHeight) {  
96.        Rect src = new Rect();  
97.        Rect dst = new Rect();  
98.        for (int i = 0; i < 3; i++) {  
99.            src = person.cardRect(person.threePukes[i], pukeWidth, pukeHeight);  
100.            dst.set(280 + i * pukeWidth, 12, 280 + (i + 1) * pukeWidth,  
101.                    12 + pukeHeight);  
102.            c.drawBitmap(sourceBitmap, src, dst, null);  
103.        }  
104.    }  
105.  
106.    @Override  
107.    public boolean onTouchEvent(MotionEvent event) {  
108.        // 正在研究点击弹出相应的扑克   
109.        return super.onTouchEvent(event);  
110.    }  
111.  
112.    @Override  
113.    public void surfaceChanged(SurfaceHolder holder, int format, int width,  
114.            int height) {  
115.    }  
116.  
117.    @Override  
118.    public void surfaceCreated(SurfaceHolder holder) {  
119.        this.thread.setFlag(true);  
120.        this.thread.start();  
121.    }  
122.  
123.    @Override  
124.    public void surfaceDestroyed(SurfaceHolder holder) {  
125.        boolean retry = true;  
126.        this.thread.setFlag(false);  
127.        while (retry) {  
128.            try {  
129.                thread.join();  
130.                retry = false;  
131.            } catch (InterruptedException e) {  
132.                e.printStackTrace();  
133.            }  
134.        }  
135.  
136.    }  
137.  
138.    // 刷帧线程,这个不解释
139.    class FlushThread extends Thread {  
140.        private boolean flag = false;  
141.        private final int span = 500;  
142.        private final GameView gameView;  
143.        private final SurfaceHolder holder;  
144.  
145.        public FlushThread(SurfaceHolder holder, GameView gameView) {  
146.            this.gameView = gameView;  
147.            this.holder = holder;  
148.        }  
149.  
150.        @Override  
151.        public void run() {  
152.            Canvas canvas;  
153.            while (this.flag) {  
154.                canvas = null;  
155.                try {  
156.                    canvas = this.holder.lockCanvas(null);  
157.                    synchronized (this.holder) {  
158.                        this.gameView.onDraw(canvas);  
159.                    }  
160.                } finally {  
161.                    if (canvas != null) {  
162.                        this.holder.unlockCanvasAndPost(canvas);  
163.                    }  
164.                }  
165.  
166.                try {  
167.                    Thread.sleep(span);  
168.                } catch (InterruptedException e) {  
169.                    e.printStackTrace();  
170.                }  
171.            }  
172.        }  
173.  
174.        public boolean isFlag() {  
175.            return flag;  
176.        }  
177.  
178.        public void setFlag(boolean flag) {  
179.            this.flag = flag;  
180.        }  
181.  
182.    }  
183.  
184. }

3、相关实体类

扑克牌类:

1. package com.bison.utils;  
2.  
3. import java.util.Random;  
4.  
5.  
6. public class Cards {  
7.    // 声明一副扑克牌   
8.    public int[] pukes = new int[54];  
9.  
10.    private static Cards cardsInstance = null;  
11.  
12.    private Cards() {  
13.        setPuke();  
14.        shuffle();  
15.    }  
16.  
17.    public static Cards getInstance() {  
18.        if (cardsInstance == null) {  
19.            cardsInstance = new Cards();  
20.        }  
21.        return cardsInstance;  
22.    }  
23.  
24.      
25.    private void setPuke() {  
26.        for (int i = 0; i < 54; i++) {  
27.            pukes[i] = i + 1;  
28.        }  
29.    }  
30.  
31.      
32.    private void shuffle() {  
33.        Random rdm = new Random();  
34.        for (int i = 0; i < 54; i++) {  
35.            // random.nextInt();是个前闭后开的方法:0~53   
36.            int rdmNo = rdm.nextInt(54);  
37.            int temp = pukes[i];  
38.            pukes[i] = pukes[rdmNo];  
39.            pukes[rdmNo] = temp;  
40.        }  
41.    }  
42. }

玩家类:

1. package com.bison.utils;  
2.  
3. import android.graphics.Rect;  
4.  
5.  
6. public class Person {  
7.    private final Cards mCards = Cards.getInstance();  
8.  
9.    public int[] person1 = new int[17];  
10.    public int[] person2 = new int[17];  
11.    public int[] person3 = new int[17];  
12.  
13.    // 余下三张属于地主的   
14.    public int[] threePukes = new int[3];  
15.  
16.    public Person() {  
17.        personHold(mCards.pukes);  
18.    }  
19.  
20.      
21.    private void personHold(int[] pukes) {  
22.        int k = 0;  
23.        for (int i = 0; i < 3; i++) {  
24.            if (i == 0) {  
25.                for (int j = 0; j < 17; j++) {  
26.                    person1[j] = pukes[k++];  
27.                }  
28.                // 将其排序   
29.                sort(person1);  
30.            }  
31.            if (i == 1) {  
32.                for (int j = 0; j < 17; j++) {  
33.                    person2[j] = pukes[k++];  
34.                }  
35.                // 将其排序   
36.                sort(person2);  
37.            }  
38.            if (i == 2) {  
39.                for (int j = 0; j < 17; j++) {  
40.                    person3[j] = pukes[k++];  
41.                }  
42.                // 将其排序   
43.                sort(person3);  
44.            }  
45.        }  
46.  
47.        threePukes[0] = pukes[51];  
48.        threePukes[1] = pukes[52];  
49.        threePukes[2] = pukes[53];  
50.    }  
51.  
52.      
53.    private void sort(int[] ary) {  
54.        for (int i = 0; i < ary.length; i++) {  
55.            for (int j = 0; j < ary.length - i - 1; j++) {  
56.                if (ary[j] > ary[j + 1]) {  
57.                    int temp = ary[j];  
58.                    ary[j] = ary[j + 1];  
59.                    ary[j + 1] = temp;  
60.                }  
61.            }  
62.        }  
63.    }  
64.  
65.      
66.    public Rect cardRect(int cardValue, int width, int height) {  
67.        int x = 0, y = 0;  
68.        if (cardValue % 4 == 0) {  
69.            x = cardValue / 4 - 1;  
70.            y = 4;  
71.        } else {  
72.            x = cardValue / 4;  
73.            y = cardValue % 4;  
74.        }  
75.  
76.        int left = x * width;  
77.        int top = (y - 1) * height;  
78.        int right = (x + 1) * width;  
79.        int bottom = (y) * height;  
80.        return new Rect(left, top, right, bottom);  
81.    }  
82. }

PS:斗地主还是可以做成很复杂的。相关图片

Android开发教程:斗地主 [牌桌实…_i++