完善联机框架
This commit is contained in:
parent
87cd436846
commit
d83e912d5b
|
@ -2,6 +2,7 @@ package com.example.catchTheLetters.entity;
|
||||||
|
|
||||||
import cn.hutool.core.collection.ConcurrentHashSet;
|
import cn.hutool.core.collection.ConcurrentHashSet;
|
||||||
import com.example.catchTheLetters.enums.RoomStatus;
|
import com.example.catchTheLetters.enums.RoomStatus;
|
||||||
|
import com.example.catchTheLetters.model.vo.Letter;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.springframework.web.socket.WebSocketSession;
|
import org.springframework.web.socket.WebSocketSession;
|
||||||
|
|
||||||
|
@ -23,6 +24,8 @@ public class GameRoom {
|
||||||
private WebSocketSession host;
|
private WebSocketSession host;
|
||||||
// 单词 : 目前在拼这个单词的玩家数
|
// 单词 : 目前在拼这个单词的玩家数
|
||||||
private final Map<String, Integer> words = new ConcurrentSkipListMap<>();
|
private final Map<String, Integer> words = new ConcurrentSkipListMap<>();
|
||||||
|
// 字母id : 字母
|
||||||
|
private final Map<Long, Letter> letters = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
public GameRoom(WebSocketSession host, PlayerInGame player) {
|
public GameRoom(WebSocketSession host, PlayerInGame player) {
|
||||||
this.roomId = UUID.randomUUID().getLeastSignificantBits();
|
this.roomId = UUID.randomUUID().getLeastSignificantBits();
|
||||||
|
|
|
@ -16,4 +16,19 @@ public class LetterAction implements Serializable {
|
||||||
private LetterActionType type;
|
private LetterActionType type;
|
||||||
private Letter letter;
|
private Letter letter;
|
||||||
private String userId;
|
private String userId;
|
||||||
|
private long letterId;
|
||||||
|
|
||||||
|
public LetterAction() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public LetterAction(LetterActionType type, Letter letter, String userId) {
|
||||||
|
this.type = type;
|
||||||
|
this.letter = letter;
|
||||||
|
this.userId = userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LetterAction(LetterActionType type, Letter letter) {
|
||||||
|
this.type = type;
|
||||||
|
this.letter = letter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,4 +26,20 @@ public class PlayerInGame implements Serializable {
|
||||||
this.currentWord = "";
|
this.currentWord = "";
|
||||||
this.currentAnswer = "";
|
this.currentAnswer = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addScore(int score) {
|
||||||
|
this.score += score;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reduceHealth(int health) {
|
||||||
|
this.health = Math.max(0, this.health - health);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentAnswer(String letter) {
|
||||||
|
this.currentAnswer += letter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearCurrentAnswer() {
|
||||||
|
this.currentAnswer = "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,4 +13,28 @@ public class RoomAction implements Serializable {
|
||||||
// 房主踢出玩家时或被邀请的玩家ID
|
// 房主踢出玩家时或被邀请的玩家ID
|
||||||
private String userID;
|
private String userID;
|
||||||
private long roomID;
|
private long roomID;
|
||||||
|
|
||||||
|
public RoomAction() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public RoomAction(RoomActionType type, String token, String userID, long roomID) {
|
||||||
|
this.type = type;
|
||||||
|
this.token = token;
|
||||||
|
this.userID = userID;
|
||||||
|
this.roomID = roomID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RoomAction(RoomActionType type, String userID) {
|
||||||
|
this.type = type;
|
||||||
|
this.userID = userID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RoomAction(RoomActionType type, long roomID) {
|
||||||
|
this.type = type;
|
||||||
|
this.roomID = roomID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RoomAction(RoomActionType type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,5 +11,7 @@ public enum MessageType {
|
||||||
LETTER,
|
LETTER,
|
||||||
SCORE,
|
SCORE,
|
||||||
HEALTH,
|
HEALTH,
|
||||||
ERROR
|
ERROR,
|
||||||
|
LOGIN,
|
||||||
|
LOGOUT
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,5 +11,7 @@ public enum RoomActionType {
|
||||||
KICK,
|
KICK,
|
||||||
LEAVE,
|
LEAVE,
|
||||||
START,
|
START,
|
||||||
INVITE
|
CANCEL_START,
|
||||||
|
INVITE,
|
||||||
|
END
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
package com.example.catchTheLetters.handler;
|
package com.example.catchTheLetters.handler;
|
||||||
|
|
||||||
import com.example.catchTheLetters.entity.GameMessage;
|
import com.example.catchTheLetters.entity.GameMessage;
|
||||||
|
import com.example.catchTheLetters.entity.LetterAction;
|
||||||
import com.example.catchTheLetters.entity.PlayerInput;
|
import com.example.catchTheLetters.entity.PlayerInput;
|
||||||
|
import com.example.catchTheLetters.entity.RoomAction;
|
||||||
|
import com.example.catchTheLetters.enums.LetterActionType;
|
||||||
import com.example.catchTheLetters.enums.MessageType;
|
import com.example.catchTheLetters.enums.MessageType;
|
||||||
import com.example.catchTheLetters.service.RoomService;
|
import com.example.catchTheLetters.service.RoomService;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
@ -13,7 +16,7 @@ import org.springframework.web.socket.TextMessage;
|
||||||
import org.springframework.web.socket.WebSocketSession;
|
import org.springframework.web.socket.WebSocketSession;
|
||||||
import org.springframework.web.socket.handler.TextWebSocketHandler;
|
import org.springframework.web.socket.handler.TextWebSocketHandler;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WebSocket 处理器
|
* WebSocket 处理器
|
||||||
|
@ -46,15 +49,49 @@ public class WebSocketHandler extends TextWebSocketHandler {
|
||||||
break;
|
break;
|
||||||
case ROOM:
|
case ROOM:
|
||||||
// 处理房间消息
|
// 处理房间消息
|
||||||
|
var roomData = (RoomAction) gameMessage.getData();
|
||||||
|
switch (roomData.getType()) {
|
||||||
|
case CREATE:
|
||||||
|
roomService.createRoom(session, roomData.getToken());
|
||||||
|
break;
|
||||||
|
case JOIN:
|
||||||
|
roomService.addPlayer(gameMessage.getRoomId(), session, roomData.getToken());
|
||||||
|
break;
|
||||||
|
case LEAVE:
|
||||||
|
roomService.removePlayer(gameMessage.getRoomId(), session);
|
||||||
|
break;
|
||||||
|
case KICK:
|
||||||
|
roomService.kickPlayer(gameMessage.getRoomId(), session, roomData.getUserID());
|
||||||
|
break;
|
||||||
|
case START:
|
||||||
|
roomService.startGame(gameMessage.getRoomId(), session);
|
||||||
|
break;
|
||||||
|
case CANCEL_START:
|
||||||
|
roomService.cancelStartGame(gameMessage.getRoomId(), session);
|
||||||
|
break;
|
||||||
|
case END:
|
||||||
|
roomService.endGame(gameMessage.getRoomId());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
roomService.sendMessage(session, new GameMessage<>(MessageType.ERROR, "未知的房间操作"));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case LETTER:
|
case LETTER:
|
||||||
// 处理字母消息
|
// 处理字母消息
|
||||||
|
var letterData = (LetterAction) gameMessage.getData();
|
||||||
|
if (Objects.requireNonNull(letterData.getType()) == LetterActionType.GET)
|
||||||
|
// 获取字母
|
||||||
|
roomService.getLetter(gameMessage.getRoomId(), session, letterData.getLetterId());
|
||||||
|
else
|
||||||
|
roomService.sendMessage(session, new GameMessage<>(MessageType.ERROR, "未知的字母操作"));
|
||||||
break;
|
break;
|
||||||
case SCORE:
|
case LOGIN:
|
||||||
// 处理分数消息
|
// 处理登录消息
|
||||||
|
roomService.connect(session, (String) gameMessage.getData());
|
||||||
break;
|
break;
|
||||||
case HEALTH:
|
case LOGOUT:
|
||||||
// 处理生命值消息
|
// 处理登出消息
|
||||||
|
roomService.disconnect((String) gameMessage.getData());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
roomService.sendMessage(session, new GameMessage<>(MessageType.ERROR, "未知的消息类型"));
|
roomService.sendMessage(session, new GameMessage<>(MessageType.ERROR, "未知的消息类型"));
|
||||||
|
|
|
@ -9,6 +9,8 @@ import lombok.Data;
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class Letter {
|
public class Letter {
|
||||||
|
private long id;
|
||||||
|
|
||||||
// 字母值,如果是10则是加血
|
// 字母值,如果是10则是加血
|
||||||
private String letterVal;
|
private String letterVal;
|
||||||
|
|
||||||
|
@ -18,12 +20,14 @@ public class Letter {
|
||||||
// 字母的x坐标,0-1之间
|
// 字母的x坐标,0-1之间
|
||||||
private float x;
|
private float x;
|
||||||
|
|
||||||
public Letter(String letterVal, float x) {
|
public Letter(long id, String letterVal, float x) {
|
||||||
|
this.id = id;
|
||||||
this.letterVal = letterVal;
|
this.letterVal = letterVal;
|
||||||
this.x = x;
|
this.x = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Letter(String letterVal, float x, float speed) {
|
public Letter(long id, String letterVal, float x, float speed) {
|
||||||
|
this.id = id;
|
||||||
this.letterVal = letterVal;
|
this.letterVal = letterVal;
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.speed = speed;
|
this.speed = speed;
|
||||||
|
|
|
@ -101,4 +101,12 @@ public interface RoomService {
|
||||||
* @param <T> 消息类型
|
* @param <T> 消息类型
|
||||||
*/
|
*/
|
||||||
<T> void sendMessage(WebSocketSession session, T message);
|
<T> void sendMessage(WebSocketSession session, T message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 玩家获得了字母
|
||||||
|
* @param roomId 房间号
|
||||||
|
* @param session WebSocket 会话
|
||||||
|
* @param letterId 字母ID
|
||||||
|
*/
|
||||||
|
void getLetter(long roomId, WebSocketSession session, long letterId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.example.catchTheLetters.service.impl;
|
package com.example.catchTheLetters.service.impl;
|
||||||
|
|
||||||
import com.example.catchTheLetters.entity.*;
|
import com.example.catchTheLetters.entity.*;
|
||||||
|
import com.example.catchTheLetters.enums.LetterActionType;
|
||||||
import com.example.catchTheLetters.enums.MessageType;
|
import com.example.catchTheLetters.enums.MessageType;
|
||||||
import com.example.catchTheLetters.enums.RoomActionType;
|
import com.example.catchTheLetters.enums.RoomActionType;
|
||||||
import com.example.catchTheLetters.enums.RoomStatus;
|
import com.example.catchTheLetters.enums.RoomStatus;
|
||||||
|
@ -17,6 +18,7 @@ import org.springframework.web.socket.WebSocketSession;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,23 +62,30 @@ public class RoomServiceImpl implements RoomService {
|
||||||
}
|
}
|
||||||
players.put(session, player);
|
players.put(session, player);
|
||||||
|
|
||||||
// TODO 发送消息通知其他玩家有人加入了
|
// 发送消息通知其他玩家有人加入了
|
||||||
|
var message = new GameMessage<>(MessageType.ROOM, new RoomAction(RoomActionType.JOIN, player.getUserId()));
|
||||||
|
for (var playerEntry : players.entrySet())
|
||||||
|
if (playerEntry.getKey() != session)
|
||||||
|
sendMessage(playerEntry.getKey(), message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removePlayer(long roomId, WebSocketSession session) {
|
public void removePlayer(long roomId, WebSocketSession session) {
|
||||||
var room = rooms.get(roomId);
|
var room = rooms.get(roomId);
|
||||||
var players = room.getPlayers();
|
var players = room.getPlayers();
|
||||||
players.remove(session);
|
var removed = players.remove(session);
|
||||||
// 如果是房主退出,更换房主,否则关闭房间
|
// 如果是房主退出,更换房主,否则关闭房间
|
||||||
if (session == room.getHost()) {
|
if (session == room.getHost()) {
|
||||||
if (!players.isEmpty()) {
|
if (!players.isEmpty())
|
||||||
room.setHost(players.keySet().iterator().next());
|
room.setHost(players.keySet().iterator().next());
|
||||||
} else {
|
else
|
||||||
rooms.remove(roomId);
|
rooms.remove(roomId);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// TODO 发送消息通知其他玩家有人退出了
|
// 发送消息通知其他玩家有人退出了
|
||||||
|
var message = new GameMessage<>(MessageType.ROOM, new RoomAction(RoomActionType.LEAVE, removed.getUserId()));
|
||||||
|
for (var player : players.keySet())
|
||||||
|
if (player != session)
|
||||||
|
sendMessage(player, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -88,13 +97,15 @@ public class RoomServiceImpl implements RoomService {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var players = room.getPlayers();
|
var players = room.getPlayers();
|
||||||
|
var message = new GameMessage<>(MessageType.ROOM, new RoomAction(RoomActionType.KICK, playerID));
|
||||||
|
WebSocketSession aimSession = null;
|
||||||
for (var player : players.entrySet()) {
|
for (var player : players.entrySet()) {
|
||||||
if (player.getValue().getUserId().equals(playerID)) {
|
if (player.getValue().getUserId().equals(playerID))
|
||||||
players.remove(player.getKey());
|
aimSession = player.getKey();
|
||||||
// TODO 发送消息通知有玩家被踢出了
|
// 发送消息通知有玩家被踢出了
|
||||||
break;
|
sendMessage(player.getKey(), message);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
players.remove(aimSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -103,10 +114,17 @@ public class RoomServiceImpl implements RoomService {
|
||||||
var players = room.getPlayers();
|
var players = room.getPlayers();
|
||||||
var readyPlayers = room.getReadyPlayers();
|
var readyPlayers = room.getReadyPlayers();
|
||||||
readyPlayers.add(session);
|
readyPlayers.add(session);
|
||||||
// TODO 发送消息通知其他玩家有人准备好了
|
// 发送消息通知其他玩家有人准备好了
|
||||||
|
var message = new GameMessage<>(MessageType.ROOM, new RoomAction(RoomActionType.START, session.getId()));
|
||||||
|
for (var player : players.keySet())
|
||||||
|
if (player != session)
|
||||||
|
sendMessage(player, message);
|
||||||
// 如果所有玩家都准备好了,开始游戏
|
// 如果所有玩家都准备好了,开始游戏
|
||||||
if (readyPlayers.size() == room.getPlayers().size()) {
|
if (readyPlayers.size() == room.getPlayers().size()) {
|
||||||
// TODO 发送消息通知所有玩家游戏开始
|
// 发送消息通知所有玩家游戏开始
|
||||||
|
var startMessage = new GameMessage<>(MessageType.ROOM, new RoomAction(RoomActionType.START, session.getId()));
|
||||||
|
for (var player : players.keySet())
|
||||||
|
sendMessage(player, startMessage);
|
||||||
readyPlayers.clear();
|
readyPlayers.clear();
|
||||||
room.setStatus(RoomStatus.PLAYING);
|
room.setStatus(RoomStatus.PLAYING);
|
||||||
gameLogic(room);
|
gameLogic(room);
|
||||||
|
@ -118,14 +136,21 @@ public class RoomServiceImpl implements RoomService {
|
||||||
var room = rooms.get(roomId);
|
var room = rooms.get(roomId);
|
||||||
var readyPlayers = room.getReadyPlayers();
|
var readyPlayers = room.getReadyPlayers();
|
||||||
readyPlayers.remove(session);
|
readyPlayers.remove(session);
|
||||||
// TODO 发送消息通知其他玩家有人取消准备
|
// 发送消息通知其他玩家有人取消准备
|
||||||
|
var message = new GameMessage<>(MessageType.ROOM, new RoomAction(RoomActionType.CANCEL_START, session.getId()));
|
||||||
|
for (var player : room.getPlayers().keySet())
|
||||||
|
if (player != session)
|
||||||
|
sendMessage(player, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void endGame(long roomId) {
|
public void endGame(long roomId) {
|
||||||
var room = rooms.get(roomId);
|
var room = rooms.get(roomId);
|
||||||
room.setStatus(RoomStatus.WAITING);
|
room.setStatus(RoomStatus.WAITING);
|
||||||
// TODO 发送消息通知所有玩家游戏结束
|
// 发送消息通知所有玩家游戏结束
|
||||||
|
var message = new GameMessage<>(MessageType.ROOM, new RoomAction(RoomActionType.END));
|
||||||
|
for (var player : room.getPlayers().keySet())
|
||||||
|
sendMessage(player, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -133,8 +158,10 @@ public class RoomServiceImpl implements RoomService {
|
||||||
var message = new GameMessage<>(MessageType.INPUT, input);
|
var message = new GameMessage<>(MessageType.INPUT, input);
|
||||||
var room = rooms.get(roomId);
|
var room = rooms.get(roomId);
|
||||||
var players = room.getPlayers();
|
var players = room.getPlayers();
|
||||||
|
// 发送消息通知其他玩家有人输入了
|
||||||
for (var player : players.keySet())
|
for (var player : players.keySet())
|
||||||
if (player != session) sendMessage(player, message);
|
if (player != session)
|
||||||
|
sendMessage(player, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -143,6 +170,8 @@ public class RoomServiceImpl implements RoomService {
|
||||||
var player = new PlayerInGame(user.getId(), user);
|
var player = new PlayerInGame(user.getId(), user);
|
||||||
var room = new GameRoom(session, player);
|
var room = new GameRoom(session, player);
|
||||||
rooms.put(room.getRoomId(), room);
|
rooms.put(room.getRoomId(), room);
|
||||||
|
// 发送消息通知玩家创建房间成功
|
||||||
|
sendMessage(session, new GameMessage<>(MessageType.ROOM, new RoomAction(RoomActionType.CREATE, room.getRoomId())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -150,8 +179,9 @@ public class RoomServiceImpl implements RoomService {
|
||||||
// 如果房间内还有玩家,全部移除
|
// 如果房间内还有玩家,全部移除
|
||||||
var room = rooms.get(roomId);
|
var room = rooms.get(roomId);
|
||||||
var players = room.getPlayers();
|
var players = room.getPlayers();
|
||||||
for (var player : players.keySet()) {
|
for (var player : players.entrySet()) {
|
||||||
// TODO 发送消息通知所有玩家房间已解散
|
// 发送消息通知所有玩家房间已解散
|
||||||
|
sendMessage(player.getKey(), new GameMessage<>(MessageType.ROOM, new RoomAction(RoomActionType.KICK, player.getValue().getUserId())));
|
||||||
}
|
}
|
||||||
rooms.remove(roomId);
|
rooms.remove(roomId);
|
||||||
}
|
}
|
||||||
|
@ -203,6 +233,24 @@ public class RoomServiceImpl implements RoomService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getLetter(long roomId, WebSocketSession session, long letterId) {
|
||||||
|
var room = rooms.get(roomId);
|
||||||
|
var letter = room.getLetters().get(letterId);
|
||||||
|
// 如果没有这个字母,代表被其他玩家拿走了
|
||||||
|
if (letter == null) return;
|
||||||
|
|
||||||
|
var players = room.getPlayers();
|
||||||
|
var player = players.get(session);
|
||||||
|
// 发送消息通知其他玩家有人获得了字母
|
||||||
|
var message = new GameMessage<>(MessageType.LETTER, new LetterAction(LetterActionType.GET, letter, player.getUserId()));
|
||||||
|
for (var playerEntry : players.entrySet())
|
||||||
|
sendMessage(playerEntry.getKey(), message);
|
||||||
|
// TODO 字母校验和加分、改变血量逻辑
|
||||||
|
// 玩家接取字母时,向玩家当前答案中添加字母,如果单词拼完,给玩家加5*word.length的分和10滴血,如果单词拼错,每秒扣5滴血,如果玩家血量为0,则死亡
|
||||||
|
// 如果接取的是回血爱心,给玩家加10滴血
|
||||||
|
}
|
||||||
|
|
||||||
private void generateLetter(GameRoom room) {
|
private void generateLetter(GameRoom room) {
|
||||||
var players = room.getPlayers();
|
var players = room.getPlayers();
|
||||||
var words = room.getWords();
|
var words = room.getWords();
|
||||||
|
@ -211,23 +259,25 @@ public class RoomServiceImpl implements RoomService {
|
||||||
if (words.size() <= 5) getWords(words);
|
if (words.size() <= 5) getWords(words);
|
||||||
|
|
||||||
Letter letter;
|
Letter letter;
|
||||||
|
var id = UUID.randomUUID().getLeastSignificantBits();
|
||||||
|
|
||||||
var val = random.nextInt(100);
|
var val = random.nextInt(100);
|
||||||
|
|
||||||
// 在80%概率当前单词的字母中随机选择一个,19%随机生成一个字母,1%是回血爱心。选定后随机赋值2f到6f的下落速度
|
// 在80%概率当前单词的字母中随机选择一个,19%随机生成一个字母,1%是回血爱心。选定后随机赋值2f到6f的下落速度
|
||||||
if (val == 0)
|
if (val == 0)
|
||||||
// 回血爱心
|
// 回血爱心
|
||||||
letter = new Letter("10", random.nextFloat(1), random.nextFloat(2, 6));
|
letter = new Letter(id, "10", random.nextFloat(1), random.nextFloat(2, 6));
|
||||||
else if (val <= 81)
|
else if (val <= 81)
|
||||||
// 从当前单词中随机选择一个字母
|
// 从当前单词中随机选择一个字母
|
||||||
letter = new Letter(words.keySet().toArray()[random.nextInt(words.size())].toString(), random.nextFloat(1), random.nextFloat(2, 6));
|
letter = new Letter(id, words.keySet().toArray()[random.nextInt(words.size())].toString(), random.nextFloat(1), random.nextFloat(2, 6));
|
||||||
else
|
else
|
||||||
// 随机生成一个字母
|
// 随机生成一个字母
|
||||||
letter = new Letter(String.valueOf((char) (random.nextInt(26) + 'a')), random.nextFloat(1), random.nextFloat(2, 6));
|
letter = new Letter(id, String.valueOf((char) (random.nextInt(26) + 'a')), random.nextFloat(1), random.nextFloat(2, 6));
|
||||||
|
|
||||||
|
room.getLetters().put(id, letter);
|
||||||
// 给所有玩家发送字母
|
// 给所有玩家发送字母
|
||||||
for (var player : players.keySet())
|
for (var player : players.keySet())
|
||||||
sendMessage(player, new GameMessage<>(MessageType.LETTER, letter));
|
sendMessage(player, new GameMessage<>(MessageType.LETTER, new LetterAction(LetterActionType.CREATE, letter)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getWords(Map<String, Integer> words) {
|
private void getWords(Map<String, Integer> words) {
|
||||||
|
@ -236,6 +286,9 @@ public class RoomServiceImpl implements RoomService {
|
||||||
|
|
||||||
private void gameLogic(GameRoom room) {
|
private void gameLogic(GameRoom room) {
|
||||||
getWords(room.getWords());
|
getWords(room.getWords());
|
||||||
// TODO 从300秒开始倒计时,每秒调用一次generateLetter方法,如果时间到了,调用endGame方法,如果当前单词被某玩家拼完,Map对应单词的value++,如果value>=玩家数(有可能中途有人退出),目前单词出队列,继续下一个单词
|
// TODO 从300秒开始倒计时,每秒调用一次generateLetter方法,如果时间到了,调用endGame方法
|
||||||
|
// 如果当前单词被某玩家拼完,Map对应单词的value++,如果value>=玩家数(有可能中途有人退出),目前单词出队列,继续下一个单词
|
||||||
|
// 游戏结束后需要向玩家发送排行榜数据(用户ID、分数、排名)
|
||||||
|
// 最大的问题:丢包后如何处理?比如其他玩家按下按键后,自己没有接收到松开消息,导致其他玩家在画面中一直持续运动,网络连接稳定后,不同C端的玩家位置不一致
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,9 @@ public class GameMessageDeserializer extends JsonDeserializer<GameMessage<?>> {
|
||||||
case "LETTER" -> new GameMessage<>(MessageType.LETTER, objectMapper.treeToValue(data, LetterAction.class));
|
case "LETTER" -> new GameMessage<>(MessageType.LETTER, objectMapper.treeToValue(data, LetterAction.class));
|
||||||
case "SCORE" -> new GameMessage<>(MessageType.SCORE, objectMapper.treeToValue(data, ScoreAction.class));
|
case "SCORE" -> new GameMessage<>(MessageType.SCORE, objectMapper.treeToValue(data, ScoreAction.class));
|
||||||
case "HEALTH" -> new GameMessage<>(MessageType.HEALTH, objectMapper.treeToValue(data, HealthAction.class));
|
case "HEALTH" -> new GameMessage<>(MessageType.HEALTH, objectMapper.treeToValue(data, HealthAction.class));
|
||||||
|
case "ERROR" -> new GameMessage<>(MessageType.ERROR, objectMapper.treeToValue(data, String.class));
|
||||||
|
case "LOGIN" -> new GameMessage<>(MessageType.LOGIN, objectMapper.treeToValue(data, String.class));
|
||||||
|
case "LOGOUT" -> new GameMessage<>(MessageType.LOGOUT, objectMapper.treeToValue(data, String.class));
|
||||||
default -> throw new IllegalArgumentException("未知的消息类型");
|
default -> throw new IllegalArgumentException("未知的消息类型");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue