发一个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:斗地主还是可以做成很复杂的。相关图片