一、项目介绍
登录界面
登录界面有需要填写用户名、密码、验证码游戏界面
游戏界面通过上下左右键进行拼图,上方菜单栏可以切换图片、重新开始
有隐藏键:按w可以直接胜利,长按A键可以查看完整图片注册界面
注册界面需要填写用户,密码,再次确认密码,两次密码需要一致
点击重置按键清空填写框,重新填写
二、代码实现
1、工具类
分析
因为有一些功能在其他类中需要重复用到,所以写了个工具类,用来存放一些公共方法
arrUtil.java
package com.lwj.util;
import com.lwj.pojo.User;
import javax.swing.*;
import java.sql.Array;
import java.util.ArrayList;
import java.util.Random;
public class arrUtil {
//打乱图片
public int[][] arrChange(){
int[] arr = {
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0};
int[][] newArr = new int[4][4];
Random random = new Random();
// 打乱一维数组
for (int i = 0; i < arr.length; i++) {
//生成随机索引
int index = random.nextInt(arr.length);
int temp = arr[i];
arr[i] = arr[index];
arr[index] = temp;
}
//将一维数组赋值给二维数组
int index = 0;
for (int i = 0; i < newArr.length; i++) {
for (int j = 0; j < newArr[i].length; j++) {
newArr[i][j] = arr[index];
index++;
}
}
return newArr;
}
//判断是否胜利
public boolean victory(int[][] arr){
//定义胜利的数组
int[][] win = {
{
1,2,3,4},{
5,6,7,8},{
9,10,11,12},{
13,14,15,0}};
//判断两个数组是否一样
for (int i = 0; i < win.length; i++) {
for (int j = 0; j < win[i].length; j++) {
if (win[i][j] != arr[i][j]){
return false;
}
}
}
return true;
}
//随机路径
public String changePath(){
String[] str = {
"animal","girl","sport"};
Random random = new Random();
String path = "";
int index = random.nextInt(3);
if (index == 0){
int i = random.nextInt(8) + 1;
path = str[0]+"\\"+"\\"+str[0]+i+"\\\\";
} else if (index == 1){
int i = random.nextInt(13) + 1;
path = str[1]+"\\"+"\\"+str[1]+i+"\\\\";
} else if (index == 2){
int i = random.nextInt(10) + 1;
path = str[2]+"\\"+"\\"+str[2]+i+"\\\\";
}
return path;
}
//生成验证码
public String createCode(){
String[] arr = {
"q","w","e","r","t","y","u","i","o","p","a","s","d","f","g","h","j","k","l","z","x","c","v","b","n","m"};
String code = "";
Random random = new Random();
for (int i = 0; i < 4; i++) {
code += arr[random.nextInt(26)];
}
code+= random.nextInt(10);
return code;
}
//弹窗提示方法
public void showJDialog(){
JDialog jDialog = new JDialog();
jDialog.setSize(200,150);
jDialog.setAlwaysOnTop(true);
jDialog.setLocationRelativeTo(null);
jDialog.setModal(true);
JLabel jLabel = new JLabel();
jLabel.setText("输入错误");
jLabel.setBounds(0,0,200,150);
jDialog.getContentPane().add(jLabel);
jDialog.setVisible(true);
}
}
2、用户pojo类
分析
存放用户信息的javabean类
User.java
package com.lwj.pojo;
public class User {
private String name;
private String password;
public User() {
}
public User(String name, String password) {
this.name = name;
this.password = password;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return password
*/
public String getPassword() {
return password;
}
/**
* 设置
* @param password
*/
public void setPassword(String password) {
this.password = password;
}
public String toString() {
return "User{name = " + name + ", password = " + password + "}";
}
}
3、登录界面
分析
其实就是添加图片、文本输入框、按钮,设置按钮事件,点击登录获取文本框的按钮,在对已有用户进行比对,在账号和密码都正确的情况下要跳转到游戏界面
登录界面代码
LoginJFrame.java
package com.lwj.ui;
import com.lwj.pojo.User;
import com.lwj.util.arrUtil;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
/**
* 登录界面
*/
public class LoginJFrame extends JFrame implements ActionListener , KeyListener {
public LoginJFrame(){
initJFrame();
initImage();
}
//设置窗体
private void initJFrame() {
//设置窗体大小
this.setSize(480,440);
//设置界面标题
this.setTitle("登录界面");
//设置界面置顶
this.setAlwaysOnTop(true);
//设置窗口居中
this.setLocationRelativeTo(null);
//设置默认关闭模式
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//设置窗体可见
this.setVisible(true);
}
//创建用户输入框对象
JTextField userText = new JTextField();
//创建密码输入框
JPasswordField passwordText = new JPasswordField();
//创建验证码输入框
JTextField codeText = new JTextField();
//创建注册按钮
JButton registerButton = new JButton();
//创建登录按钮
JButton loginButton = new JButton();
//存放验证码
String create = "";
//创建工具类对象
arrUtil arrutil = new arrUtil();
//创建数组存放用户
static ArrayList<User> userList = new ArrayList<>();
static {
userList.add(new User("林","123456"));
userList.add(new User("沈敬斌","123456"));
}
public ArrayList<User> reUser(){
return userList;
}
public void setUser(String username,String password){
userList.add(new User(username,password));
}
private void initImage() {
//清空原本已经出现的图片
this.getContentPane().removeAll();
//添加用户图片
JLabel userImage = new JLabel(new ImageIcon("puzzGame\\image\\login\\username.png"));
userImage.setBounds(150,150,47,17);
this.add(userImage);
//添加用户输入框
userText.setBounds(210,150,100,18);
this.add(userText);
//添加密码图片
JLabel passImage = new JLabel(new ImageIcon("puzzGame\\image\\login\\pass.png"));
passImage.setBounds(158,200,32,16);
this.add(passImage);
//添加密码输入框
passwordText.setBounds(210,200,100,18);
this.add(passwordText);
//添加验证码图片
JLabel codeImage = new JLabel(new ImageIcon("puzzGame\\image\\login\\code.png"));
codeImage.setBounds(150,250,56,21);
this.add(codeImage);
//添加验证码输入框
codeText.setBounds(210,250,100,18);
this.add(codeText);
//生成验证码
JLabel code = new JLabel();
code.setBounds(320,245,50,30);
create = arrutil.createCode();
code.setText(create);
System.out.println(create);
this.add(code);
//添加登录按钮
loginButton.setBounds(180,300,50,30);
loginButton.setIcon(new ImageIcon("puzzGame\\image\\login\\loginbutton.png"));
loginButton.addActionListener(this);
this.add(loginButton);
//添加注册按钮
registerButton.setBounds(260,300,50,30);
registerButton.setIcon(new ImageIcon("puzzGame\\image\\login\\registerButton.png"));
registerButton.addActionListener(this);
this.add(registerButton);
//添加背景图片
JLabel backround = new JLabel(new ImageIcon("puzzGame\\image\\register\\background.png"));
backround.setBounds(0,0,470,390);
this.add(backround);
//刷新页面
this.getContentPane().repaint();
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == loginButton){
String username = userText.getText();
String password = passwordText.getText();
String code = codeText.getText();
boolean flag = checkUser(userList, username, password, code);
if (flag){
new GameJFrame();
} else {
arrutil.showJDialog();
initImage();
}
} else if (e.getSource() == registerButton){
new RegisterJFrame();
this.setVisible(false);
System.out.println("注册");
}
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
//判断用户名密码是否正确
public boolean checkUser(ArrayList<User> userList,String username,String password,String code) {
for (int i = 0; i < userList.size(); i++) {
if (username.equals(userList.get(i).getName())) {
System.out.println("用户名正确");
if (password.equals(userList.get(i).getPassword())) {
System.out.println("密码正确");
if (code.equals(create)) {
return true;
}
}
}
}
return false;
}
}
4、游戏界面
分析
- 拼图部分,其实是15张图片,将其改成对应名字,再通过数组的方式打乱,通过事件,再点击键盘的时候,交换索引来实现图片移动
- 查看完整图片功能,就是按A键在页面中找出完整图片
- w键直接胜利,通过对数组排序来实现完成图片
游戏界面代码
GameJFrame.java
package com.lwj.ui;
import com.lwj.util.arrUtil;
import javax.swing.*;
import javax.swing.border.BevelBorder;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
/**
* 游戏界面
*/
public class GameJFrame extends JFrame implements KeyListener , ActionListener {
public GameJFrame(){
//初始化界面
initJFrame();
//初始化菜单
initJMenuBar();
//初始化图片
initImage();
//设置窗体可见
this.setVisible(true);
}
//记录空白方块位置
int x = 0;
int y = 0;
//记录图片路径
String path = "puzzGame\\image\\animal\\animal3\\";
//随机图片记录
String changeimage = "";
String background = "puzzGame\\image\\background.png";
//调用工具类方法,打乱数组
arrUtil arrutil = new arrUtil();
int[][] ints = arrutil.arrChange();
//判断游戏是否胜利标记
boolean flag = false;
//统计步数
int step = 0;
private void initImage() {
//清空原本已经出现的图片
this.getContentPane().removeAll();
flag = arrutil.victory(ints);
if (flag){
//显示胜利图片
JLabel winJLabel = new JLabel(new ImageIcon("puzzGame\\image\\win.png"));
winJLabel.setBounds(203,283,197,73);
this.getContentPane().add(winJLabel);
}
JLabel stepCount = new JLabel("步数"+step);
stepCount.setBounds(50,30,100,20);
this.getContentPane().add(stepCount);
//双重循序添加图片
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
//创建一个图片对象,将数组进行图片循环
ImageIcon icon = new ImageIcon(path+ints[i][j]+".jpg");
//创建Jlabel对象
JLabel jLabel = new JLabel(icon);
//指定图片位置
jLabel.setBounds(105*j+83,105*i+134, 105, 105);
//给图片添加边框
jLabel.setBorder(new BevelBorder(BevelBorder.RAISED));
this.setLayout(null);
this.getContentPane().add(jLabel);
//记录空白方块位置
if (ints[i][j] == 0){
x = i;
y = j;
}
//刷新页面
this.getContentPane().repaint();
}
}
JLabel backround = new JLabel(new ImageIcon(background));
backround.setBounds(40,40,508,560);
this.add(backround);
}
//创建条目对象
JMenuItem replayItem = new JMenuItem("重新游戏");
JMenuItem reLoginItem = new JMenuItem("重新登录");
JMenuItem closeItem = new JMenuItem("关闭游戏");
JMenuItem changeImage = new JMenuItem("切换图片");
JMenuItem accountItem = new JMenuItem("公众号");
private void initJMenuBar() {
/**
* 初始化菜单
* 1、创建整个菜单对象
* 2、创建选项对象
* 3、创建选项条目对象
* 4、组合,将条目对象放在选项中,选项放进菜单
*/
//创建菜单对象
JMenuBar jMenuBar = new JMenuBar();
//创建菜单选项
JMenu functionJMenu = new JMenu("功能");
JMenu aboutJMenu = new JMenu("关于我们");
//条目对象添加进选项
functionJMenu.add(replayItem);
functionJMenu.add(reLoginItem);
functionJMenu.add(changeImage);
functionJMenu.add(closeItem);
aboutJMenu.add(accountItem);
//给条目绑定事件
replayItem.addActionListener(this);
reLoginItem.addActionListener(this);
closeItem.addActionListener(this);
accountItem.addActionListener(this);
changeImage.addActionListener(this);
//菜单选项添加进菜单
jMenuBar.add(functionJMenu);
jMenuBar.add(aboutJMenu);
//设置整个界面
this.setJMenuBar(jMenuBar);
}
private void initJFrame() {
//设置窗体大小
this.setSize(603,680);
//设置界面标题
this.setTitle("拼图单机版");
//设置界面置顶
this.setAlwaysOnTop(true);
//设置窗口居中
this.setLocationRelativeTo(null);
//设置默认关闭模式
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//给整个界面添加键盘监听事件
this.addKeyListener(this);
}
@Override
public void keyTyped(KeyEvent e) {
}
//按下不松调用方法
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == 65){
//把界面中所有图片全部删除
this.getContentPane().removeAll();
//加载完整图片
ImageIcon icon = new ImageIcon(path+"all.jpg");
JLabel jLabel = new JLabel(icon);
jLabel.setBounds(83,134,420,420);
this.setLayout(null);
this.getContentPane().add(jLabel);
//添加背景图片
JLabel backround = new JLabel(new ImageIcon(background));
backround.setBounds(40,40,508,560);
this.add(backround);
//刷新页面
this.getContentPane().repaint();
}
}
@Override
public void keyReleased(KeyEvent e) {
//判断游戏是否胜利,胜利结束该方法
if (flag){
return;
}
/**
*键盘上下左右判断
* 左:37,右:39 上:38,下:40
*/
int code = e.getKeyCode();
if (code == 37){
System.out.println("向左移动");
if (y != 3){
//把空白方块下方的数字赋值给空白方块
ints[x][y] = ints[x][y+1];
ints[x][y+1] = 0;
y++;
//步数增
step++;
//调用方法展示最新数据
initImage();
}
} else if (code == 38){
System.out.println("向上移动");
if (x != 3){
//把空白方块下方的数字赋值给空白方块
ints[x][y] = ints[x+1][y];
ints[x+1][y] = 0;
x++;
//步数增
step++;
//调用方法展示最新数据
initImage();
}
} else if (code == 39){
System.out.println("向右移动");
if (y != 0){
//把空白方块下方的数字赋值给空白方块
ints[x][y] = ints[x][y-1];
ints[x][y-1] = 0;
y--;
//步数增
step++;
//调用方法展示最新数据
initImage();
}
} else if (code == 40){
System.out.println("向下移动");
if (x != 0){
//把空白方块下方的数字赋值给空白方块
ints[x][y] = ints[x-1][y];
ints[x-1][y] = 0;
x--;
//步数增
step++;
//调用方法展示最新数据
initImage();
}
} else if (code == 65){
initImage();
} else if (code == 87){
//按下w键直接获胜
ints = new int[][]{
{
1, 2, 3, 4}, {
5, 6, 7, 8}, {
9, 10, 11, 12}, {
13, 14, 15, 0}};
initImage();
}
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == replayItem){
System.out.println("重新游戏");
//打乱数组数据
ints = arrutil.arrChange();
//计数器清零
step = 0;
//重新加载图
initImage();
} else if (e.getSource() == reLoginItem) {
System.out.println("重新登录");
this.setVisible(false);
new LoginJFrame();
} else if (e.getSource() == closeItem) {
System.out.println("关闭游戏");
//直接停止虚拟机
System.exit(0);
} else if (e.getSource() == accountItem) {
System.out.println("公众号");
//创建弹框对象
JDialog jDialog = new JDialog();
//创建容器对象
JLabel jLabel = new JLabel(new ImageIcon("puzzGame\\image\\my.jpg"));
//设置位置
jLabel.setBounds(0,0,258,258);
jDialog.getContentPane().add(jLabel);
jDialog.setSize(344,344);
//设置置顶居中
jDialog.setAlwaysOnTop(true);
jDialog.setLocationRelativeTo(null);
//弹框不关闭则无法操作页面
jDialog.setModal(true);
jDialog.setVisible(true);
} else if (e.getSource() == changeImage) {
String newPath = arrutil.changePath();
path = "puzzGame\\\\image\\\\"+newPath;
System.out.println(path);
//打乱数组
ints = arrutil.arrChange();
step = 0;
//重新加载图
initImage();
}
}
}
5、注册页面
分析
添加图片、文本框、按钮,通过按钮来实现事件,获取到文本框的文本,再将用户名跟现有的用户进行比对,如果存在则注册失败,不存在再进行二次密码确认,注册成功跳转到登录界面
注册界面代码
RegisterJFrame.java
package com.lwj.ui;
import com.lwj.pojo.User;
import com.lwj.util.arrUtil;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import static com.lwj.ui.LoginJFrame.*;
/**
* 注册界面
*/
public class RegisterJFrame extends JFrame implements ActionListener {
public RegisterJFrame(){
initJFrmae();
initImage();
}
//创建注册用户对象
JTextField registerUsername = new JTextField();
//创建密码输入框对象
JPasswordField passwordText = new JPasswordField();
//创建再次输入密码对象
JPasswordField rePasswordText = new JPasswordField();
//注册对象
JButton registerButton = new JButton();
//重置对象
JButton rebootButton = new JButton();
//添加图片
private void initImage() {
//清空原本已经出现的图片
this.getContentPane().removeAll();
//添加用户图片
JLabel userImage = new JLabel(new ImageIcon("puzzGame\\image\\register\\registername.png"));
userImage.setBounds(125,150,79,17);
this.add(userImage);
//添加用户输入框
registerUsername.setBounds(210,150,100,18);
this.add(registerUsername);
//添加密码图片
JLabel passwordImage = new JLabel(new ImageIcon("puzzGame\\image\\register\\password.png"));
passwordImage.setBounds(130,200,64,16);
this.add(passwordImage);
//添加密码输入框
passwordText.setBounds(210,200,100,18);
this.add(passwordText);
//添加再次密码图片
JLabel repasswordImage = new JLabel(new ImageIcon("puzzGame\\image\\register\\repassowrd.png"));
repasswordImage.setBounds(110,250,96,17);
this.add(repasswordImage);
//添加密码输入框
rePasswordText.setBounds(210,250,100,18);
this.add(rePasswordText);
//添加注册按钮
registerButton.setBounds(180,300,50,30);
registerButton.setIcon(new ImageIcon("puzzGame\\image\\register\\registerbutton.png"));
registerButton.addActionListener(this);
this.add(registerButton);
rebootButton.setBounds(250,300,50,30);
rebootButton.setIcon(new ImageIcon("puzzGame\\image\\register\\rebootButton.png"));
rebootButton.addActionListener(this);
this.add(rebootButton);
//添加背景图片
JLabel backround = new JLabel(new ImageIcon("puzzGame\\image\\register\\background.png"));
backround.setBounds(0,0,470,390);
this.add(backround);
//刷新页面
this.getContentPane().repaint();
}
//初始化窗体
private void initJFrmae() {
//设置窗体大小
this.setSize(480,440);
//设置界面标题
this.setTitle("注册界面");
//设置界面置顶
this.setAlwaysOnTop(true);
//设置窗口居中
this.setLocationRelativeTo(null);
//设置默认关闭模式
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//设置窗体可见
this.setVisible(true);
}
//添加用户
public static boolean addUser(String username,String password,String repassword){
LoginJFrame jF = new LoginJFrame();
ArrayList<User> users = jF.reUser();
for (int i = 0; i < users.size(); i++) {
if (username.equals(users.get(i).getName())){
return false;
}
}
if (!(password.equals(repassword))){
return false;
}
jF.setUser(username,password);
return true;
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == registerButton){
String username = registerUsername.getText();
String password = passwordText.getText();
String repassword = rePasswordText.getText();
boolean flag = addUser(username, password, repassword);
if (flag){
new LoginJFrame();
this.setVisible(false);
} else {
arrUtil util = new arrUtil();
util.showJDialog();
initImage();
}
} else if (e.getSource() == rebootButton){
registerUsername.setText("");
passwordText.setText("");
rePasswordText.setText("");
initImage();
}
}
}
6、启动类
添加main方法启动
import com.lwj.ui.GameJFrame;
import com.lwj.ui.LoginJFrame;
import com.lwj.ui.RegisterJFrame;
public class App {
public static void main(String[] args) {
// 调用登录界面
new LoginJFrame();
//调用游戏界面
// new GameJFrame();
//调用注册界面
// new RegisterJFrame();
}
}