斗地主游戏项目文档
本文档介绍斗地主游戏的设计要求、数据模型、简单测试、视图设计、GUI程序、程序发布等方面的内容,以提供一个全面而清晰的说明。以下是各个部分的详细介绍。
设计要求
斗地主游戏的设计要求如下:
1:实现一个登录注册界面,包括点击生成随机验证码 验证账密等功能
添加更改密码 查看已注册用户功能
2. 实现一个经典的斗地主游戏,包括发牌、抢地主、出牌、倒计时等功能。
3. 支持单人参与游戏,玩家进行操作与两位人机对战。
数据模型
在斗地主游戏中,需要设计以下数据模型:
一: 玩家:包括玩家的姓名、手牌等信息。
二:牌:包括牌的4种花色、大小王与13种序号等信息,进行权重排序。通过牌型比较判断玩家是否能出牌。
三:地主:表示当前的地主玩家,获得初始的3张手牌,率先出牌。
Common类主要包括对扑克牌进行排序、判断牌型、移动牌等功能;
1. 判断牌型:根据输入的扑克牌列表,判断其牌型,如单牌、对子、三张牌等,并返回对应的牌型。
2. 移动牌:提供了移动扑克牌的方法,可以实现带有动画效果的扑克牌移动,牌点击后向上移动20像素,再次点击向下移动20像素
3. 排序:利用扑克牌的牌面大小和花色进行排序,将输入的扑克牌列表按照一定规则进行排序。
4. 重新摆放牌的顺序:根据游戏界面和需要摆放的集合,将扑克牌重新摆放到指定的位置。
登录界面类
在LoginJFrame类中,首先定义了一些成员变量,比如按钮、文本框等,以及一个保存用户信息的列表(userDatabase)。
注册新用户后会创建User类的一个新对象,用户对象实际存储在Userdatabase的List表中
构造方法LoginJFrame(),用于初始化界面、添加组件,并将界面显示出来。
public LoginJFrame(){
//初始化界面
initJFrame();
//初始化组件,在页面中添加内容
initView();
//让当前界面显示出来
this.setVisible(true);
}
initJFrame() 设置窗体的大小、标题
public void initJFrame(){
//设置宽高 标题 关闭后停止运行 居中 置顶 取消默认布局
this.setSize(640,420);
this.setTitle("斗地主游戏登录 Version:1.0.0 ");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setAlwaysOnTop(true);
this.setLayout(null);
}
initView() 添加各种组件,比如标签、输入框、按钮
注意创建完标签,账号密码输入框,验证码,4个按钮后添加组件到面板中,由于本类已经继承了JFrame类,直接用this.getContentPane().add(组件),将组件添加到当前面板
GameJFrame类是一个基于 Java 编写的斗地主游戏的界面部分。它使用了 Swing 库来创建游戏窗口,并包含了玩家操作的按钮、玩家手牌的展示以及倒计时等功能。
在 `GameJFrame` 类中,首先定义了游戏界面的一些基本属性和组件,然后在构造函数中进行了界面的初始化工作。其中通过多线程的方式进行了牌的初始化(备牌、洗牌、发牌),以及播放游戏音乐的操作,避免阻塞主线程。界面初始化完成后,展示了抢地主和不抢地主两个按钮,以及倒计时文本等。
通过 `initView()` 方法,添加了抢地主和不抢地主两个按钮,以及出牌和不要的按钮,同时创建了玩家前的提示文字倒计时显示。
通用功能类
Common是一个扑克牌游戏中的通用功能类,其中包括了对扑克牌进行排序、判断牌型、移动牌等功能。
首先是jugdeType
方法,用于判断牌型,包括单张、对子、三不带、炸弹、顺子、连对、飞机、四带二等类型。
然后是move
方法,实现了移动牌的动画效果。
接着是order
方法,利用牌的价值对集合中的牌进行排序。
rePosition
方法用于重新摆放牌的顺序,包括左、中、右三个位置。
验证码类 CodeUtil.getCode()会返回一个 4个英文字符与一个数字字符 拼接成的字符串
位置随机
创建一个ArrayList对象 可以动态改变大小的数组
根据ascii码即字节码中 a – z 与 A – Z的关系
向list表中依次添加大小写共52个字母 例如:aA - zZ
利用Random类 对象的nextInt()方法 向其传入list表长 生成一个随机字母在表中的索引
表.get(索引) 获取索引对应字母
写在for循环中,遍历4次拼接字符串
利用Random类 对象的nextInt()方法 向其传入10 范围即为0-9
1个随机数字暂时拼接在4个随机字母后面
将字符串 转换 为字符数组
定义一个索引 利用Random类 对象的nextInt()方法 向其传入 字符数组长度
空水杯交换 空水杯 = 数字字符;数字字符 = 随机索引对应英文字符;英文字符 = 空水杯
public static String getCode(){
//创建一个集合;
ArrayList<Character> list = new ArrayList<>(); //52 索引范围0-51
//添加字母 a - z A - Z
for(int i=0;i<26;i++){
list.add((char)('a' + i));//类型转换为字符97-a 65-A
list.add((char)('A' + i));
}
//打印集合
//System.out.println(list);
//生成4个随机字母
String result = "";
Random r = new Random();
for(int i=0;i<4;i++){
int randomIndex = r.nextInt(list.size());
result = result + list.get(randomIndex);
}
//长度为4的随机字符串 return result;
//基础上拼接数字0-9
int number = r.nextInt(10);
//把随机数字拼接到result后面
result = result + number;
//把字符串变成字符数组
char[] chars = result.toCharArray();
//生成一个字符数组长度的随机索引
int index = r.nextInt(chars.length);
//末索引4上的数字字符与随机索引上的字符交换 使数字出现在索引0-4的任何位置
char temp = chars[4];
chars[4] = chars[index];
chars[index] = temp;
//字符数组变回字符串
String code = new String(chars);
return code;
}
出牌类型类
枚举类型enum表示一组相关的常量
方便判断出牌是否为同一类型
简单测试
在开发过程中,可以进行简单的测试来验证代码的正确性和可靠性。例如,可以模拟发牌、抢地主、出牌等操作,并检查结果是否符合预期。
测试过程发现音频无法播放,搜索错误得知不支持applet工具类,wav,m4p等音乐格式也不支持。于是导入javazoom下的Player类,构造方法抛出异常与文件无法找到的错误,为使音乐在不同路径下都能播放,采取项目路径与相对路径拼接为字符串,再将字符串传入文件输入流,并预先用缓冲流加载,while(true)死循环使音频不断播放。
又由于音频是在登录成功后跳转的游戏界面播放,因此在游戏界面类构造函数处调用播放音频方法,为避免音乐播放阻塞主程序,将音频播放构造方法添加到异步加载中,
打包后cmd java -jar 包名或直接双击运行jar包,发现游戏界面的扑克与地主图片图片消失,原来是由于默认从src文件夹下找图片,img文件夹不在src里,可以在打包之后把图片文件夹img粘贴至jar包路径处,成功显示图片
打包后音频也无法播放,还是路径原因,原先拼接成的绝对路径改为相对路径,jar包位置创建文件夹src再放置音乐文件夹。
总结,都是取决于原先的图片或音频的路径
视图设计
为了提供友好的用户界面,需要进行视图设计。可以使用图形用户界面(GUI)来展示游戏进程和玩家操作。例如,可以设计游戏桌面、玩家手牌区域、出牌区域等。视图设计应符合用户习惯,界面简洁明了,方便玩家操作。
GUI程序
基于视图设计,可以开发一个GUI程序来实现斗地主游戏。GUI程序应当具备以下功能:
1. 显示游戏进程和玩家操作。
2. 提供按钮或其他交互元素,用于玩家进行抢地主、出牌等操作。
3. 实时更新游戏状态,包括当前玩家、地主玩家、出牌倒计时等信息。
4. 提供可视化的手牌区域和出牌区域,方便玩家查看和选择牌。
5.注册后可以更改密码 或者 查看已注册用户列表
程序发布
完成代码开发后,可以将程序进行发布,以供用户下载和使用。程序发布应包括以下步骤:
对代码进行编译和打jar包,生成可执行文件。
通过以上介绍,详细阐述了斗地主游戏代码的设计要求、数据模型、简单测试、视图设计、GUI程序、程序发布等方面的内容。希望这个文档能够对开发斗地主游戏的学习和游玩有所帮助
源码分为game main util music四个包
game包下新建类
Common类
import java.awt.*; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import lynu.rookie.main.Poker; public class Common { //四种花色:1"黑桃",2"红桃",3"梅花",4"方块" //序号5 大小王 //十三种序号:"3","4","5","6","7","8","9","10","J","Q","K","A"序号1,"2"序号2 //判断牌型 public static PokerType jugdeType(ArrayList<Poker> list) { int len = list.size(); if (len <= 4) { if (list.size() > 0 && Common.getValue(list.get(0)) == Common.getValue(list.get(len - 1))) { switch (len) { case 1: return PokerType.c1; case 2: return PokerType.c2; case 3: return PokerType.c3; case 4: return PokerType.c4; } } if (len == 2 && Common.getColor(list.get(1)) == 5) return PokerType.c2; if (len == 4 && ((Common.getValue(list.get(0)) == Common.getValue(list.get(len - 2))) || Common.getValue(list.get(1)) == Common.getValue(list.get(len - 1)))) return PokerType.c31; else { return PokerType.c0; } } if (len >= 5) { PokerIndex pokerIndex = new PokerIndex(); ArrayList<ArrayList<Integer>> indexList = pokerIndex.indexList; for (int i = 0; i < 4; i++) { indexList.add(new ArrayList<>()); } Common.getMax(pokerIndex, list); if (indexList.get(2).size() == 1 && indexList.get(1).size() == 1 && len == 5) return PokerType.c32; if (indexList.get(3).size() == 1 && len == 6) return PokerType.c411; if (indexList.get(3).size() == 1 && indexList.get(1).size() == 2 && len == 8) return PokerType.c422; if ((Common.getColor(list.get(0)) != 5) && (indexList.get(0).size() == len) && (Common.getValue(list.get(0)) - Common.getValue(list.get(len - 1)) == len - 1)) return PokerType.c123; if (indexList.get(1).size() == len / 2 && len % 2 == 0 && len / 2 >= 3 && (Common.getValue(list.get(0)) - Common.getValue(list.get(len - 1)) == (len / 2 - 1))) return PokerType.c112233; if (indexList.get(2).size() == len / 3 && (len % 3 == 0) && (Common.getValue(list.get(0)) - Common.getValue(list.get(len - 1)) == (len / 3 - 1))) return PokerType.c111222; if (indexList.get(2).size() == len / 4 && (indexList.get(2).get(len / 4 - 1) - (indexList.get(2).get(0)) == len / 4 - 1)) return PokerType.c11122234; if (indexList.get(2).size() == len / 5 && indexList.get(2).size() == len / 5 && ((indexList.get(2).get(len / 5 - 1)) - (indexList.get(2).get(0)) == len / 5 - 1)) return PokerType.c1112223344; } return PokerType.c0; } //移动牌(有移动的动画效果) 形参 当前移动牌 目标起始索引 结束索引 public static void move(Poker poker, Point from, Point to) { if (to.x != from.x) { double k = (1.0) * (to.y - from.y) / (to.x - from.x); double b = to.y - to.x * k; int flag = 0; if (from.x < to.x) flag = 20; else { flag = -20; } for (int i = from.x; Math.abs(i - to.x) > 20; i += flag) { double y = k * i + b; poker.setLocation(i, (int) y); try { Thread.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } } } poker.setLocation(to); } //利用牌的价值,将集合中的牌进行排序 public static void order(ArrayList<Poker> list) { //此时可以改为lambda表达式 Collections.sort(list, new Comparator<Poker>() { @Override public int compare(Poker o1, Poker o2) { //获取花色 //1-黑桃 2-红桃 3-梅花 4-方块 5-大小王 int a1 = Integer.parseInt(o1.getName().substring(0, 1)); int a2 = Integer.parseInt(o2.getName().substring(0, 1)); //获取牌上的数字,同时也是牌的价值 //1-A ... 11-J 12-Q 13-K int b1 = Integer.parseInt(o1.getName().substring(2)); int b2 = Integer.parseInt(o2.getName().substring(2)); //计算牌的价值,利用牌的价值进行排序 //牌上的数字在3~10之间,价值就是3~10 //3:价值3 //... //10:价值10 //J:价值11 //Q:价值12 //K:价值13 //A:1 + 20 = 21 //2:2 + 30 = 32 //小王:1 + 100 = 101 //大王:2 + 100 = 102 //计算大小王牌的价值 if (a1 == 5) { b1 += 100; } if (a2 == 5) { b2 += 100; } //计算A的价值 if (b1 == 1) { b1 += 20; } if (b2 == 1) { b2 += 20; } //计算2的价值 if (b1 == 2) { b1 += 30; } if (b2 == 2) { b2 += 30; } //倒序排列 int flag = b2 - b1; //如果牌的价值一样,则按照花色排序 if (flag == 0) { return a2 - a1; } else { return flag; } } }); } //重新摆放牌的顺序 游戏界面 要摆放的集合 标记0 1 2 左 中 右 public static void rePosition(GameJFrame m, ArrayList<Poker> list, int flag) { Point p = new Point(); if (flag == 0) { p.x = 50; p.y = (450 / 2) - (list.size() + 1) * 15 / 2; } if (flag == 1) { p.x = (800 / 2) - (list.size() + 1) * 21 / 2; p.y = 450; } if (flag == 2) { p.x = 700; p.y = (450 / 2) - (list.size() + 1) * 15 / 2; } int len = list.size(); for (int i = 0; i < len; i++) { Poker poker = list.get(i); Common.move(poker, poker.getLocation(), p); m.container.setComponentZOrder(poker, 0); if (flag == 1) p.x += 21; else p.y += 15; } } public static int getScore(ArrayList<Poker> list) { int count = 0; for (int i = 0, len = list.size(); i < len; i++) { Poker poker = list.get(i); if (poker.getName().substring(0, 1).equals("5")) { count += 5; } if (poker.getName().substring(2).equals("2")) { count += 2; } } return count; } public static int getColor(Poker poker) { return Integer.parseInt(poker.getName().substring(0, 1)); } public static int getValue(Poker poker) { int i = Integer.parseInt(poker.getName().substring(2)); if (poker.getName().substring(2).equals("2")) i += 13; if (poker.getName().substring(2).equals("1")) i += 13; if (Common.getColor(poker) == 5) i += 2; return i; } public static void getMax(PokerIndex pokerIndex, ArrayList<Poker> list) { int count[] = new int[14]; for (int i = 0; i < 14; i++) count[i] = 0; for (int i = 0, len = list.size(); i < len; i++) { if (Common.getColor(list.get(i)) == 5)// 王 count[13]++; else count[Common.getValue(list.get(i)) - 1]++; } ArrayList<ArrayList<Integer>> indexList = pokerIndex.indexList; for (int i = 0; i < 14; i++) { switch (count[i]) { case 1: indexList.get(0).add(i + 1); break; case 2: indexList.get(1).add(i + 1); break; case 3: indexList.get(2).add(i + 1); break; case 4: indexList.get(3).add(i + 1); break; } } } public static Model getModel(ArrayList<Poker> list, int[] orders) { ArrayList list2 = new ArrayList<>(list); Model model = new Model(); for (int i = 0; i < orders.length; i++) showOrders(orders[i], list2, model); return model; } public static void get123(ArrayList<Poker> list, Model model) { ArrayList<Poker> del = new ArrayList<>(); if (list.size() > 0 && (Common.getValue(list.get(0)) < 7 || Common.getValue(list.get(list.size() - 1)) > 10)) return; if (list.size() < 5) return; ArrayList<Poker> list2 = new ArrayList<>(); ArrayList<Poker> temp = new ArrayList<>(); ArrayList<Integer> integers = new ArrayList<>(); for (Poker poker : list2) { if (integers.indexOf(Common.getValue(poker)) < 0) { integers.add(Common.getValue(poker)); temp.add(poker); } } Common.order(temp); for (int i = 0, len = temp.size(); i < len; i++) { int k = i; for (int j = i; j < len; j++) { if (Common.getValue(temp.get(i)) - Common.getValue(temp.get(j)) == j - i) { k = j; } } if (k - i >= 4) { String s = ""; for (int j = i; j < k; j++) { s += temp.get(j).getName() + ","; del.add(temp.get(j)); } s += temp.get(k).getName(); del.add(temp.get(k)); model.a123.add(s); i = k; } } list.removeAll(del); } public static void getTwoTwo(ArrayList<Poker> list, Model model) { ArrayList<String> del = new ArrayList<>(); ArrayList<String> l = model.a2; if (l.size() < 3) return; Integer s[] = new Integer[l.size()]; for (int i = 0, len = l.size(); i < len; i++) { String[] name = l.get(i).split(","); s[i] = Integer.parseInt(name[0].substring(2, name[0].length())); } for (int i = 0, len = l.size(); i < len; i++) { int k = i; for (int j = i; j < len; j++) { if (s[i] - s[j] == j - i) k = j; } if (k - i >= 2) { String ss = ""; for (int j = i; j < k; j++) { ss += l.get(j) + ","; del.add(l.get(j)); } ss += l.get(k); model.a112233.add(ss); del.add(l.get(k)); i = k; } } l.removeAll(del); } public static void getPlane(ArrayList<Poker> list, Model model) { ArrayList<String> del = new ArrayList<>(); ArrayList<String> l = model.a3; if (l.size() < 2) return; Integer s[] = new Integer[l.size()]; for (int i = 0, len = l.size(); i < len; i++) { String[] name = l.get(i).split(","); s[i] = Integer.parseInt(name[0].substring(2, name[0].length())); } for (int i = 0, len = l.size(); i < len; i++) { int k = i; for (int j = i; j < len; j++) { if (s[i] - s[j] == j - i) k = j; } if (k != i) { String ss = ""; for (int j = i; j < k; j++) { ss += l.get(j) + ","; del.add(l.get(j)); } ss += l.get(k); model.a111222.add(ss); del.add(l.get(k)); i = k; } } l.removeAll(del); } public static void getBoomb(ArrayList<Poker> list, Model model) { ArrayList<Poker> del = new ArrayList<>(); if (list.size() < 1) return; if (list.size() >= 2 && Common.getColor(list.get(0)) == 5 && Common.getColor(list.get(1)) == 5) { model.a4.add(list.get(0).getName() + "," + list.get(1).getName()); del.add(list.get(0)); del.add(list.get(1)); } if (Common.getColor(list.get(0)) == 5 && Common.getColor(list.get(1)) != 5) { del.add(list.get(0)); model.a1.add(list.get(0).getName()); } list.removeAll(del); for (int i = 0, len = list.size(); i < len; i++) { if (i + 3 < len && Common.getValue(list.get(i)) == Common.getValue(list.get(i + 3))) { String s = list.get(i).getName() + ","; s += list.get(i + 1).getName() + ","; s += list.get(i + 2).getName() + ","; s += list.get(i + 3).getName(); model.a4.add(s); for (int j = i; j <= i + 3; j++) del.add(list.get(j)); i = i + 3; } } list.removeAll(del); } public static void getThree(ArrayList<Poker> list, Model model) { ArrayList<Poker> del = new ArrayList<>(); for (int i = 0, len = list.size(); i < len; i++) { if (i + 2 < len && Common.getValue(list.get(i)) == Common.getValue(list.get(i + 2))) { String s = list.get(i).getName() + ","; s += list.get(i + 1).getName() + ","; s += list.get(i + 2).getName(); model.a3.add(s); for (int j = i; j <= i + 2; j++) del.add(list.get(j)); i = i + 2; } } list.removeAll(del); } public static void getTwo(ArrayList<Poker> list, Model model) { ArrayList<Poker> del = new ArrayList<>(); for (int i = 0, len = list.size(); i < len; i++) { if (i + 1 < len && Common.getValue(list.get(i)) == Common.getValue(list.get(i + 1))) { String s = list.get(i).getName() + ","; s += list.get(i + 1).getName(); model.a2.add(s); for (int j = i; j <= i + 1; j++) del.add(list.get(j)); i = i + 1; } } list.removeAll(del); } public static void getSingle(ArrayList<Poker> list, Model model) { ArrayList<Poker> del = new ArrayList<>(); for (int i = 0, len = list.size(); i < len; i++) { model.a1.add(list.get(i).getName()); del.add(list.get(i)); } list.removeAll(del); } public static void hideCards(ArrayList<Poker> list) { for (int i = 0, len = list.size(); i < len; i++) { list.get(i).setVisible(false); } } public static int checkCards(ArrayList<Poker> c, ArrayList<ArrayList<Poker>> current, GameJFrame m) { ArrayList<Poker> currentlist; if (m.time[0].getText().equals("不要")) currentlist = current.get(2); else currentlist = current.get(0); PokerType cType = Common.jugdeType(c); PokerType cType2 = Common.jugdeType(currentlist); if (cType != PokerType.c4 && c.size() != currentlist.size()) return 0; if (cType != PokerType.c4 && Common.jugdeType(c) != Common.jugdeType(currentlist)) { return 0; } if (cType == PokerType.c4) { if (c.size() == 2) return 1; if (cType2 != PokerType.c4) { return 1; } } if (cType == PokerType.c1 || cType == PokerType.c2 || cType == PokerType.c3 || cType == PokerType.c4) { if (Common.getValue(c.get(0)) <= Common.getValue(currentlist.get(0))) { return 0; } else { return 1; } } if (cType == PokerType.c123 || cType == PokerType.c112233 || cType == PokerType.c111222) { if (Common.getValue(c.get(0)) <= Common.getValue(currentlist.get(0))) return 0; else return 1; } if (cType == PokerType.c31 || cType == PokerType.c32 || cType == PokerType.c411 || cType == PokerType.c422 || cType == PokerType.c11122234 || cType == PokerType.c1112223344) { List<Poker> a1 = Common.getOrder2(c); List<Poker> a2 = Common.getOrder2(currentlist); if (Common.getValue(a1.get(0)) < Common.getValue(a2.get(0))) return 0; } return 1; } public static ArrayList getOrder2(List<Poker> list) { ArrayList<Poker> list2 = new ArrayList<>(list); ArrayList<Poker> list3 = new ArrayList<>(); int len = list2.size(); int a[] = new int[20]; for (int i = 0; i < 20; i++) a[i] = 0; for (int i = 0; i < len; i++) { a[Common.getValue(list2.get(i))]++; } int max = 0; for (int i = 0; i < 20; i++) { max = 0; for (int j = 19; j >= 0; j--) { if (a[j] > a[max]) max = j; } for (int k = 0; k < len; k++) { if (Common.getValue(list2.get(k)) == max) { list3.add(list2.get(k)); } } list2.remove(list3); a[max] = 0; } return list3; } public static void showOrders(int i, ArrayList<Poker> list, Model model) { switch (i) { case 1: Common.getSingle(list, model); break; case 2: Common.getTwo(list, model); Common.getTwoTwo(list, model); break; case 3: Common.getThree(list, model); Common.getPlane(list, model); break; case 4: Common.getBoomb(list, model); break; case 5: Common.get123(list, model); break; } } } class PokerIndex { ArrayList<ArrayList<Integer>> indexList = new ArrayList<>(); }
游戏界面GameJFrame类
import javazoom.jl.decoder.JavaLayerException; import lynu.rookie.main.Poker; import music.MusicPlayer; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Collections; public class GameJFrame extends JFrame implements ActionListener{ //获取界面中的隐藏容器 public static Container container = null; //抢地主和不抢两个按钮 初始 JButton[] landlord= new JButton[2]; //null //管理出牌和不要两个按钮 JButton[] publishCard = new JButton[2]; int lordFlag; int turn; //抢地主后的地主图标 JLabel lord; //集合嵌套集合 大集合嵌套三个小集合 //小集合装每一个玩家当前要出的牌 //索引 0:左边电脑 1:中间玩家 2:右边电脑 ArrayList<ArrayList<Poker>> currentList = new ArrayList<>(); //小集合中装着每一个玩家的手牌 ArrayList<ArrayList<Poker>> playerList = new ArrayList<>(); //底牌 ArrayList<Poker> lordList = new ArrayList<>(); //牌库,装所有的牌 ArrayList<Poker> pokerList = new ArrayList(); //3个玩家前方的出牌倒计时提示 JTextField time[] = new JTextField[3]; //用户操作 多线程 PlayerOperation po; boolean nextPlayer = false; public GameJFrame(){ //设置任务栏地主图标 setIconImage(Toolkit.getDefaultToolkit().getImage("image\\lord.png")); //设置窗口的基本属性,包括标题、大小、关闭模式、窗口是否可以调节、背景颜色等 initJFrame(); //添加添加界面中需要的组件,如抢地主和不抢地主按钮、玩家前的提示文字等 initView(); //先显示界面再发牌,发牌动画在界面展示前无法展示 this.setVisible(true); //初始化牌 备-洗-发 //initCard()方法放在新的线程中执行,可以实现在后台进行牌局的初始化操作 new Thread(this::initCard).start(); //进行牌局的初始化,包括创建三个集合装三个玩家要出的牌、展示抢地主和不抢地主两个按钮、展示倒计时文本等 initGame(); //播放音乐 playMusic(); } //由于登陆成功后游戏界面打开,音乐播放器阻塞游戏界面 //将音乐播放器放在异步加载的线程中,以免阻塞主线程游戏界面的加载 private void playMusic(){ Thread thread = new Thread(() -> { //播放音乐 try { new MusicPlayer(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (JavaLayerException e) { e.printStackTrace(); } }); thread.start(); } //初始化 备-洗-发牌 public void initCard(){ //准备牌 //把所有牌添加到牌盒cardList中 4个花色 13个序号 大小王当作第5种花色存两张 for(int i=1;i<=5;i++){ for(int j=1;j<=13;j++){ if(i==5 && j>2){ break; }else{ //中央牌盒显示为背面 Poker poker = new Poker(this,i + "-" + j,false); poker.setLocation(350,150); pokerList.add(poker); container.add(poker); } } } //洗牌 Collections.shuffle(pokerList); //创建三个数据集合装三个玩家的牌,放到大集合管理 ArrayList<Poker> player0 = new ArrayList<>(); ArrayList<Poker> player1 = new ArrayList<>(); ArrayList<Poker> player2 = new ArrayList<>(); for(int i = 0;i<pokerList.size();i++){ //获取当前遍历的牌 Poker poker = pokerList.get(i); //给地主发三张牌 if(i<=2){ //移动牌 获取牌当前位置 设置新的坐标 Common.move(poker,poker.getLocation(),new Point(270+(75*i),10)); //把底牌添加到集合中 lordList.add(poker); continue; } //给三个玩家发牌 if(i%3 == 0){ Common.move(poker,poker.getLocation(),new Point(50,60+i*5)); player0.add(poker); }else if(i%3 == 1){ Common.move(poker,poker.getLocation(),new Point(180+i*7,470)); player1.add(poker); //自己的牌展示为正面 poker.turnFront(); }else if(i%3 == 2){ Common.move(poker,poker.getLocation(),new Point(700,i*5)); player2.add(poker); } //把三个装着牌的集合放入大集合管理 playerList.add(player0); playerList.add(player1); playerList.add(player2); //把当前的牌置于顶端,效果:牌依次错开 container.setComponentZOrder(poker,0); } //给手牌排序 for(int i=0;i<3;i++){ //排序 Common.order(playerList.get(i)); //重新摆放顺序 Common.rePosition(this,playerList.get(i),i); } } //打牌之前的准备工作 private void initGame(){ //创建三个集合装三个玩家要出的牌 for(int i=0;i<3;i++){ ArrayList<Poker> list = new ArrayList<>(); //添加到大集合 currentList.add(list); } //展示抢地主和不抢地主两个按钮 landlord[0].setVisible(true); landlord[1].setVisible(true); //展示自己前方倒计时文本 time[1].setVisible(true); //倒计时10秒 po = new PlayerOperation(this,10); //开启倒计时 po.start(); } @Override //0出抢 1不出不抢 public void actionPerformed(ActionEvent e){ if(e.getSource() == landlord[0]){ //点击抢地主 time[1].setText("抢地主"); po.isRun = false; }else if(e.getSource() == landlord[1]){ //点击不抢 time[1].setText("不抢"); po.isRun = false; }else if(e.getSource() == publishCard[1]){ //点击不要 清空当前牌列表 轮到下一位玩家 currentList.get(1).clear(); this.nextPlayer = true; time[1].setText("不要"); }else if(e.getSource() == publishCard[0]){ //点击出牌 //创建一个临时集合 存放当前 要出的牌 ArrayList<Poker> c = new ArrayList<>(); //获取当前 手牌 ArrayList<Poker> player2 = playerList.get(1); //遍历手牌 要出的牌存放到临时集合 for(int i=0;i<player2.size();i++){ Poker poker = player2.get(i); if(poker.isClicked()){ c.add(poker); } } int flag = 0; //判断,如果左右两个玩家都不要 if(time[0].getText().equals("不要") && time[2].getText().equals("不要")){ //判断当前玩家出牌是否合法 PokerType.c0为不出牌 if(Common.jugdeType(c) != PokerType.c0){ flag = 1; } } else { flag = Common.checkCards(c,currentList,this); } if(flag == 1){ //牌合法 要出的牌放入大集合管理 currentList.set(1,c); //手牌中去除已出的牌 player2.removeAll(c); //计算坐标并移动牌 //移动 使要出的牌出现在手牌上方 Point point = new Point(); point.x = (770/2) - (c.size() + 1) * 15 / 2; point.y = 300; for(int i=0,len = c.size();i<len;i++){ Poker poker = c.get(i); Common.move(poker,poker.getLocation(),point); point.x += 15; } //重新摆放剩余的牌 Common.rePosition(this,player2,1); //隐藏文本提示 time[1].setVisible(false); //轮到下一位玩家 this.nextPlayer = true; } } } //设置界面 public void initJFrame(){ //设置标题 this.setTitle("斗地主"); //设置大小 this.setSize(830,620); //设置关闭模式 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //设置窗口无法进行调节 this.setResizable(false); //界面居中 this.setLocationRelativeTo(null); //container获取界面中的隐藏容器,以后无需再次调用方法获取 container = this.getContentPane(); //取消内部默认的居中放置 container.setLayout(null); //设置背景颜色 container.setBackground(Color.LIGHT_GRAY); } //添加组件 public void initView(){ //创建抢地主的按钮 JButton robBut = new JButton("抢地主"); //设置位置 robBut.setBounds(320,400,75,20); //添加点击事件 robBut.addActionListener(this); robBut.setVisible(false); landlord[0] = robBut; container.add(robBut); //创建不抢的按钮 JButton noBut = new JButton("不 抢"); //设置位置 noBut.setBounds(420,400,75,20); //添加点击事件 noBut.addActionListener(this); noBut.setVisible(false); //添加到数组中管理 landlord[1] = noBut; container.add(noBut); //创建出牌的按钮 JButton outCardBut = new JButton("出牌"); outCardBut.setBounds(320,400,60,20); outCardBut.addActionListener(this); outCardBut.setVisible(false); publishCard[0] = outCardBut; container.add(outCardBut); //创建不要的按钮 JButton noCardBut = new JButton("不要"); noCardBut.setBounds(420, 400, 60, 20); noCardBut.addActionListener(this); noCardBut.setVisible(false); publishCard[1] = noCardBut; container.add(noCardBut); //创建玩家前的提示文字 倒计时 for (int i = 0; i < 3; i++) { time[i] = new JTextField("倒计时"); //输入框不可编辑 time[i].setEditable(false); time[i].setVisible(false); //三个输入框添加到容器界面 container.add(time[i]); int x = 150 + 235 * i; int y = 230 + (i==1 ? 130 : 0); time[i].setBounds(x, y, 60, 20); } //创建地主图标 先不设置位置 lord = new JLabel(new ImageIcon("image/lord.png")); lord.setVisible(false); lord.setSize(40,40); container.add(lord); } }
登录注册类LoginJFrame
import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; //继承JFrame类 鼠标监听接口 public class LoginJFrame extends JFrame implements MouseListener { private String newcodeStr = ""; //保存codeStr的值的变量 newcodeStr为全局变量 封装后仅有本类可以访问 可以在本类不同方法传递 private static List<User> userDatabase = new ArrayList<>(); //静态方法getUser(String userName) 从userDatabase列表中根据用户名查找用户对象 //在登录和修改密码的事件监听器中 //根据用户名从数据库中获取对应的用户对象 private static User getUser(String userName){ for(User user: userDatabase){ //for-each 循环来遍历 userDatabase 列表中的每个用户对象 if(user.getUserName().equals(userName)){ return user; } } return null; } JButton loginButton = new JButton(); JButton registerButton = new JButton(); JButton changePasswordButton = new JButton(); JButton showUserListButton = new JButton(); JTextField usernameText = new JTextField(20); JPasswordField passwordText = new JPasswordField(20); JTextField codeText = new JTextField(6); //正确的验证码 JLabel rightCode = new JLabel(); public LoginJFrame(){ //初始化界面 initJFrame(); //初始化组件,在页面中添加内容 initView(); //让当前界面显示出来 this.setVisible(true); } public void initJFrame(){ //设置宽高 标题 关闭后停止运行 居中 置顶 取消默认布局 this.setSize(640,420); this.setTitle("斗地主游戏登录 Version:1.0.0 "); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setLocationRelativeTo(null); this.setAlwaysOnTop(true); this.setLayout(null); } public void initView(){ //添加用户名文字 Font字体样式大小 JLabel标签 setForeground设置前景颜色 setFont传入定义字体 setBounds设置字边框大小 //getContentPane(添加标签).add() 获取内容窗格 Font usernameFont = new Font("微软雅黑",1,16); JLabel usernameLabel = new JLabel("用户名"); usernameLabel.setForeground(Color.white); usernameLabel.setFont(usernameFont); usernameLabel.setBounds(140,55,55,22); this.getContentPane().add(usernameLabel); //添加用户名输入框 usernameText.setBounds(223,46,200,30); this.getContentPane().add(usernameText); //添加密码文字 Font passwordFont = new Font("微软雅黑",1,16); JLabel passwordLabel = new JLabel("密码"); passwordLabel.setForeground(Color.white); passwordLabel.setFont(passwordFont); passwordLabel.setBounds(197,95,40,22); this.getContentPane().add(passwordLabel); //添加密码输入框 passwordText.setBounds(263,87,160,30); this.getContentPane().add(passwordText); //验证码文字 Font codeFont = new Font("微软雅黑",1,16); JLabel codeLabel = new JLabel("验证码"); codeLabel.setForeground(Color.white); codeLabel.setFont(codeFont); codeLabel.setBounds(215,142,55,22); this.getContentPane().add(codeLabel); //验证码输入框 codeText.setBounds(291,133,100,30); this.getContentPane().add(codeText); //获取正确的验证码 String codeStr = CodeUtil.getCode(); Font rightCodeFont = new Font("微软雅黑",1,15); //设置颜色 rightCode.setForeground(Color.white); //设置字体 rightCode.setFont(rightCodeFont); //设置内容 rightCode.setText(codeStr); newcodeStr = codeStr; //组件初始化时,调用CodeUtil.getCode()方法获取随机验证码保存到codeStr中 再将codeStr的值赋给newCodeStr //绑定鼠标事件 rightCode.addMouseListener(this); //设置位置和宽高 rightCode.setBounds(400,133,100,30); //添加到界面 this.getContentPane().add(rightCode); //添加登录按钮 loginButton.setBounds(50,310,128,47); loginButton.setIcon(new ImageIcon("D:\\CHINESEPOKER\\image\\login\\登录按钮.png")); //去除按钮的边框背景 loginButton.setBorderPainted(false); loginButton.setContentAreaFilled(false); //给登录按钮绑定鼠标事件 loginButton.addMouseListener(this); loginButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("点击了登录按钮"); // 获取用户名输入框与密码输入框内容 String usernameInput = usernameText.getText(); String passwordInput = new String(passwordText.getPassword()); String codeInput = codeText.getText(); User user = getUser(usernameInput); //Java中,当一个对象为null时,如果我们试图调用该对象的方法或访问其属性,就会抛出空指针异常 //检查getUser()返回的user对象是否为null,以避免空指针异常 if(codeInput.length() != 0 && codeInput.equals(newcodeStr)){ System.out.println("验证码正确"); if (user != null && user.getUserName().equals(usernameInput) && user.getPassWord().equals(passwordInput)) { showJDialog("登录成功"); //关闭当前登录界面并打开游戏界面 closeOpenGameWindow(); usernameText.setText(""); passwordText.setText(""); codeText.setText(""); } else { showJDialog("用户名或密码错误"); } }else{ showJDialog("验证码错误"); } } }); this.getContentPane().add(loginButton); //添加注册按钮 大小图标 registerButton.setBounds(190,310,128,47); registerButton.setIcon(new ImageIcon("D:\\CHINESEPOKER\\image\\login\\注册按钮.png")); //去除按钮的边框背景 registerButton.setBorderPainted(false); registerButton.setContentAreaFilled(false); //给注册按钮绑定鼠标事件 registerButton.addMouseListener(this); registerButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("点击了注册按钮"); String usernameInput = usernameText.getText(); String passwordInput = new String(passwordText.getPassword()); String codeInput = codeText.getText(); if(codeInput.length() !=0 && codeInput.equals(newcodeStr)){ System.out.println("验证码正确"); if(usernameInput.length() != 0 && passwordInput.length() !=0){ User user = getUser(usernameInput); if(user == null){ user = new User(usernameInput,passwordInput); userDatabase.add(user); showJDialog("注册成功"); //更换验证码 String code = CodeUtil.getCode(); rightCode.setText(code); newcodeStr = code; //如果没有newCoderStr保存改变验证码的值 那么rightCode标签变化CodeStr值不变 登录验证码不匹配 usernameText.setText(""); passwordText.setText(""); codeText.setText(""); } else { showJDialog("用户已存在"); } } else { showJDialog("用户名或密码为空"); } }else{ showJDialog("验证码错误"); } } }); this.getContentPane().add(registerButton); //添加修改密码按钮 大小图标 changePasswordButton.setBounds(330,310,128,47); changePasswordButton.setIcon(new ImageIcon("D:\\CHINESEPOKER\\image\\login\\修改密码按钮.png")); //去除按钮边框背景 changePasswordButton.setBorderPainted(false); changePasswordButton.setContentAreaFilled(false); //给按钮绑定鼠标事件和监听器 changePasswordButton.addMouseListener(this); changePasswordButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { String usernameInput = usernameText.getText(); User user = getUser(usernameInput); if(user != null && user.getUserName().equals(usernameInput)){ String newPassword = new String(passwordText.getPassword()); if(newPassword != null && !newPassword.isEmpty()){ user.setPassword(newPassword); // 更新用户密码 showJDialog("更改密码成功"); } else { showJDialog("密码不能为空"); } } else { showJDialog("用户不存在"); } } }); this.getContentPane().add(changePasswordButton); //添加用户列表按钮 大小图标 showUserListButton.setBounds(470,310,128,47); showUserListButton.setIcon(new ImageIcon("D:\\CHINESEPOKER\\image\\login\\用户列表按钮.png")); //去除按钮边框背景 showUserListButton.setBorderPainted(false); showUserListButton.setContentAreaFilled(false); //给按钮添加鼠标事件和监听 showUserListButton.addMouseListener(this); showUserListButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { StringBuilder userList = new StringBuilder("注册用户名列表:\n"); if (!userDatabase.isEmpty()) { for (User user : userDatabase) { userList.append(user.getUserName()).append("\n"); } showJDialog(userList.toString()); } else { showJDialog("未注册用户"); } } }); this.getContentPane().add(showUserListButton); //添加背景图片 JLabel background = new JLabel(new ImageIcon("D:\\CHINESEPOKER\\image\\login\\background.png")); background.setBounds(0,0,633,423); this.getContentPane().add(background); } public void closeOpenGameWindow(){ this.dispose(); new GameJFrame(); } //弹窗方法 public void showJDialog(String content){ //创建一个弹窗对象 JDialog jDialog = new JDialog(); //给弹窗设置大小 jDialog.setSize(260,150); //给弹窗置顶 jDialog.setAlwaysOnTop(true); //让弹窗居中 jDialog.setLocationRelativeTo(null); //弹窗不关闭无法操作下面界面 jDialog.setModal(true); //设置弹窗背景颜色 jDialog.getContentPane().setBackground(Color.LIGHT_GRAY); //设置边框 jDialog.getRootPane().setBorder(BorderFactory.createLineBorder(Color.GRAY,2)); //创建JLabel对象 添加文字到弹窗上 JLabel warning = new JLabel(content,SwingConstants.CENTER); warning.setFont(new Font("微软雅黑",Font.BOLD,16)); warning.setBounds(0,0,200,150); jDialog.getContentPane().add(warning); //添加重试按钮 JPanel widowPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); jDialog.add(widowPanel,BorderLayout.SOUTH); JButton closeButton = new JButton("重试"); closeButton.setFocusPainted(false); closeButton.setFont(new Font("微软雅黑",Font.BOLD,16)); widowPanel.add(closeButton); closeButton.addActionListener(e -> jDialog.dispose()); //显示弹窗 jDialog.setVisible(true); } @Override //鼠标点击 e.getSource()方法获取用户单击的组件 public void mouseClicked(MouseEvent e) { if(e.getSource() == rightCode){ System.out.println("更换了验证码"); //更换验证码 String code = CodeUtil.getCode(); rightCode.setText(code); newcodeStr = code; } } @Override //按下不松 public void mousePressed(MouseEvent e) { if(e.getSource() == loginButton){ loginButton.setIcon(new ImageIcon("D:\\CHINESEPOKER\\image\\login\\登录按下.png")); }else if(e.getSource() == registerButton){ registerButton.setIcon(new ImageIcon("D:\\CHINESEPOKER\\image\\login\\注册按下.png")); }else if(e.getSource() == changePasswordButton){ changePasswordButton.setIcon(new ImageIcon("D:\\CHINESEPOKER\\image\\login\\修改密码按下.png")); }else if(e.getSource() == showUserListButton){ showUserListButton.setIcon(new ImageIcon("D:\\\\CHINESEPOKER\\\\image\\\\login\\\\用户列表按下.png")); } } @Override //松开按钮 public void mouseReleased(MouseEvent e) { if(e.getSource() == loginButton){ loginButton.setIcon(new ImageIcon("D:\\CHINESEPOKER\\image\\login\\登录按钮.png")); }else if(e.getSource() == registerButton){ registerButton.setIcon(new ImageIcon("D:\\CHINESEPOKER\\image\\login\\注册按钮.png")); }else if(e.getSource() == changePasswordButton){ changePasswordButton.setIcon(new ImageIcon("D:\\CHINESEPOKER\\image\\login\\修改密码按钮.png")); }else if(e.getSource() == showUserListButton){ showUserListButton.setIcon(new ImageIcon("D:\\\\CHINESEPOKER\\\\image\\\\login\\\\用户列表按钮.png")); } } @Override //鼠标划入 public void mouseEntered(MouseEvent e) { } @Override //鼠标划出 public void mouseExited(MouseEvent e) { } }
Model类
import java.util.ArrayList; public class Model { int value; //极值 int num; //过手数 ArrayList<String> a1 = new ArrayList<>(); //单张 ArrayList<String> a2 = new ArrayList<>(); //对子 ArrayList<String> a3 = new ArrayList<>(); //三带 ArrayList<String> a123 = new ArrayList<>(); //连子 ArrayList<String> a112233 = new ArrayList<>(); //连牌 ArrayList<String> a111222 = new ArrayList<>(); //飞机 ArrayList<String> a4 = new ArrayList<>(); //炸弹 }
游戏操作类PlayerOperation import lynu.rookie.main.Poker; import javax.swing.*; import java.awt.*; import java.util.ArrayList; import java.util.List; public class PlayerOperation extends Thread { //游戏主界面 GameJFrame gameJFrame; //是否能走 boolean isRun = true; //倒计时 int i; public PlayerOperation(GameJFrame m, int i) { this.gameJFrame = m; this.i = i; } @Override public void run() { while (i > -1 && isRun) { gameJFrame.time[1].setText("倒计时:" + i--); sleep(1); } if (i == -1){ gameJFrame.time[1].setText("不抢"); } gameJFrame.landlord[0].setVisible(false); gameJFrame.landlord[1].setVisible(false); for (Poker poker2 : gameJFrame.playerList.get(1)){ poker2.setCanClick(true);// 可被点击 } if (gameJFrame.time[1].getText().equals("抢地主")) { gameJFrame.playerList.get(1).addAll(gameJFrame.lordList); openlord(true); sleep(2); Common.order(gameJFrame.playerList.get(1)); Common.rePosition(gameJFrame, gameJFrame.playerList.get(1), 1); gameJFrame.publishCard[1].setEnabled(false); setlord(1); } else { if (Common.getScore(gameJFrame.playerList.get(0)) < Common.getScore(gameJFrame.playerList.get(2))) { gameJFrame.time[2].setText("抢地主"); gameJFrame.time[2].setVisible(true); setlord(2); openlord(true); sleep(3); gameJFrame.playerList.get(2).addAll(gameJFrame.lordList); Common.order(gameJFrame.playerList.get(2)); Common.rePosition(gameJFrame, gameJFrame.playerList.get(2), 2); openlord(false); } else { gameJFrame.time[0].setText("抢地主"); gameJFrame.time[0].setVisible(true); setlord(0); openlord(true); sleep(3); gameJFrame.playerList.get(0).addAll(gameJFrame.lordList); Common.order(gameJFrame.playerList.get(0)); Common.rePosition(gameJFrame, gameJFrame.playerList.get(0), 0); openlord(false); } } gameJFrame.landlord[0].setVisible(false); gameJFrame.landlord[1].setVisible(false); turnOn(false); for (int i = 0; i < 3; i++) { gameJFrame.time[i].setText("不要"); gameJFrame.time[i].setVisible(false); } gameJFrame.turn = gameJFrame.lordFlag; while (true) { if (gameJFrame.turn == 1) { if (gameJFrame.time[0].getText().equals("不要") && gameJFrame.time[2].getText().equals("不要")) gameJFrame.publishCard[1].setEnabled(false); else { gameJFrame.publishCard[1].setEnabled(true); } turnOn(true); timeWait(30, 1); turnOn(false); gameJFrame.turn = (gameJFrame.turn + 1) % 3; if (win()) break; } if (gameJFrame.turn == 0) { computer0(); gameJFrame.turn = (gameJFrame.turn + 1) % 3; if (win()) break; } if (gameJFrame.turn == 2) { computer2(); gameJFrame.turn = (gameJFrame.turn + 1) % 3; if (win()) break; } } } //定义一个方法用来暂停N秒 //参数为等待的时间 //因为线程中的sleep方法有异常,直接调用影响阅读 public void sleep(int i) { try { Thread.sleep(i * 1000); } catch (InterruptedException e) { e.printStackTrace(); } } public void openlord(boolean is) { for (int i = 0; i < 3; i++) { if (is) gameJFrame.lordList.get(i).turnFront(); else { gameJFrame.lordList.get(i).turnRear(); } gameJFrame.lordList.get(i).setCanClick(true); } } public void setlord(int i) { Point point = new Point(); if (i == 1) { point.x = 80; point.y = 430; gameJFrame.lordFlag = 1; } if (i == 0) { point.x = 80; point.y = 20; gameJFrame.lordFlag = 0; } if (i == 2) { point.x = 700; point.y = 20; gameJFrame.lordFlag = 2; } gameJFrame.lord.setLocation(point); gameJFrame.lord.setVisible(true); } public void turnOn(boolean flag) { gameJFrame.publishCard[0].setVisible(flag); gameJFrame.publishCard[1].setVisible(flag); } public void computer0() { timeWait(1, 0); ShowCard(0); } public void computer2() { timeWait(1, 2); ShowCard(2); } public void ShowCard(int role) { int orders[] = new int[] { 4, 3, 2, 1, 5 }; Model model = Common.getModel(gameJFrame.playerList.get(role), orders); ArrayList<String> list = new ArrayList<>(); if (gameJFrame.time[(role + 1) % 3].getText().equals("不要") && gameJFrame.time[(role + 2) % 3].getText().equals("不要")) { if (model.a123.size() > 0) { list.add(model.a123.get(model.a123.size() - 1)); } else if (model.a3.size() > 0) { if (model.a1.size() > 0) { list.add(model.a1.get(model.a1.size() - 1)); } else if (model.a2.size() > 0) { list.add(model.a2.get(model.a2.size() - 1)); } list.add(model.a3.get(model.a3.size() - 1)); } else if (model.a112233.size() > 0) { list.add(model.a112233.get(model.a112233.size() - 1)); } else if (model.a111222.size() > 0) { String name[] = model.a111222.get(0).split(","); if (name.length / 3 <= model.a1.size()) { list.add(model.a111222.get(model.a111222.size() - 1)); for (int i = 0; i < name.length / 3; i++) list.add(model.a1.get(i)); } else if (name.length / 3 <= model.a2.size()) { list.add(model.a111222.get(model.a111222.size() - 1)); for (int i = 0; i < name.length / 3; i++) list.add(model.a2.get(i)); } } else if (model.a2.size() > (model.a111222.size() * 2 + model.a3.size())) { list.add(model.a2.get(model.a2.size() - 1)); } else if (model.a1.size() > (model.a111222.size() * 2 + model.a3.size())) { list.add(model.a1.get(model.a1.size() - 1)); } else if (model.a4.size() > 0) { int sizea1 = model.a1.size(); int sizea2 = model.a2.size(); if (sizea1 >= 2) { list.add(model.a1.get(sizea1 - 1)); list.add(model.a1.get(sizea1 - 2)); list.add(model.a4.get(0)); } else if (sizea2 >= 2) { list.add(model.a2.get(sizea1 - 1)); list.add(model.a2.get(sizea1 - 2)); list.add(model.a4.get(0)); } else { list.add(model.a4.get(0)); } } } else { if (role != gameJFrame.lordFlag) { int f = 0; if (gameJFrame.time[gameJFrame.lordFlag].getText().equals("不要")) { f = 1; } if ((role + 1) % 3 == gameJFrame.lordFlag) { if ((Common.jugdeType(gameJFrame.currentList.get((role + 2) % 3)) != PokerType.c1 || Common.jugdeType(gameJFrame.currentList.get((role + 2) % 3)) != PokerType.c2) && gameJFrame.currentList.get(gameJFrame.lordFlag).size() < 1) f = 1; if (gameJFrame.currentList.get((role + 2) % 3).size() > 0 && Common.getValue(gameJFrame.currentList.get((role + 2) % 3).get(0)) > 13) f = 1; } if (f == 1) { gameJFrame.time[role].setVisible(true); gameJFrame.time[role].setText("不要"); return; } } int can = 0; if (role == gameJFrame.lordFlag) { if (gameJFrame.playerList.get((role + 1) % 3).size() <= 5 || gameJFrame.playerList.get((role + 2) % 3).size() <= 5) can = 1; } else { if (gameJFrame.playerList.get(gameJFrame.lordFlag).size() <= 5) can = 1; } ArrayList<Poker> player; if (gameJFrame.time[(role + 2) % 3].getText().equals("不要")) player = gameJFrame.currentList.get((role + 1) % 3); else player = gameJFrame.currentList.get((role + 2) % 3); PokerType cType = Common.jugdeType(player); if (cType == PokerType.c1) { if (can == 1) model = Common.getModel(gameJFrame.playerList.get(role), new int[] { 1, 4, 3, 2, 5 }); AI_1(model.a1, player, list, role); } else if (cType == PokerType.c2) { if (can == 1) model = Common.getModel(gameJFrame.playerList.get(role), new int[] { 2, 4, 3, 5, 1 }); AI_1(model.a2, player, list, role); } else if (cType == PokerType.c3) { AI_1(model.a3, player, list, role); } else if (cType == PokerType.c4) { AI_1(model.a4, player, list, role); } else if (cType == PokerType.c31) { if (can == 1) model = Common.getModel(gameJFrame.playerList.get(role), new int[] { 3, 1, 4, 2, 5 }); AI_2(model.a3, model.a1, player, list, role); } else if (cType == PokerType.c32) { if (can == 1) model = Common.getModel(gameJFrame.playerList.get(role), new int[] { 3, 2, 4, 5, 1 }); AI_2(model.a3, model.a2, player, list, role); } else if (cType == PokerType.c411) { AI_5(model.a4, model.a1, player, list, role); } else if (cType == PokerType.c422) { AI_5(model.a4, model.a2, player, list, role); } else if (cType == PokerType.c123) { if (can == 1) model = Common.getModel(gameJFrame.playerList.get(role), new int[] { 5, 3, 2, 4, 1 }); AI_3(model.a123, player, list, role); } else if (cType == PokerType.c112233) { if (can == 1) model = Common.getModel(gameJFrame.playerList.get(role), new int[] { 2, 4, 3, 5, 1 }); AI_3(model.a112233, player, list, role); } else if (cType == PokerType.c11122234) { AI_4(model.a111222, model.a1, player, list, role); } else if (cType == PokerType.c1112223344) { AI_4(model.a111222, model.a2, player, list, role); } if (list.size() == 0 && can == 1) { int len4 = model.a4.size(); if (len4 > 0) list.add(model.a4.get(len4 - 1)); } } gameJFrame.currentList.get(role).clear(); if (list.size() > 0) { Point point = new Point(); if (role == 0) point.x = 200; if (role == 2) point.x = 550; if (role == 1) { point.x = (770 / 2) - (gameJFrame.currentList.get(1).size() + 1) * 15 / 2; point.y = 300; } point.y = (400 / 2) - (list.size() + 1) * 15 / 2; ArrayList<Poker> temp = new ArrayList<>(); for (int i = 0, len = list.size(); i < len; i++) { List<Poker> pokers = getCardByName(gameJFrame.playerList.get(role), list.get(i)); for (Poker poker : pokers) { temp.add(poker); } } temp = Common.getOrder2(temp); for (Poker poker : temp) { Common.move(poker, poker.getLocation(), point); point.y += 15; gameJFrame.container.setComponentZOrder(poker, 0); gameJFrame.currentList.get(role).add(poker); gameJFrame.playerList.get(role).remove(poker); } Common.rePosition(gameJFrame, gameJFrame.playerList.get(role), role); } else { gameJFrame.time[role].setVisible(true); gameJFrame.time[role].setText("不要"); } for (Poker poker : gameJFrame.currentList.get(role)) poker.turnFront(); } public List getCardByName(List<Poker> list, String n) { String[] name = n.split(","); ArrayList cardsList = new ArrayList(); int j = 0; for (int i = 0, len = list.size(); i < len; i++) { if (j < name.length && list.get(i).getName().equals(name[j])) { cardsList.add(list.get(i)); i = 0; j++; } } return cardsList; } public void AI_3(List<String> model, List<Poker> player, List<String> list, int role) { for (int i = 0, len = model.size(); i < len; i++) { String[] s = model.get(i).split(","); if (s.length == player.size() && getValueInt(model.get(i)) > Common.getValue(player.get(0))) { list.add(model.get(i)); return; } } } public void AI_4(List<String> model1, List<String> model2, List<Poker> player, List<String> list, int role) { player = Common.getOrder2(player); int len1 = model1.size(); int len2 = model2.size(); if (len1 < 1 || len2 < 1) return; for (int i = 0; i < len1; i++) { String[] s = model1.get(i).split(","); String[] s2 = model2.get(0).split(","); if ((s.length / 3 <= len2) && (s.length * (3 + s2.length) == player.size()) && getValueInt(model1.get(i)) > Common.getValue(player.get(0))) { list.add(model1.get(i)); for (int j = 1; j <= s.length / 3; j++) list.add(model2.get(len2 - j)); } } } public void AI_5(List<String> model1, List<String> model2, List<Poker> player, List<String> list, int role) { player = Common.getOrder2(player); int len1 = model1.size(); int len2 = model2.size(); if (len1 < 1 || len2 < 2) return; for (int i = 0; i < len1; i++) { if (getValueInt(model1.get(i)) > Common.getValue(player.get(0))) { list.add(model1.get(i)); for (int j = 1; j <= 2; j++) list.add(model2.get(len2 - j)); } } } public void AI_1(List<String> model, List<Poker> player, List<String> list, int role) { for (int len = model.size(), i = len - 1; i >= 0; i--) { if (getValueInt(model.get(i)) > Common.getValue(player.get(0))) { list.add(model.get(i)); break; } } } public void AI_2(List<String> model1, List<String> model2, List<Poker> player, List<String> list, int role) { player = Common.getOrder2(player); int len1 = model1.size(); int len2 = model2.size(); if (len1 > 0 && model1.get(0).length() < 10) { list.add(model1.get(0)); System.out.println("王炸"); return; } if (len1 < 1 || len2 < 1) return; for (int len = len1, i = len - 1; i >= 0; i--) { if (getValueInt(model1.get(i)) > Common.getValue(player.get(0))) { list.add(model1.get(i)); break; } } list.add(model2.get(len2 - 1)); if (list.size() < 2) list.clear(); } public void timeWait(int n, int player) { if (gameJFrame.currentList.get(player).size() > 0) Common.hideCards(gameJFrame.currentList.get(player)); if (player == 1) { int i = n; while (gameJFrame.nextPlayer == false && i >= 0) { gameJFrame.time[player].setText("倒计时:" + i); gameJFrame.time[player].setVisible(true); sleep(1); i--; } if (i == -1 && player == 1) { ShowCard(1); } gameJFrame.nextPlayer = false; } else { for (int i = n; i >= 0; i--) { sleep(1); gameJFrame.time[player].setText("倒计时:" + i); gameJFrame.time[player].setVisible(true); } } gameJFrame.time[player].setVisible(false); } public int getValueInt(String n) { String name[] = n.split(","); String s = name[0]; int i = Integer.parseInt(s.substring(2, s.length())); if (s.substring(0, 1).equals("5")) i += 3; if (s.substring(2, s.length()).equals("1") || s.substring(2, s.length()).equals("2")) i += 13; return i; } public boolean win() { for (int i = 0; i < 3; i++) { if (gameJFrame.playerList.get(i).size() == 0) { String s; if (i == 1) { s = "恭喜你,胜利了!"; } else { s = "恭喜电脑" + i + ",赢了! 你的智商有待提高哦"; } for (int j = 0; j < gameJFrame.playerList.get((i + 1) % 3).size(); j++) gameJFrame.playerList.get((i + 1) % 3).get(j).turnFront(); for (int j = 0; j < gameJFrame.playerList.get((i + 2) % 3).size(); j++) gameJFrame.playerList.get((i + 2) % 3).get(j).turnFront(); JOptionPane.showMessageDialog(gameJFrame, s); return true; } } return false; } }
出牌类型PokerType 枚举 一些有相同关系的常量
public enum PokerType { c0,//不出牌 c1,//单张牌 c2,//二张相同牌,对子 c3,//三张相同牌 c4,//四张相同牌,炸弹 c31,//三张相同牌与单张牌,三带一 c32,//三张相同牌与二张相同牌,三带二 c411,//4张相同牌与二张牌 c422,//4张相同牌与二对牌 c123,//连牌 c112233,//连对 c111222,//飞机 c11122234,//飞机带二张牌 c1112223344,//飞机带对子 }
main包下新建类
Poker类
import javax.swing.*; import java.awt.*; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; public class Poker extends JLabel implements MouseListener { //游戏的主界面 GameJFrame gameJFrame; //牌的名字 String name; //牌显示正面还是反面 boolean up; //是否可点击 boolean canClick = false; //当前状态,是否已经被点击 boolean clicked = false; public Poker(GameJFrame m, String name, boolean up) { this.gameJFrame = m; this.name = name; this.up = up; //判断当前的牌是显示正面还是背面 if (this.up){ this.turnFront(); }else { this.turnRear(); } //设置牌的宽高大小 this.setSize(71, 96); //把牌显示出来 this.setVisible(true); //给每一张牌添加鼠标监听 this.addMouseListener(this); } public Poker() { } public Poker(GameJFrame gameJFrame, String name, boolean up, boolean canClick, boolean clicked) { this.gameJFrame = gameJFrame; this.name = name; this.up = up; this.canClick = canClick; this.clicked = clicked; } //显示正面 public void turnFront() { this.setIcon(new ImageIcon("image\\poker\\" + name + ".png")); this.up = true; } //显示背面 public void turnRear() { this.setIcon(new ImageIcon("image\\poker\\rear.png")); this.up = false; } //出牌时,需要点击牌 //被点击之后,牌向上移动20个像素 //再次被点击,牌回落20个像素 @Override public void mouseClicked(MouseEvent e) { if (canClick) { Point from = this.getLocation(); int step; if (clicked){ step = 20; }else { step = -20; } clicked = !clicked; Point to = new Point(from.x, from.y + step); this.setLocation(to); } } public void mouseEntered(MouseEvent arg0) { } public void mouseExited(MouseEvent arg0) { } public void mouseReleased(MouseEvent arg0) { } public void mousePressed(MouseEvent e) { } /** * 获取 * @return gameJFrame */ public GameJFrame getGameJFrame() { return gameJFrame; } /** * 设置 * @param gameJFrame */ public void setGameJFrame(GameJFrame gameJFrame) { this.gameJFrame = gameJFrame; } /** * 获取 * @return name */ public String getName() { return name; } /** * 设置 * @param name */ public void setName(String name) { this.name = name; } /** * 获取 * @return up */ public boolean isUp() { return up; } /** * 设置 * @param up */ public void setUp(boolean up) { this.up = up; } /** * 获取 * @return canClick */ public boolean isCanClick() { return canClick; } /** * 设置 * @param canClick */ public void setCanClick(boolean canClick) { this.canClick = canClick; } /** * 获取 * @return clicked */ public boolean isClicked() { return clicked; } /** * 设置 * @param clicked */ public void setClicked(boolean clicked) { this.clicked = clicked; } public String toString() { return "Poker{gameJFrame = " + gameJFrame + ", name = " + name + ", up = " + up + ", canClick = " + canClick + ", clicked = " + clicked + "}"; } }
User类
import java.util.HashMap; import java.util.Map; import java.util.Objects; public class User { // 每当用户注册时,会创建一个新的User对象 // 用户对象实际中存储在userDatabase的List列表中 private String username; private String password; public User(String username,String password){ this.username = username; this.password = password; } /* 获取 */ public String getUserName(){ return username; } public String getPassWord(){ return password; } /* 设置 */ public void setUsername(String username){ this.username = username; } public void setPassword(String password) { this.password = password;} @Override public boolean equals(Object o){ if(this == o) return true; if(o == null || getClass() != o.getClass()) return false; User user = (User)o; return Objects.equals(username,user.username) && Objects.equals(password,user.password); } @Override public int hashCode(){ return Objects.hash(username,password); } public String toString(){ //{"内为变量"} return "User{username = " + username + ", password = " + password +"}"; } }
util包下新建类
验证码CodeUtil类
import java.util.ArrayList; import java.util.Random; public class CodeUtil { public static String getCode(){ //创建一个集合; ArrayList<Character> list = new ArrayList<>(); //52 索引范围0-51 //添加字母 a - z A - Z for(int i=0;i<26;i++){ list.add((char)('a' + i));//类型转换为字符97-a 65-A list.add((char)('A' + i)); } //打印集合 //System.out.println(list); //生成4个随机字母 String result = ""; Random r = new Random(); for(int i=0;i<4;i++){ int randomIndex = r.nextInt(list.size()); result = result + list.get(randomIndex); } //长度为4的随机字符串 return result; //基础上拼接数字0-9 int number = r.nextInt(10); //把随机数字拼接到result后面 result = result + number; //把字符串变成字符数组 char[] chars = result.toCharArray(); //生成一个字符数组长度的随机索引 int index = r.nextInt(chars.length); //末索引4上的数字字符与随机索引上的字符交换 使数字出现在索引0-4的任何位置 char temp = chars[4]; chars[4] = chars[index]; chars[index] = temp; //字符数组变回字符串 String code = new String(chars); return code; } }
music包下新建类
MusicPlayer类
音乐可自行替换 javazoom需要配置jar包 jlayer-1.0.1-1.jar 搜索下载
package music; import javazoom.jl.decoder.JavaLayerException; import javazoom.jl.player.Player; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; public class MusicPlayer { public MusicPlayer() throws FileNotFoundException, JavaLayerException { Player player; //工作目录路径拼接音乐的相对路径 String str = System.getProperty("user.dir")+"/src/music/Omeo.mp3"; //BufferedInputStream对象,用于读取音乐文件。将文件路径传递给FileInputStream的构造函数, // 将其包装在BufferedInputStream中,以提高文件读取的效率 while(true){ BufferedInputStream name = new BufferedInputStream(new FileInputStream(str)); player = new Player(name); player.play(); } } }
src下新建App类
import rookie.game.LoginJFrame; public class App { public static void main(String[] args) { new LoginJFrame(); } }