文档章节

Android --- 斗地主 [牌桌实现源码]

晨曦之光
 晨曦之光
发布于 2012/03/21 18:33
字数 1303
阅读 7773
收藏 22

最近一直在研究关于游戏编程,人在深圳,工作不好找啊!

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

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

 

 1、主Activity

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));
	}
}

2、牌桌页面

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;

/**
 * 牌桌,会被老婆骂,最好不要上去,你懂的
 * 
 * 扑克图片来源,和牌桌背景在文章的下面。 扑克背面图等我没上传,玩家自行百度
 * 
 * @author Bison
 * 
 */
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);
	}

	@Override
	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,
					// pukeHeight);
					// 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) {
		Rect src = new Rect();
		Rect dst = new Rect();
		for (int i = 0; i < 3; i++) {
			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);
		}
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// 正在研究点击弹出相应的扑克
		return super.onTouchEvent(event);
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		this.thread.setFlag(true);
		this.thread.start();
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		boolean retry = true;
		this.thread.setFlag(false);
		while (retry) {
			try {
				thread.join();
				retry = false;
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

	}

	// 刷帧线程,这个不解释,实在看不懂,M我:289302487@qq.com
	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);
					}
				}

				try {
					Thread.sleep(span);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}

		public boolean isFlag() {
			return flag;
		}

		public void setFlag(boolean flag) {
			this.flag = flag;
		}

	}

}


 

3、相关实体类

扑克牌类:

package com.bison.utils;

import java.util.Random;

/**
 * 生成一副洗好的牌,并且 设计为单例模式
 * 
 * @author Bison
 * 
 */
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();
		for (int i = 0; i < 54; i++) {
			// random.nextInt();是个前闭后开的方法:0~53
			int rdmNo = rdm.nextInt(54);
			int temp = pukes[i];
			pukes[i] = pukes[rdmNo];
			pukes[rdmNo] = temp;
		}
	}
}

 

玩家类:

package com.bison.utils;

import android.graphics.Rect;

/**
 * 这个是玩家的实体类
 * 
 * @author Bison
 * 
 */
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;
		for (int i = 0; i < 3; i++) {
			if (i == 0) {
				for (int j = 0; j < 17; j++) {
					person1[j] = pukes[k++];
				}
				// 将其排序
				sort(person1);
			}
			if (i == 1) {
				for (int j = 0; j < 17; j++) {
					person2[j] = pukes[k++];
				}
				// 将其排序
				sort(person2);
			}
			if (i == 2) {
				for (int j = 0; j < 17; j++) {
					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:斗地主还是可以做成很复杂的。相关图片



原文链接: http://blog.csdn.net/bys0201/article/details/7378271

本文转载自:http://blog.csdn.net/bys0201/article/details/7378271

共有 人打赏支持
晨曦之光
粉丝 394
博文 4426
码字总数 2559
作品 0
深圳
程序员
私信 提问
加载中

评论(4)

开源中国部长_柯标
开源中国部长_柯标
https://github.com/kbengine/kbengine_unity3d_warring
s
soholee
要學習要學習~
E
EMPERY
寻找程序牛人
我有一款游戏的雏形设计,我可以解决创意、美术和设计的问题,现在急需技术过硬的游戏编程。
寻找游戏程序牛人。如果你对编写程序极度热爱,如果你对游戏也有兴趣,如果你也不甘于平淡的生活,那么请你联系我!!!如果你身边有这样的人,那么请把我的联系方式给他,我在这里先谢谢大家了。
我把这次项目看成是微创业,如果我们制作、运作的好,我有信心把我们这次微创业变成创业,并一直走下去。
我是中央美术学院动画系的安鹏宇,期待你的加入!
联系电话:13717528806
QQ:459118257
kipeng
kipeng
蛮不错的
Android源码50例汇总,欢迎各位下载

下载中心好资料很多,藏在各个角落,小弟在此帮大家做了一个整理,做了一个下载目录,方便大家选择性下载。 源码实例如下: 《Android应用开发揭秘》源代码推荐 http://down.51cto.com/data...

程序袁_绪龙
2015/01/23
0
0
怎样在android中实现手机斗地主的音频效果?

怎样在android中实现手机斗地主的音频效果?

程彦峰
2012/03/28
680
0
求android应用平台开发思路

公司开发了几个android版的手机应用,都是独立成一个一个项目的,现在老总有这样的需求,把公司开发的这些android版项目统一放在一个平台上,用户只要安装平台,就可以看到所有的android项目...

嘀咕
2012/10/08
390
3
基于cocos2d的移动端游戏(android版本)开发

【业务需求】 一、功能需求 1、基于cocos2d引擎的移动端游戏开发(android版本) 2、项目界面交互参考QQ斗地主这种休闲游戏风格 3、服务端开发已完成,只需联调 4、游戏逻辑及规则由我们这边自...

hansen5490
2016/01/19
26
5
android的斗地主游戏扑克控件

在android的斗地主游戏中,我想把每张扑克写成一个控件,应该继承哪个控件呢?是还是等等控件呢,要能够设置扑克的大小和位置,可是我不知道怎么实现?请求大家帮忙想想办法,谢谢!

张士伟
2012/07/13
153
0

没有更多内容

加载失败,请刷新页面

加载更多

Java基础:String、StringBuffer和StringBuilder的区别

1 String String:字符串常量,字符串长度不可变。Java中String是immutable(不可变)的。 String类的包含如下定义: /** The value is used for character storage. */private final cha...

watermelon11
29分钟前
2
0
mogodb服务

部署MongoDB 官网: https://www.mongodb.com/download-center/community 创建mongo数据目录 mkdir /data/mongodb 二进制部署 wget -c https://fastdl.mongodb.org/linux/mongodb-linux-x8......

以谁为师
昨天
5
0
大神教你Debian GNU/Linux 9.7 “Stretch” Live和安装镜像开放下载

Debian项目团队于昨天发布了Debian GNU/Linux 9 "Stretch" 的第7个维护版本更新,重点修复了APT软件管理器中存在的安全漏洞。在敦促每位用户尽快升级系统的同时,Debian团队还发布了Debian ...

linux-tao
昨天
4
0
PHP 相关配置

1. php-fpm的pool 编辑php-fpm配置文件php-fpm.con vim /usr/local/php/etc/php-fpm.conf //在[global]部分增加以下内容 include = etc/php-fpm.d/*.conf # 相当与Nginx的虚拟主机文件 “vho......

Yue_Chen
昨天
2
0
EOS主网数据同步指南

本文介绍如何安装EOS节点软件并接入EOS主网,主要包括以下内容: 如何安装EOS节点软件 如何配置EOS节点软件接入主网 如何启动EOS节点软件与主网数据同步 如何检查主网数据同步进度 如何正确地...

汇智网教程
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部