一、学习目标
Map集合、List集合、集合工具类Collections的API在阶段的项目中体现使用。
掌握斗地主验证码登录的业务逻辑。
在斗地主界面需要经过准备牌、洗牌、发牌、排序、看牌这些流程的业务逻辑。
掌握按照业务场景进行面向对象的设计。
最后关于阶段项目的GUI图形化界面自己可以读懂代码即可,现在企业中不需要这种了,前端页面还是重点在h5和JS等。本篇博客底部放上GUI图形化界面我做好每一句的注释,有需要的自取阅读。
二、效果图
登录界面
游戏主界面
三、详解功能
3.1 常见集合API
它是由k、v组成的一一对应的键值对或键值对对象即Entry对象,键不可重复,值可以重复。常见的API如图:
方法 | 说明 |
put方法:添加/覆盖 | 添加元素时键不存在,直接将键值对对象添加到map集合中, 返回null;添加元素时键存在,将原来的键值对对象覆盖,被覆盖的值返回 |
remove方法 | 删除元素 |
clear方法 | 清空集合 |
containsKey方法 | 判断键是否存在 |
containsValue方法 | 判断值是否存在 |
isEmpty方法 | 判断集合是否为空 |
size方法 | 集合的长度 |
Collections是 java.util.Collections 集合工具类,常见的API如图:
名称 | 说明 |
addAll(Collection<? super T> c, T... elements) | 将所有指定元素添加到指定集合。 |
使用默认的随机源随机排列指定的列表。 | |
将指定的列表按照元素的自然顺序升序排列。 | |
sort(List<T> list, Comparator<? super T> c) | 根据指定的比较器的顺序对指定的列表进行排序。 |
binarySearch(List<? extends Comparable<? super T>> list, T key) | 使用二分查找算法在指定列表中查找指定对象。 |
将一个列表中的所有元素复制到另一个列表中。 | |
用指定的元素替换指定列表中的所有元素。 | |
max(Collection<? extends T> coll) | 按元素的自然顺序返回给定集合中的最大元素。 |
交换指定列表中指定位置的元素。 |
验证码登录由生成验证码-->校验验证码--->主界面
图形验证码工具类CodeUtil
public static String getCode(){
// 1.把大写字母或小写字母放到数组中
//1.1 创建数组对象
char[] chs = new char[52];
for (int i = 0; i < chs.length; i++) {
//使用ASCII值转换字符添加大小写字母到数组中
if (i <= 25){
//添加小写字母到数组中
chs[i] = (char) (97 + i);
}else {
//添加大写字母到数组中
chs[i] = (char) (65 + i - 26);
}
}
// 2.在这些字母中的数组中随机抽取4次
//定义字符常量
String result = "";
//创建随机索引的对象
Random r = new Random();
for (int i = 0; i < 4; i++) {
int randIndex = r.nextInt(chs.length);
result = result + chs[randIndex];
}
// 3.随机抽取2个数字
for (int i = 0; i < 2; i++) {
int number = r.nextInt(10);
result = result + number;
}
//System.out.println(result); //BoZG99
//把字符串变成字符数组
char[] chars = result.toCharArray(); //[m,R,o,P,8,4]
int index = r.nextInt(chars.length); // index = 0, 1, 2, 3, 4 5
//4个索引的字母和数字交换
char temp = chars[5];
chars[5] =chars[index];
chars[index] = temp;
//将字符数组转换成字符串
String code = new String(chars);
//System.out.println(code);
return code;
}
验证码校验逻辑
@Override
public void mouseClicked(MouseEvent e) {
//获取登录用户信息
Object obj = e.getSource();
//判断是否有用户登录
//登录
if (obj == login) {
//获取用户名
String usernameInput = username.getText();
//获取密码
String passwordInput = password.getText();
//获取验证码
String codeInput = code.getText();
//判断验证码是否为空
if (codeInput.length() == 0){
showJDialog("验证码为空");
return;
}
//判断用户名或密码是否为空
if (usernameInput.length() == 0 || passwordInput.length() == 0){
showJDialog("用户名或密码为空");
return;
}
//判断验证码是否正确
if (!codeInput.equalsIgnoreCase(rightCode.getText())){
showJDialog("验证码输入错误!");
return;
}
//判断用户名和密码是否正确
User userinfo = new User(usernameInput, passwordInput);
if (allUsers.contains(userinfo)){
this.setVisible(false);
new GameJFrame();
}else {
showJDialog("用户名或密码错误!");
}
}
//注册
if (obj == register) {
System.out.println("新用户注册");
}
//新的验证码
if (obj == rightCode){
String code = CodeUtil.getCode();
rightCode.setText(code);
}
}
准备牌、洗牌、发牌、排序、看牌
public void initCard() {
// 1.准备牌
//i表示牌的花色
for (int i = 1; i <= 5; i++) {
//j表示数字
for (int j = 1; j <= 13; j++) {
if ((i == 5) && (j > 2)) {
break;
} else {
//牌盒的牌在正中央
Poker poker = new Poker(i + "-" + j, false);
poker.setLocation(350, 150);
pokerList.add(poker);
container.add(poker);
}
}
}
// 2.洗牌
Collections.shuffle(pokerList);
// 3.发牌
//创建三个集合管理玩家手中的牌
ArrayList<Poker> user1 = new ArrayList<>(); //左边
ArrayList<Poker> user2 = new ArrayList<>(); //中间
ArrayList<Poker> user3 = new ArrayList<>(); //右边
//遍历牌盒
for (int i = 0; i < pokerList.size(); i++) {
Poker poker = pokerList.get(i);
if (i <= 2) {
lordList.add(poker);
Common.move(poker, poker.getLocation(), new Point(270 + (75 * i), 10));
continue;
} else if (i % 3 == 0) {
Common.move(poker, poker.getLocation(), new Point(50, 60 + i * 5));
user1.add(poker);
} else if (i % 3 == 1) {
Common.move(poker, poker.getLocation(), new Point(180 + i * 7, 450));
user2.add(poker);
} else if (i % 3 == 2) {
Common.move(poker, poker.getLocation(), new Point(700, 60 + i * 5));
user3.add(poker);
}
//把三个装着牌的小集合放到大集合中方便管理
playerList.add(user1);
playerList.add(user2);
playerList.add(user3);
//把当前的牌至于最顶端,这样就会有牌依次错开且叠起来的效果
container.setComponentZOrder(poker, 0);
}
//排序 玩家索引0, 1, 2
for (int i = 0; i < 3; i++) {
order(playerList.get(i));
//重新排序
Common.rePosition(this, playerList.get(i), i);
}
}
//排序
public void order(ArrayList<Poker> list) {
//定义牌的价值进行排序
Collections.sort(list, new Comparator<Poker>() {
@Override
public int compare(Poker o1, Poker o2) {
//o1: 当前要插入到有序序列的牌♥3 ♥6 ♥7 ♥9 🃏 🃏
//o2: 已经在有序序列的牌♥5
//负数:o1是小的
//正数: o1是大的
//0: o1和o2相等 根据花色排序
//计算o1牌的花色和价值 🃏 🃏 截取大小王出现乱码
int color1 = Integer.parseInt(o1.getName().substring(0, 1));
int value1 = getValue(o1);
//计算o2牌的花色和价值
int color2 = Integer.parseInt(o2.getName().substring(0, 1));
int value2 = getValue(o2);
//降序排列
int flag = value2 - value1;
//如果牌的值一样,按照花色排序
if (flag == 0) {
return color2 - color1;
} else {
return flag;
}
}
});
}
//获取每一张牌的价值
public int getValue(Poker poker) {
//TODO 获取牌的名字 1-1
String name = poker.getName(); //1-1
//获取花色
int color = Integer.parseInt(poker.getName().substring(0, 1));
//获取牌的价值
int value = Integer.parseInt(name.substring(2));
//计算大小王的价值
if (color == 5) {
return value += 100;
}
//计算A的价值
if (value == 1) {
return value += 20;
}
//计算2的价值
if (value == 2) {
return value += 30;
}
return value;
}
设计面向对象
//扑克牌实体类
public class Poker extends JLabel implements MouseListener {
//牌的名字 数字-数字 花色-数字
private String name;
//牌的正反面
private boolean up;
//牌是否可以被点击
private boolean clickable = false;
//当前牌的状态,表示牌是否被点击
private boolean clicked = false;
//get/set方法 构造方法省略 ...
在小项目中学习更多关于集合使用细节,可取源码进行学习... ...
链接:https://pan.baidu.com/s/1vsIJRXHzfRLSXx4NDFAu3Q?pwd=lzf6
提取码:lzf6