核心功能
- 用户模块: 用户注册, 用户登录, 用户天梯分数记录, 用户比赛场次记录.
- 匹配模块: 按照用户的天梯分数实现匹配机制.
- 对战模块: 实现两个玩家在网页端进行五子棋对战的功能.
核心技术
- Spring/SpringBoot/SpringMVC
- WebSocket
- MySQL
- MyBatis
- HTML/CSS/JS/AJAX
项目演示
进入注册页面
输入用户名和密码之后点击提交就会跳转到登录页面
输入用户名和密码后点击提交进入游戏大厅页面
点击开始匹配后系统会根据你的分数为你匹配实力相当的对手
匹配成功后两名玩家进入游戏房间
根据先手方先落子,后手方后落子。棋盘上都会展示双方落子的位置情况
当某一方达成行、列、对角线成五子时则获胜,界面中会显示你是获胜方还是失败方
点击回到大厅,发现此时的用户信息也得到了及时的更新
实现用户模块
数据库设计
创建java_gobang数据库,并创建一张user表来表示用户信息
create database if not exists java_gobang; use java_gobang; drop table if exists user; create table user ( userId int primary key auto_increment, username varchar(50) unique, password varchar(50), score int, -- 天梯积分 totalCount int, -- 比赛总场数 winCount int -- 获胜场数 ); --为了测试方便,先往里面插入三个用户数据 insert into user values(null, 'zhangsan', '123', 1000, 0, 0); insert into user values(null, 'lisi', '123', 1000, 0, 0); insert into user values(null, 'wangwu', '123', 1000, 0, 0);
配置MyBatis
编辑application.yml
# 配置数据库的连接字符串 spring: datasource: url: jdbc:mysql://127.0.0.1/java_gobang?characterEncoding=utf8 username: root password: 111111 driver-class-name: com.mysql.cj.jdbc.Driver # 设置 Mybatis 的 xml 保存路径 mybatis: mapper-locations: classpath:mapper/**Mapper.xml configuration: # 配置打印 MyBatis 执行的 SQL log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 配置打印 MyBatis 执行的 SQL logging: level: com: example: demo: debug
创建实体类
创建User类
@Data public class User { private int userId; private String username; private String password; private int score; private int totalCount; private int winCount; }
创建UserMapper
给UserMapper中加入4个方法
@Mapper public interface UserMapper { /** * 往数据库中进行插入数据,进行注册功能 * @param user */ void insert(User user); /** * 根据用户名查询用户信息,登录功能 * @param username * @return */ User selectByName(String username); /** * 给获胜玩家修改分数 * 总比赛场次 + 1, 获胜场数 + 1, 天梯分数 + 30 * @param userId */ void userWin(int userId); /** * 给失败玩家修改分数 * 总比赛场数 + 1, 获胜场数 不变, 天梯分数 - 30 * @param userId */ void userLose(int userId); }
实现UserMapper.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.java_gobang.mapper.UserMapper"> <insert id="insert"> insert into user values(null, #{username}, #{password}, 1000, 0, 0) </insert> <select id="selectByName" resultType="com.example.java_gobang.model.User"> select * from user where username = #{username} </select> <update id="userWin"> update user set totalCount = totalCount + 1, winCount = winCount + 1, score = score + 30 where userId = #{userId} </update> <update id="userLose"> update user set totalCount = totalCount + 1, score = score - 30 where userId = #{userId} </update> </mapper>
设计前后端交互接口
登录交互接口
请求: { POST /login HTTP/1.1 Content-Type: application/x-www-form-urlencoded username=zhangsan&password=123 } 响应: { HTTP/1.1 200 OK Content-Type: application/json { userId: 1, username: 'zhangsan', score: 1000, totalCount: 10, winCount: 5 } }
注册交互接口
请求: { POST /register HTTP/1.1 Content-Type: application/x-www-form-urlencoded username=zhangsan&password=123 } 响应: { HTTP/1.1 200 OK Content-Type: application/json { userId: 1, username: 'zhangsan', score: 1000, totalCount: 10, winCount: 5 } }
获取用户信息
请求: { GET /userInfo HTTP/1.1 } 响应: { HTTP/1.1 200 OK Content-Type: application/json { userId: 1, username: 'zhangsan', score: 1000, totalCount: 10, winCount: 5 } }
服务器开发
创建一个api包,在包中创建UserAPI类
在类中添加三个方法,主要用来实现登录注册和获取用户信息
@RestController public class UserAPI { @Autowired private UserMapper userMapper; /** * 实现登录请求 * @param username * @param password * @param request * @return */ @RequestMapping("/login") public Object login(String username, String password, HttpServletRequest request) { // 去数据库中查询user User user = userMapper.selectByName(username); if(user == null || !user.getPassword().equals(password)) { // 登录失败 System.out.println("登陆失败"); return new User(); } // 将user对象存入会话中 HttpSession session = request.getSession(true); session.setAttribute("user", user); return user; } /** * 实现注册请求 * @param username * @param password * @return */ @RequestMapping("/register") public Object register(String username, String password) { try{ User user = new User(); user.setUsername(username); user.setPassword(password); // 将user对象存入数据库中 userMapper.insert(user); return user; }catch (org.springframework.dao.DuplicateKeyException e) { return new User(); } } /** * 实现查询用户信息请求 * @param request * @return */ @RequestMapping("/userInfo") public Object getUserInfo(HttpServletRequest request) { try { HttpSession session = request.getSession(false); User user = (User) session.getAttribute("user"); User newUser = userMapper.selectByName(user.getUsername()); return newUser; }catch (NullPointerException e) { return new User(); } } }
客户端开发
登陆页面
创建login.html
通过 jQuery 中的 AJAX 和服务器进行交互
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>登录</title> <link rel="stylesheet" href="css/common.css"> <link rel="stylesheet" href="css/login.css"> </head> <body> <div class="nav"> 五子棋对战 </div> <div class="login-container"> <!-- 登录界面的对话框 --> <div class="login-dialog"> <!-- 提示信息 --> <h3>登录</h3> <!-- 这个表示一行 --> <div class="row"> <span>用户名</span> <input type="text" id="username"> </div> <!-- 这是另一行 --> <div class="row"> <span>密码</span> <input type="password" id="password"> </div> <!-- 提交按钮 --> <div class="row"> <button id="submit">提交</button> </div> </div> </div> <script src="./js/jquery.min.js"></script> <script> let usernameInput = document.querySelector('#username'); let passwordInput = document.querySelector('#password'); let submitButton = document.querySelector('#submit'); submitButton.onclick = function() { $.ajax({ type: 'post', url: '/login', data: { username: usernameInput.value, password: passwordInput.value, }, success: function(body) { // 请求执行成功之后的回调函数 // 判定当前是否登录成功~ // 如果登录成功, 服务器会返回当前的 User 对象. // 如果登录失败, 服务器会返回一个空的 User 对象. if (body && body.userId > 0) { // 登录成功 alert("登录成功!"); // 重定向跳转到 "游戏大厅页面". location.assign('/game_hall.html'); } else { alert("登录失败!"); } }, error: function() { // 请求执行失败之后的回调函数 alert("登录失败!"); } }); } </script> </body> </html>
创建 css/common.css
/* 公共的样式 */ * { margin: 0; padding: 0; box-sizing: border-box; } html, body { height: 100%; background-image: url(../image/bcg.jpg); background-repeat: no-repeat; background-position: center; background-size: cover; } .nav { height: 50px; background-color: rgb(50, 50, 50); color: white; line-height: 50px; padding-left: 20px; } .container { width: 100%; height: calc(100% - 50px); display: flex; align-items: center; justify-content: center; }
创建 css/login.css
.login-container { height: calc(100% - 50px); display: flex; justify-content: center; align-items: center; } .login-dialog { width: 400px; height: 400px; background-color: rgba(255, 255, 255, 0.8); border-radius: 10px; } /* 标题 */ .login-dialog h3 { text-align: center; padding: 50px 0; } /* 针对一行设置样式 */ .login-dialog .row { width: 100%; height: 50px; display: flex; align-items: center; justify-content: center; } .login-dialog .row span { width: 100px; font-weight: 700; } #username, #password { width: 200px; height: 40px; font-size: 20px; line-height: 40px; padding-left: 10px; border: none; outline: none; border-radius: 10px; } #submit { width: 300px; height: 50px; background-color: rgb(0, 128, 0); color: white; border: none; outline: none; border-radius: 10px; margin-top: 20px; } #submit:active { background-color: #666; }
注册页面
创建 register.html
同样通过 jQuery 中的 AJAX 和服务器进行交互
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>注册</title> <link rel="stylesheet" href="css/common.css">