登录类
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.util.Random;
import java.net.URL;
//登录界面
public class LoginFrame extends JFrame implements ActionListener, MouseListener {
//随机生成验证码
String code = vtfcode();
//验证码组件
private JLabel VTF_code = new JLabel(code);
//登录和注册组件
private JButton login = new JButton(new ImageIcon("image\\login\\登录按钮.png"));
private JButton register = new JButton(new ImageIcon("image\\login\\注册按钮.png"));
//用户名和密码文本框
private JTextField username = new JTextField();
private JTextField password = new JTextField();
//验证码文本框
JTextField VTF_text = new JTextField();
//记录用户名
private String account;
//验证码错误弹窗
private JDialog dialog = new JDialog();
public LoginFrame() {
//绑定监听器
login.addActionListener(this);
VTF_code.addMouseListener(this);
register.addActionListener(this);
//初始化界面
InitJframe();
//初始化图片
InitImage();
setVisible(true);
}
//验证码弹窗
private void InitJDialog() {
dialog.setSize(100, 100);
dialog.setModal(true);
dialog.setLocationRelativeTo(null);
dialog.add(new JLabel("验证码错误!", SwingConstants.CENTER));
dialog.setVisible(true);
dialog.setAlwaysOnTop(true);
}
//初始化图片
private void InitImage() {
this.getContentPane().removeAll();
//添加用户名组件
JLabel UserName = new JLabel(new ImageIcon("image\\login\\用户名.png"));
UserName.setBounds(116, 135, 51, 19);
username.setBounds(195, 136, 200, 20);
this.getContentPane().add(username);
this.getContentPane().add(UserName);
//添加密码组件
JLabel PassWord = new JLabel(new ImageIcon("image\\login\\密码.png"));
PassWord.setBounds(130, 195, 35, 18);
password.setBounds(195, 196, 200, 20);
this.getContentPane().add(password);
this.getContentPane().add(PassWord);
//添加验证码组件
JLabel VTF_image = new JLabel(new ImageIcon("image\\login\\验证码.png"));
VTF_image.setBounds(116, 255, 56, 21);
VTF_text.setBounds(195, 256, 100, 20);
VTF_code.setBounds(300, 255, 50, 20);
this.getContentPane().add(VTF_text);
this.getContentPane().add(VTF_image);
this.getContentPane().add(VTF_code);
//添加登录和注册组件
login.setBounds(133, 290, 90, 40);
register.setBounds(280, 290, 90, 40);
this.getContentPane().add(login);
this.getContentPane().add(register);
//添加背景图片
JLabel background = new JLabel(new ImageIcon("image\\login\\background.png"));
background.setBounds(0, 0, 470, 390);
this.getContentPane().add(background);
//刷新界面
getContentPane().repaint();
}
//初始化界面
private void InitJframe() {
setSize(488, 430);
//设置界面的标题
setTitle("拼图小游戏登录界面");
//设置界面置顶
//setAlwaysOnTop(true);
//设置窗口不可拉伸
setResizable(false);
//设置界面居中显示
setLocationRelativeTo(null);
//设置关闭模式
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//取消默认的居中放置,取消之后才会按照x,y坐标放置图片
setLayout(null);
}
//生成随机验证码
public static String vtfcode() {
char[] code = new char[5];
Random rand = new Random();
for (int i = 0; i < 4; i++) {
int flag = rand.nextInt(2);
if (flag == 0) {
int num = rand.nextInt(26) + 65;
code[i] = (char) num;
} else if (flag == 1) {
int num = rand.nextInt(26) + 97;
code[i] = (char) num;
}
}
int num = rand.nextInt(10) + 48;
code[4] = (char) num;
for (int i = 4; i >= 0; i--) {
int number = rand.nextInt(i + 1);
char temp = code[number];
code[number] = code[i];
code[i] = temp;
}
return new String(code);
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public JLabel getVTF_code() {
return VTF_code;
}
public void setVTF_code(JLabel VTF_code) {
this.VTF_code = VTF_code;
}
public JButton getLogin() {
return login;
}
public void setLogin(JButton login) {
this.login = login;
}
public JButton getRegister() {
return register;
}
public void setRegister(JButton register) {
this.register = register;
}
public JTextField getUsername() {
return username;
}
public void setUsername(JTextField username) {
this.username = username;
}
public JTextField getPassword() {
return password;
}
public void setPassword(JTextField password) {
this.password = password;
}
public JTextField getVTF_text() {
return VTF_text;
}
public void setVTF_text(JTextField VTF_text) {
this.VTF_text = VTF_text;
}
//监听普通点击事件
@Override
public void actionPerformed(ActionEvent e) {
Object obj = e.getSource();
if (obj == login) {
String temp = VTF_text.getText();
System.out.println("登录被点击了");
System.out.println(code);
if (temp.equals(code)) {
System.out.println("验证码正确");
if (sendLoginRequest()) {
new GameJFrame(account);
setVisible(false);
}
} else {
InitJDialog();
System.out.println("验证码错误");
char_code();
}
} else if (obj == register) {
String temp = VTF_text.getText();
System.out.println("注册被点击了");
System.out.println(code);
if (temp.equals(code)) {
System.out.println("验证码正确");
sendRegisterRequest();
} else {
InitJDialog();
System.out.println("验证码错误");
char_code();
}
}
}
//向服务器发送注册信息
public boolean sendLoginRequest() {
System.out.println("登录被调用了");
String un = username.getText();
account = un;
String pw = password.getText();
try {
URL url = new URL("http://47.94.222.194:5000/login");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);
String jsonInput = String.format(
"{\"username\":\"%s\", \"password\":\"%s\"}", un, pw
);
try (OutputStream os = conn.getOutputStream()) {
byte[] input = jsonInput.getBytes("utf-8");
os.write(input, 0, input.length);
}
try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"))) {
StringBuilder response = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
response.append(line.trim());
}
String respStr = response.toString();
String status = null;
int statusIndex = respStr.indexOf("\"status\"");
if (statusIndex != -1) {
int colonIndex = respStr.indexOf(":", statusIndex);
int startQuote = respStr.indexOf("\"", colonIndex);
int endQuote = respStr.indexOf("\"", startQuote + 1);
if (startQuote != -1 && endQuote != -1) {
status = respStr.substring(startQuote + 1, endQuote);
}
}
if ("success".equalsIgnoreCase(status)) {
JOptionPane.showMessageDialog(this, "登录成功");
return true;
} else if ("fail".equalsIgnoreCase(status)) {
JOptionPane.showMessageDialog(this, "登录失败,用户名或密码错误!");
return false;
} else {
JOptionPane.showMessageDialog(this, "未知响应:" + respStr);
return false;
}
}
} catch (Exception ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(this, "请求异常:" + ex.getMessage());
return false;
}
}
//向服务器发送注册信息
public void sendRegisterRequest() {
String un = username.getText();
String pw = password.getText();
try {
URL url = new URL("http://47.94.222.194:5000/register");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);
String jsonInput = String.format(
"{\"username\":\"%s\", \"password\":\"%s\"}", un, pw
);
try (OutputStream os = conn.getOutputStream()) {
byte[] input = jsonInput.getBytes("utf-8");
os.write(input, 0, input.length);
}
try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"))) {
StringBuilder response = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
response.append(line.trim());
}
String respStr = response.toString();
String status = null;
int statusIndex = respStr.indexOf("\"status\"");
if (statusIndex != -1) {
int colonIndex = respStr.indexOf(":", statusIndex);
int startQuote = respStr.indexOf("\"", colonIndex);
int endQuote = respStr.indexOf("\"", startQuote + 1);
if (startQuote != -1 && endQuote != -1) {
status = respStr.substring(startQuote + 1, endQuote);
}
}
if ("success".equalsIgnoreCase(status)) {
JOptionPane.showMessageDialog(this, "注册成功");
} else if ("fail".equalsIgnoreCase(status)) {
JOptionPane.showMessageDialog(this, "注册失败,用户名已存在!");
} else {
JOptionPane.showMessageDialog(this, "未知响应:" + respStr);
}
}
} catch (Exception ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(this, "请求异常:" + ex.getMessage());
}
}
//鼠标点击事件
@Override
public void mouseClicked(MouseEvent e) {
Object obj = e.getSource();
if (obj == VTF_code) {
System.out.println("更换验证码");
char_code();
System.out.println(code);
}
}
private void char_code() {
code = vtfcode();
VTF_code.setText(code);
InitImage();
}
//按下鼠标事件
@Override
public void mousePressed(MouseEvent e) {
}
//松开鼠标事件
@Override
public void mouseReleased(MouseEvent e) {
}
//移入鼠标事件
@Override
public void mouseEntered(MouseEvent e) {
}
//移除鼠标事件
@Override
public void mouseExited(MouseEvent e) {
}
}
游戏类
import javax.swing.*;
import javax.swing.border.BevelBorder;
import java.awt.*;
import java.awt.event.*;
import java.net.URI;
import java.util.Random;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
//游戏的主界面
public class GameJFrame extends JFrame implements KeyListener, ActionListener {
//记录所有图片的索引
private int[][] Array = {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}, {12, 13, 14, 15}};
//记录空白的坐标
private int x = 0, y = 0;
//记录图片的路径
private String path = "image\\animal\\animal3\\";
//记录走的步数
private int step = 0;
//创建选项下面的条目对象
private JMenuItem replayItem = new JMenuItem("重新游戏");
private JMenuItem closeItem = new JMenuItem("关闭游戏");
private JMenuItem accountItem = new JMenuItem("主播粉丝群");
private JMenuItem blogItem = new JMenuItem("主播博客");
private JMenuItem girl = new JMenuItem("美女");
private JMenuItem animal = new JMenuItem("动物");
private JMenuItem sport = new JMenuItem("运动");
Random rand = new Random();
private String account;
public GameJFrame(String account) {
this.account = account;
//初始化窗口
InitJframe();
//初始化菜单
InitMenu();
//初始化数据
InitData();
//初始化图片
InitImage();
//让界面显示出来,写在最后
setVisible(true);
}
//实现打乱图片的效果
public void InitData() {
//初始化一维数组
int[] tempArr = new int[16];
for (int i = 0; i < tempArr.length; i++) {
tempArr[i] = i;
}
while (true) {
//Fisher–Yates 洗牌算法打乱数组
for (int i = tempArr.length - 1; i >= 0; i--) {
int index = rand.nextInt(i + 1);
int temp = tempArr[index];
tempArr[index] = tempArr[i];
tempArr[i] = temp;
}
//计算逆序数和0所在的行,保证游戏有解
int temp_count = 0;
for (int i = 0; i < tempArr.length; i++) {
if (tempArr[i] == 0) {
continue;
}
for (int j = i + 1; j < tempArr.length; j++) {
if (tempArr[j] == 0) {
continue;
}
if (tempArr[i] > tempArr[j]) {
temp_count++;
}
}
}
//将一维数组的数据转移到4X4的二维数组
for (int i = 0; i < tempArr.length; i++) {
if (tempArr[i] == 0) {
x = i / 4;
y = i % 4;
}
Array[i / 4][i % 4] = tempArr[i];
System.out.print(tempArr[i] + ",");
}
System.out.println();
temp_count += (4 - x);
if (temp_count % 2 == 0) {
break;
}
}
}
public void InitImage() {
//清空之前存在的元素
this.getContentPane().removeAll();
//判断是否胜利,添加胜利图片
if (victory()) {
JLabel win_picture = new JLabel(new ImageIcon(".\\image\\win.png"));
win_picture.setBounds(203, 283, 197, 73);
getContentPane().add(win_picture);
sendStepUpdate(account,step);
}
//添加步数信息
JLabel step_count = new JLabel("步数:" + step);
step_count.setBounds(50, 30, 100, 20);
getContentPane().add(step_count);
//添加游戏图片
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
int num = Array[i][j];
//获取图片的url
String url = path + num + ".jpg";
//创建一个图片imageIcaon对象
ImageIcon icon = new ImageIcon(url);
//创建一个JLable对象(管理容器)
JLabel jl = new JLabel(icon);
//指定图片位置
jl.setBounds(105 * j + 83, 105 * i + 134, 105, 105);
//给图片添加边框
//0代表图片凸起来
//1代表图片凹下去
jl.setBorder(new BevelBorder(1));
//把管理容器添加到界面
getContentPane().add(jl);
}
}
//添加背景图片
ImageIcon bg = new ImageIcon(".\\image\\background.png");
JLabel background = new JLabel(bg);
background.setBounds(40, 40, 508, 560);
getContentPane().add(background);
//刷新界面
getContentPane().repaint();
}
public void InitJframe() {
//设置界面的宽和高
setSize(603, 680);
//设置界面的标题
setTitle("拼图游戏联机版 V2.5");
//设置界面置顶
setAlwaysOnTop(true);
//设置窗口不可拉伸
setResizable(false);
//设置界面居中显示
setLocationRelativeTo(null);
//设置关闭模式
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//取消默认的居中放置,取消之后才会按照x,y坐标放置图片
setLayout(null);
//添加键盘监听事件
addKeyListener(this);
}
public void sendStepUpdate(String username, int step) {
try {
URL url = new URL("http://47.94.222.194:5000/update");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);
// 构建 JSON 字符串
String jsonInput = String.format(
"{\"username\":\"%s\", \"step\":%d}", username, step
);
// 发送请求体
try (OutputStream os = conn.getOutputStream()) {
byte[] input = jsonInput.getBytes("utf-8");
os.write(input, 0, input.length);
}
// 可选:读取响应(你说不需要看结果的话可以省略这部分)
conn.getInputStream().close(); // 保证连接完整释放
} catch (Exception e) {
e.printStackTrace();
}
}
public void InitMenu() {
//初始化菜单
//创建整个的菜单对象
JMenuBar menuBar = new JMenuBar();
//创建菜单上的两个选项的对象(功能,关于我们)
JMenu functionJmenu = new JMenu("功能");
JMenu aboutJmenu = new JMenu("关于作者");
JMenu charge = new JMenu("更换图片");
//将每一个选项下面的条目添加到选项当中
functionJmenu.add(charge);
functionJmenu.add(replayItem);
functionJmenu.add(closeItem);
aboutJmenu.add(accountItem);
aboutJmenu.add(blogItem);
//charge.add(girl);
charge.add(animal);
//charge.add(sport);
//给条目绑定事件
girl.addActionListener(this);
animal.addActionListener(this);
sport.addActionListener(this);
replayItem.addActionListener(this);
closeItem.addActionListener(this);
accountItem.addActionListener(this);
blogItem.addActionListener(this);
//将两个选项添加到菜单里
menuBar.add(functionJmenu);
menuBar.add(aboutJmenu);
//将菜单添加到整个界面
setJMenuBar(menuBar);
}
@Override
public void keyTyped(KeyEvent e) {
}
//按下不松调用的方法
@Override
public void keyPressed(KeyEvent e) {
//游戏结束不能进行其他操作
if (victory()) {
return;
}
int code = e.getKeyCode();
if (code == 65) {
//删除全部图片
this.getContentPane().removeAll();
//加载完整的图片
JLabel all = new JLabel(new ImageIcon(path + "all.jpg"));
all.setBounds(83, 134, 420, 420);
this.getContentPane().add(all);
//加载背景图片
ImageIcon bg = new ImageIcon(".\\image\\background.png");
JLabel background = new JLabel(bg);
background.setBounds(40, 40, 508, 560);
getContentPane().add(background);
//刷新界面
getContentPane().repaint();
}
}
//按下松开后调用的方法
@Override
public void keyReleased(KeyEvent e) {
//游戏结束不能再进行其他操作
if (victory()) {
return;
}
int code = e.getKeyCode();
//左37,上38,右39,下40
if (code == 37) {
if (y + 1 < 4) {
Array[x][y] = Array[x][y + 1];
Array[x][y + 1] = 0;
y++;
step++;
InitImage();
System.out.println("向左移动");
} else {
System.out.println("向左移动失败");
}
} else if (code == 38) {
if (x + 1 < 4) {
Array[x][y] = Array[x + 1][y];
Array[x + 1][y] = 0;
x++;
step++;
InitImage();
System.out.println("向上移动");
} else {
System.out.println("向上移动失败");
}
} else if (code == 39) {
if (y - 1 >= 0) {
Array[x][y] = Array[x][y - 1];
Array[x][y - 1] = 0;
y--;
step++;
InitImage();
System.out.println("向右移动");
} else {
System.out.println("向右移动失败");
}
} else if (code == 40) {
if (x - 1 >= 0) {
Array[x][y] = Array[x - 1][y];
Array[x - 1][y] = 0;
x--;
step++;
InitImage();
System.out.println("向下移动");
} else {
System.out.println("向下移动失败");
}
} else if (code == 65) {
InitImage();
} else if (code == 80) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
Array[i][j] = i * 4 + j + 1;
}
}
Array[3][3] = 0;
InitImage();
}
}
//判断是否胜利
public boolean victory() {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (i == 3 && j == 3) {
continue;
}
if (Array[i][j] != i * 4 + j + 1) {
return false;
}
}
}
return true;
}
//鼠标点击事件
@Override
public void actionPerformed(ActionEvent e) {
Object obj = e.getSource();
if (obj == replayItem) {
step = 0;
InitData();
InitImage();
System.out.println("重新游戏");
} else if (obj == closeItem) {
System.exit(0);
System.out.println("关闭游戏");
} else if (obj == accountItem) {
try {
Desktop desktop = Desktop.getDesktop();
desktop.browse(new URI("https://qm.qq.com/q/dgv5awkpDG"));
} catch (Exception ex) {
ex.printStackTrace();
}
System.out.println("粉丝群");
} else if (obj == blogItem) {
try {
Desktop desktop = Desktop.getDesktop();
desktop.browse(new URI("https://homeofmjr.top"));
} catch (Exception ex) {
ex.printStackTrace();
}
System.out.println("博客");
} else if (obj == girl) {
int number = rand.nextInt(11) + 1;
path = "image\\girl\\girl" + number + "\\";
step = 0;
InitData();
InitImage();
System.out.println("美女图片");
} else if (obj == animal) {
int number = rand.nextInt(8) + 1;
path = "image\\animal\\animal" + number + "\\";
step = 0;
InitData();
InitImage();
System.out.println("动物图片");
} else if (obj == sport) {
int number = rand.nextInt(10) + 1;
path = "image\\sport\\sport" + number + "\\";
step = 0;
InitData();
InitImage();
System.out.println("运动图片");
}
}
}
主入口
public class App {
public static void main(String[] args) {
new LoginFrame();
}
}
python的flask框架做的后端
import files
from flask import Flask,request,jsonify
app=Flask(__name__)
@app.route("/register",methods=['POST'])
def register():
data=request.json
username=data.get('username')
password=data.get('password')
if files.register(username,password):
print(f"接受到的信息:{username},{password}")
return jsonify({"status":"success","message":"注册成功"})
else:
print(f"接受到的信息:{username},{password}")
return jsonify({"status":"fail","message":"用户名已经存在!"})
@app.route("/login",methods=['POST'])
def login():
data=request.json
username=data.get('username')
password=data.get('password')
if files.login(username,password):
print(f"接受到的信息:{username},{password}")
return jsonify({"status":"success","message":"登录成功"})
else:
print(f"接受到的信息:{username},{password}")
return jsonify({"status":"fail","message":"登录失败"})
@app.route("/update", methods=["POST"])
def update():
data = request.json
print(data)
username = data.get("username")
step = data.get("step")
print(f"接收到上传数据:用户名 = {username}, 步数 = {step}")
if not isinstance(step, int) or not username:
return jsonify({"status": "fail", "message": "无效的参数"})
try:
success = files.updata(step, username)
if success:
return jsonify({"status": "success", "message": "上传成功"})
else:
return jsonify({"status": "fail", "message": "更新失败"})
except Exception as e:
return jsonify({"status": "fail", "message": f"发生错误:{str(e)}"})
@app.route("/")
def home():
return """
<html>
<head><title>Flask 服务测试</title></head>
<body>
<h1>Flask 服务已启动!</h1>
<p>这里是首页,接口可以用 POST 请求测试。</p>
</body>
</html>
"""
app.run(host="0.0.0.0",port=5000)
然后处理java发送的json的python模块
import json
def register(username,password):
try:
with open("data.json","r",encoding="utf-8") as file:
users=json.load(file)
except (FileNotFoundError,json.JSONDecodeError):
users={}
with open("data.json","w",encoding="utf-8") as file:
json.dump(users,file)
for i in users:
if i==username:
return False
new_user=username
users[new_user]= {
"password":password,
"play_count":0,
"total_steps":0,
"average_steps":0,
}
with open("data.json","w",encoding="utf-8") as file:
json.dump(users,file,indent=4,ensure_ascii=False)
return True
def login(username,password):
try:
with open("data.json", "r", encoding="utf-8") as file:
users = json.load(file)
except (FileNotFoundError, json.JSONDecodeError):
users = {}
with open("data.json", "w", encoding="utf-8") as file:
json.dump(users, file)
for i in users:
if i==username:
if users[i]['password']==password:
return True
return False
def updata(step,username):
try:
with open("data.json", "r", encoding="utf-8") as file:
users = json.load(file)
except (FileNotFoundError, json.JSONDecodeError):
users = {}
with open("data.json", "w", encoding="utf-8") as file:
json.dump(users, file)
users[username]['total_steps']+=step
users[username]['play_count']+=1
with open("data.json","w",encoding="utf-8") as file:
json.dump(users,file,indent=4,ensure_ascii=False)
return True
评论区