实现游戏数据到数据库的存储
This commit is contained in:
parent
069a207b23
commit
d1bc4c1ba4
|
@ -5,6 +5,7 @@ package com.kob.backend.consumer;
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.kob.backend.consumer.utils.Game;
|
import com.kob.backend.consumer.utils.Game;
|
||||||
import com.kob.backend.consumer.utils.JwtAuthenticationUtil;
|
import com.kob.backend.consumer.utils.JwtAuthenticationUtil;
|
||||||
|
import com.kob.backend.mapper.RecordMapper;
|
||||||
import com.kob.backend.mapper.UserMapper;
|
import com.kob.backend.mapper.UserMapper;
|
||||||
import com.kob.backend.pojo.User;
|
import com.kob.backend.pojo.User;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -32,6 +33,8 @@ public class WebSocketServer {
|
||||||
private static final CopyOnWriteArraySet<User> matchPool = new CopyOnWriteArraySet<>();
|
private static final CopyOnWriteArraySet<User> matchPool = new CopyOnWriteArraySet<>();
|
||||||
// 在 WebSocketServer 中注入数据库的方法演示-> 使用 static 定义为独一份的变量
|
// 在 WebSocketServer 中注入数据库的方法演示-> 使用 static 定义为独一份的变量
|
||||||
private static UserMapper userMapper;
|
private static UserMapper userMapper;
|
||||||
|
// 注入 RecordMapper 用于调用实现游戏数据到数据库的存储
|
||||||
|
public static RecordMapper recordMapper;
|
||||||
// 后端向前端发送信息,首先需要创建一个 session
|
// 后端向前端发送信息,首先需要创建一个 session
|
||||||
private Session session = null;
|
private Session session = null;
|
||||||
// 用户信息:定义一个成员变量
|
// 用户信息:定义一个成员变量
|
||||||
|
@ -45,6 +48,11 @@ public class WebSocketServer {
|
||||||
WebSocketServer.userMapper = userMapper;
|
WebSocketServer.userMapper = userMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public void setRecordMapper(RecordMapper recordMapper) {
|
||||||
|
WebSocketServer.recordMapper = recordMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// @OnOpen 创建链接时自动触发这个函数
|
// @OnOpen 创建链接时自动触发这个函数
|
||||||
@OnOpen
|
@OnOpen
|
||||||
|
@ -91,7 +99,7 @@ public class WebSocketServer {
|
||||||
System.out.println("start matching");
|
System.out.println("start matching");
|
||||||
matchPool.add(this.user);
|
matchPool.add(this.user);
|
||||||
|
|
||||||
while (matchPool.size()>=2){
|
while (matchPool.size() >= 2) {
|
||||||
// 迭代器用于枚举前两个人进行匹配
|
// 迭代器用于枚举前两个人进行匹配
|
||||||
Iterator<User> it = matchPool.iterator();
|
Iterator<User> it = matchPool.iterator();
|
||||||
User a = it.next(), b = it.next();
|
User a = it.next(), b = it.next();
|
||||||
|
@ -100,7 +108,7 @@ public class WebSocketServer {
|
||||||
matchPool.remove(b);
|
matchPool.remove(b);
|
||||||
|
|
||||||
// 匹配成功时,创建联机地图
|
// 匹配成功时,创建联机地图
|
||||||
Game game = new Game(13,14,20,a.getId(),b.getId());
|
Game game = new Game(13, 14, 20, a.getId(), b.getId());
|
||||||
game.createMap(); // 初始化地图
|
game.createMap(); // 初始化地图
|
||||||
users.get(a.getId()).game = game; // 将 game 赋给 a 玩家
|
users.get(a.getId()).game = game; // 将 game 赋给 a 玩家
|
||||||
users.get(b.getId()).game = game;
|
users.get(b.getId()).game = game;
|
||||||
|
@ -108,32 +116,32 @@ public class WebSocketServer {
|
||||||
game.start(); // 开启新线程,执行函数
|
game.start(); // 开启新线程,执行函数
|
||||||
|
|
||||||
JSONObject respGameData = new JSONObject();
|
JSONObject respGameData = new JSONObject();
|
||||||
respGameData.put("game_map",game.getG());
|
respGameData.put("game_map", game.getG());
|
||||||
respGameData.put("rows",game.getRows());
|
respGameData.put("rows", game.getRows());
|
||||||
respGameData.put("cols",game.getCols());
|
respGameData.put("cols", game.getCols());
|
||||||
respGameData.put("inner_walls_count",game.getInnerWallsCount());
|
respGameData.put("inner_walls_count", game.getInnerWallsCount());
|
||||||
respGameData.put("a_id",game.getPlayerA().getId());
|
respGameData.put("a_id", game.getPlayerA().getId());
|
||||||
respGameData.put("a_sx",game.getPlayerA().getSx());
|
respGameData.put("a_sx", game.getPlayerA().getSx());
|
||||||
respGameData.put("a_sy",game.getPlayerA().getSy());
|
respGameData.put("a_sy", game.getPlayerA().getSy());
|
||||||
respGameData.put("b_id",game.getPlayerB().getId());
|
respGameData.put("b_id", game.getPlayerB().getId());
|
||||||
respGameData.put("b_sx",game.getPlayerB().getSx());
|
respGameData.put("b_sx", game.getPlayerB().getSx());
|
||||||
respGameData.put("b_sy",game.getPlayerB().getSy());
|
respGameData.put("b_sy", game.getPlayerB().getSy());
|
||||||
|
|
||||||
// 将 a 配对成功的消息传回客户端
|
// 将 a 配对成功的消息传回客户端
|
||||||
JSONObject respA = new JSONObject();
|
JSONObject respA = new JSONObject();
|
||||||
respA.put("event","start-matching");
|
respA.put("event", "start-matching");
|
||||||
respA.put("opponent_username",b.getUsername());
|
respA.put("opponent_username", b.getUsername());
|
||||||
respA.put("opponent_photo",b.getPhoto());
|
respA.put("opponent_photo", b.getPhoto());
|
||||||
respA.put("game_data",respGameData);
|
respA.put("game_data", respGameData);
|
||||||
// 获取 a 的链接,并通过 sendMessage 将消息传给前端
|
// 获取 a 的链接,并通过 sendMessage 将消息传给前端
|
||||||
users.get(a.getId()).sendMessage(respA.toJSONString());
|
users.get(a.getId()).sendMessage(respA.toJSONString());
|
||||||
|
|
||||||
// 同理,将 b 的匹配成功信息传回给前端
|
// 同理,将 b 的匹配成功信息传回给前端
|
||||||
JSONObject respB = new JSONObject();
|
JSONObject respB = new JSONObject();
|
||||||
respB.put("event","start-matching");
|
respB.put("event", "start-matching");
|
||||||
respB.put("opponent_username",a.getUsername());
|
respB.put("opponent_username", a.getUsername());
|
||||||
respB.put("opponent_photo",a.getPhoto());
|
respB.put("opponent_photo", a.getPhoto());
|
||||||
respB.put("game_data",respGameData);
|
respB.put("game_data", respGameData);
|
||||||
users.get(b.getId()).sendMessage(respB.toJSONString());
|
users.get(b.getId()).sendMessage(respB.toJSONString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,13 +153,12 @@ public class WebSocketServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
// direction 传入 move(移动) 方向参数
|
// direction 传入 move(移动) 方向参数
|
||||||
private void move(int direction){
|
private void move(int direction) {
|
||||||
// 判断角色:如果是 A 角色,则将获取到的方向设置为 A 的 nextStep 方向
|
// 判断角色:如果是 A 角色,则将获取到的方向设置为 A 的 nextStep 方向
|
||||||
// user.getId() 是获取当前链接的用户 id
|
// user.getId() 是获取当前链接的用户 id
|
||||||
if(game.getPlayerA().getId().equals(user.getId())){
|
if (game.getPlayerA().getId().equals(user.getId())) {
|
||||||
game.setNextStepA(direction);
|
game.setNextStepA(direction);
|
||||||
}
|
} else if (game.getPlayerB().getId().equals(user.getId())) {
|
||||||
else if(game.getPlayerB().getId().equals(user.getId())){
|
|
||||||
game.setNextStepB(direction);
|
game.setNextStepB(direction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,11 @@ package com.kob.backend.consumer.utils;
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.kob.backend.consumer.WebSocketServer;
|
import com.kob.backend.consumer.WebSocketServer;
|
||||||
|
import com.kob.backend.pojo.Record;
|
||||||
|
|
||||||
import javax.swing.event.InternalFrameEvent;
|
import javax.swing.event.InternalFrameEvent;
|
||||||
import java.util.ArrayList;
|
import java.sql.Time;
|
||||||
import java.util.List;
|
import java.util.*;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
// 用来管理整个游戏流程:这里需要多线程
|
// 用来管理整个游戏流程:这里需要多线程
|
||||||
|
@ -62,6 +61,23 @@ public class Game extends Thread {
|
||||||
return inner_walls_count;
|
return inner_walls_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getGameMapString(){
|
||||||
|
StringBuilder res = new StringBuilder();
|
||||||
|
// 将地图数据展开成一维
|
||||||
|
/* for (int i = 0; i < rows; i++) {
|
||||||
|
for (int j = 0; j < cols; j++) {
|
||||||
|
res.append(g[i][j]);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
for (int[] row:g){
|
||||||
|
for(int col:row){
|
||||||
|
res.append(col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.toString();
|
||||||
|
}
|
||||||
|
|
||||||
public void setNextStepA(Integer nextStepA) {
|
public void setNextStepA(Integer nextStepA) {
|
||||||
// 为了防止两方读写冲突,需要加线程锁之后操作 nextStep 值
|
// 为了防止两方读写冲突,需要加线程锁之后操作 nextStep 值
|
||||||
lock.lock();
|
lock.lock();
|
||||||
|
@ -273,6 +289,27 @@ public class Game extends Thread {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 将游戏结果存到数据库中
|
||||||
|
private void saveToDataBase(){
|
||||||
|
Record record = new Record(
|
||||||
|
null,
|
||||||
|
playerA.getId(),
|
||||||
|
playerA.getSx(),
|
||||||
|
playerA.getSy(),
|
||||||
|
playerB.getId(),
|
||||||
|
playerB.getSx(),
|
||||||
|
playerB.getSy(),
|
||||||
|
playerA.getStepsString(),
|
||||||
|
playerB.getStepsString(),
|
||||||
|
getGameMapString(),
|
||||||
|
loser,
|
||||||
|
new Date()
|
||||||
|
);
|
||||||
|
|
||||||
|
WebSocketServer.recordMapper.insert(record);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 向两个 Client 公布结果
|
// 向两个 Client 公布结果
|
||||||
private void sendResult() {
|
private void sendResult() {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
|
@ -283,6 +320,8 @@ public class Game extends Thread {
|
||||||
// 将最后碰撞时的蛇的眼睛指向传给前端
|
// 将最后碰撞时的蛇的眼睛指向传给前端
|
||||||
resp.put("a_eyes_finally_direction", nextStepA);
|
resp.put("a_eyes_finally_direction", nextStepA);
|
||||||
resp.put("b_eyes_finally_direction", nextStepB);
|
resp.put("b_eyes_finally_direction", nextStepB);
|
||||||
|
// 发送结果之前,先将结果存到数据库中
|
||||||
|
saveToDataBase();
|
||||||
sendAllMessage(resp.toJSONString());
|
sendAllMessage(resp.toJSONString());
|
||||||
} finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
|
|
@ -48,4 +48,14 @@ public class Player {
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// steps 转换为 string 的辅助函数
|
||||||
|
public String getStepsString() {
|
||||||
|
StringBuilder res = new StringBuilder();
|
||||||
|
for (int d : steps) {
|
||||||
|
res.append(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.kob.backend.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.kob.backend.pojo.Record;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface RecordMapper extends BaseMapper<Record> {
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
//用于将 Mysql 表 Bot 转换为 class
|
// 用于将 Mysql 表 Bot 转换为 class
|
||||||
|
// 数据库中 user_id 这种在 pojo 里要命名为 userId
|
||||||
package com.kob.backend.pojo;
|
package com.kob.backend.pojo;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.kob.backend.pojo;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Timer;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class Record {
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
private Integer aId;
|
||||||
|
private Integer aSx;
|
||||||
|
private Integer aSy;
|
||||||
|
private Integer bId;
|
||||||
|
private Integer bSx;
|
||||||
|
private Integer bSy;
|
||||||
|
|
||||||
|
private String aSteps;
|
||||||
|
private String bSteps;
|
||||||
|
private String map;
|
||||||
|
private String loser;
|
||||||
|
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
|
||||||
|
private Date createtime;
|
||||||
|
}
|
Loading…
Reference in New Issue