Compare commits

...

2 Commits

Author SHA1 Message Date
ETHEREAL 14581ecbf9 Merge remote-tracking branch 'origin/main' 2024-06-19 14:49:29 +08:00
ETHEREAL 858be7769f 添加房间逻辑 2024-06-19 14:49:06 +08:00
7 changed files with 98 additions and 10 deletions

View File

@ -26,4 +26,8 @@ public interface CommonConstant {
String STATUS = "status"; String STATUS = "status";
String BUCKET = "catchtheletters"; String BUCKET = "catchtheletters";
Integer WORDS_NUM = 10;
String HEAL = "10";
} }

View File

@ -76,14 +76,14 @@ public class AuthController {
@ApiOperation(value = "发送邮件") @ApiOperation(value = "发送邮件")
@PostMapping("/email") @PostMapping("/email")
public R<String> emailSend(@RequestHeader("token") String token, String email) { public R<String> emailSend(String email) {
return emailService.sendEmail(email); return emailService.sendEmail(email);
} }
@ApiOperation(value = "验证邮箱") @ApiOperation(value = "验证邮箱")
@PostMapping("/verify-email") @PostMapping("/verify-email")
public R<String> emailVerify(@RequestHeader("token") String token, String email, String code) { public R<String> emailVerify(String email, String code) {
return emailService.verifyEmail(email, code); return emailService.verifyEmail(email, code);
} }

View File

@ -5,6 +5,7 @@ import com.example.catchTheLetters.model.vo.Letter;
import lombok.Data; import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
import java.util.Map;
/** /**
* 字母操作 * 字母操作
@ -17,6 +18,7 @@ public class LetterAction implements Serializable {
private Letter letter; private Letter letter;
private String userId; private String userId;
private long letterId; private long letterId;
private Map<String, Integer> words;
public LetterAction() { public LetterAction() {
} }
@ -40,4 +42,9 @@ public class LetterAction implements Serializable {
public LetterAction(LetterActionType type) { public LetterAction(LetterActionType type) {
this.type = type; this.type = type;
} }
public LetterAction(LetterActionType type, Map<String, Integer> words) {
this.type = type;
this.words = words;
}
} }

View File

@ -0,0 +1,13 @@
package com.example.catchTheLetters.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Word {
private String id;
private String word;
}

View File

@ -6,6 +6,7 @@ import com.example.catchTheLetters.entity.ScoreInfoPage;
import com.example.catchTheLetters.model.vo.RankVo; import com.example.catchTheLetters.model.vo.RankVo;
import com.example.catchTheLetters.service.AuthService; import com.example.catchTheLetters.service.AuthService;
import com.example.catchTheLetters.service.LevelService; import com.example.catchTheLetters.service.LevelService;
import com.example.catchTheLetters.service.RoomService;
import com.example.catchTheLetters.utils.JwtUtil; import com.example.catchTheLetters.utils.JwtUtil;
import com.example.catchTheLetters.utils.R; import com.example.catchTheLetters.utils.R;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;

View File

@ -1,5 +1,6 @@
package com.example.catchTheLetters.service.impl; package com.example.catchTheLetters.service.impl;
import com.example.catchTheLetters.constant.CommonConstant;
import com.example.catchTheLetters.entity.*; import com.example.catchTheLetters.entity.*;
import com.example.catchTheLetters.enums.*; import com.example.catchTheLetters.enums.*;
import com.example.catchTheLetters.model.vo.Letter; import com.example.catchTheLetters.model.vo.Letter;
@ -7,15 +8,18 @@ import com.example.catchTheLetters.service.AuthService;
import com.example.catchTheLetters.service.RoomService; import com.example.catchTheLetters.service.RoomService;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import lombok.Data;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.WebSocketSession;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.sql.Time;
import java.util.Random; import java.util.*;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
/** /**
@ -36,6 +40,8 @@ public class RoomServiceImpl implements RoomService {
private final Random random = new Random(); private final Random random = new Random();
private int remainTime = 300;
@Resource @Resource
private MongoTemplate mongoTemplate; private MongoTemplate mongoTemplate;
@ -249,8 +255,35 @@ public class RoomServiceImpl implements RoomService {
for (var playerEntry : players.entrySet()) for (var playerEntry : players.entrySet())
sendMessage(playerEntry.getKey(), message); sendMessage(playerEntry.getKey(), message);
// TODO 字母校验和加分改变血量逻辑 // TODO 字母校验和加分改变血量逻辑
// 玩家接取字母时向玩家当前答案中添加字母如果单词拼完给玩家加5*word.length的分和10滴血如果单词拼错每秒扣5滴血如果玩家血量为0则死亡
// 如果接取的是回血爱心给玩家加10滴血 // 如果接取的是回血爱心给玩家加10滴血
if (letter.getLetterVal().equals(CommonConstant.HEAL)){
player.setHealth(player.getHealth() + 10);
}
//判断单词是否拼完
player.setCurrentAnswer(player.getCurrentAnswer() + letter.getLetterVal());
if (player.getCurrentAnswer().length() != player.getCurrentWord().length()){
return;
}
//如果单词拼完给玩家加5*word.length的分和10滴血
if (player.getCurrentAnswer().equals(player.getCurrentWord())){
player.setScore(player.getScore() + 5 * letter.getLetterVal().length());
player.setHealth(player.getHealth() + 10);
} else {
//每秒扣5滴血如果玩家血量为0则死亡
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
if (player.getHealth() > 0){
player.setHealth(player.getHealth() - 5);
} else {
//TODO
// 玩家死亡逻辑
}
}
},0,1000);
}
} }
private void generateLetter(GameRoom room) { private void generateLetter(GameRoom room) {
@ -258,7 +291,7 @@ public class RoomServiceImpl implements RoomService {
var words = room.getWords(); var words = room.getWords();
// 如果words长度<=5从数据库中再获取一批随机单词 // 如果words长度<=5从数据库中再获取一批随机单词
if (words.size() <= 5) getWords(words); if (words.size() <= 5) getWords(words,room);
Letter letter; Letter letter;
var id = UUID.randomUUID().getLeastSignificantBits(); var id = UUID.randomUUID().getLeastSignificantBits();
@ -282,16 +315,41 @@ public class RoomServiceImpl implements RoomService {
sendMessage(player, new GameMessage<>(MessageType.LETTER, new LetterAction(LetterActionType.CREATE, 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,GameRoom room) {
// TODO 从数据库中获取一批随机单词然后放入words中并把单词数组推送给所有玩家 // TODO 从数据库中获取一批随机单词然后放入words中并把单词数组推送给所有玩家
Aggregation aggregation = Aggregation.newAggregation(Aggregation.sample(10));
AggregationResults<Word> results = mongoTemplate.aggregate(aggregation,Word.class,Word.class);
List<Word> mappedResults = results.getMappedResults();
int num = CommonConstant.WORDS_NUM;
num += words.size();
for (Word word : mappedResults) {
words.put(word.getWord(),num--);
}
for (var player : room.getPlayers().keySet()) {
sendMessage(player, new GameMessage<>(MessageType.LETTER, new LetterAction(LetterActionType.CREATE, words)));
}
} }
private void gameLogic(GameRoom room) { private void gameLogic(GameRoom room) {
getWords(room.getWords()); getWords(room.getWords(),room);
// TODO 从300秒开始倒计时每秒调用一次generateLetter方法如果时间到了调用endGame方法 // TODO 从300秒开始倒计时每秒调用一次generateLetter方法如果时间到了调用endGame方法
// 如果当前单词被某玩家拼完Map对应单词的value++如果value>=玩家数有可能中途有人退出目前单词出队列继续下一个单词 // 如果当前单词被某玩家拼完Map对应单词的value++如果value>=玩家数有可能中途有人退出目前单词出队列继续下一个单词
// 游戏结束后需要向玩家发送排行榜数据用户ID分数排名 // 游戏结束后需要向玩家发送排行榜数据用户ID分数排名
// 最大的问题丢包后如何处理比如其他玩家按下按键后自己没有接收到松开消息导致其他玩家在画面中一直持续运动网络连接稳定后不同C端的玩家位置不一致 // 最大的问题丢包后如何处理比如其他玩家按下按键后自己没有接收到松开消息导致其他玩家在画面中一直持续运动网络连接稳定后不同C端的玩家位置不一致
//用timer进行异步执行任务保证倒计时正常进行
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
remainTime--;
generateLetter(room);
if (remainTime == 0) {
endGame(room.getRoomId());
timer.cancel();
}
}
},0,1000);
} }
public void endGame(long roomId) { public void endGame(long roomId) {

View File

@ -4,8 +4,8 @@ import com.example.catchTheLetters.controller.LevelController;
import com.example.catchTheLetters.entity.Level; import com.example.catchTheLetters.entity.Level;
import com.example.catchTheLetters.entity.ScoreInfo; import com.example.catchTheLetters.entity.ScoreInfo;
import com.example.catchTheLetters.entity.VersionDownload; import com.example.catchTheLetters.entity.VersionDownload;
import com.example.catchTheLetters.entity.Word;
import com.example.catchTheLetters.service.VersionService; import com.example.catchTheLetters.service.VersionService;
import com.example.catchTheLetters.utils.R;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -14,8 +14,10 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -122,5 +124,8 @@ class TestInsertLevel {
@Test @Test
@Disabled @Disabled
void minIOTest(){ void minIOTest(){
Aggregation aggregation = Aggregation.newAggregation(Aggregation.sample(5));
AggregationResults<Word> results = mongoTemplate.aggregate(aggregation,Word.class,Word.class);
System.out.println(results.getMappedResults());
} }
} }