你画我猜【附源码】

简介: 你画我猜【附源码】

1 前言

🚀获取源码,文末公众号回复【你画我猜】,即可。

⭐欢迎点赞留言

2 正文

2.1 展示预览

13MB GIF可以欣赏:


2.2 项目结构

2.2 主要代码展示

package cn.moodright.drawandguess.logic;

import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import cn.moodright.drawandguess.entity.message.PainterMessage;
import cn.moodright.drawandguess.entity.message.WordMessage;
import cn.moodright.drawandguess.entity.game.Settings;
import cn.moodright.drawandguess.entity.message.WordPromptMessage;
import cn.moodright.drawandguess.socket.LobbyWebSocketServer;
import com.alibaba.fastjson.JSON;

import java.io.IOException;
import java.util.*;

/**
 * 游戏过程
 * Created by moodright in 2021/5/17
 */
public class GameProcess {
    private static final Log log = LogFactory.get();
    // 定时器
    private static final Timer timer = new Timer();
    // 玩家用户名Map,用于确定绘画者
    private static Map<String, Boolean> playerMap = null;
    // 玩家用户名列表,存储顺序为玩家建立连接时的先后顺序,用于确定绘画者
    private static List<String> playerList = null;
    // 玩家准备数量,用于判断游戏是否开始
    private static int playerReadyCount = 0;
    // 游戏总回合数
    private static int roundCount = 0;
    // 选择单词计时器
    private static WordPickTimer wordPickTimer = null;
    // 游戏状态
    private static boolean status = false;

    /**
     * 获取游戏状态
     * @return 游戏状态
     */
    public static synchronized boolean getGameStatus() {
        return status;
    }

    /**
     * 重置游戏状态
     */
    public static synchronized void resetGameStatus() {
        status = false;
    }

    public static synchronized void setGameStatus() {
        status = true;
    }

    /**
     * 获取单词计时器
     * @return 单词计时器
     */
    public static WordPickTimer getWordPickTimer() {
        return wordPickTimer;
    }

    /**
     * 获取游戏总回合数
     * @return 游戏总回合数
     */
    public static synchronized int getRoundCount() {
        return roundCount;
    }

    /**
     * 游戏总回合数自减
     */
    public static synchronized void subRoundCount() {
        roundCount--;
    }

    /**
     * 获取玩家准备数量
     * @return 玩家准备数量
     */
    public static synchronized int getPlayerReadyCount() {
        return playerReadyCount;
    }

    /**
     * 玩家准备数量自增
     */
    public static synchronized void addPlayerReadyCount() {
        playerReadyCount++;
    }

    /**
     * 玩家准备数量自减
     */
    public static synchronized void subPlayerReadyCount() {
        playerReadyCount--;
    }

    /**
     * 重置玩家准备数量
     */
    public static synchronized void resetPlayerReadyCount() {
        playerReadyCount = 0;
    }

    /**
     * 回合开始
     */
    public static void roundStart() throws IOException {
        // 确定该回合绘画者
        String painterUsername = GameProcess.whoIsPainter();
        // 向绘画者发送该回合单词
        String word = sendWordToPainter(painterUsername);
        // 初始化当前回合资源
        RoundTimer.initRoundResource(word, playerList.size());
        // 存储该引用用于接收到玩家确认单词消息时修改confirm变量
        wordPickTimer = new WordPickTimer(painterUsername);
        // 确认单词计时器开始计时
        timer.schedule(wordPickTimer, 0, 1000);
    }

    /**
     * 发送单词
     * @param painterUsername 绘画者用户名
     * @return 词典中取出的字符串
     */
    public static String sendWordToPainter(String painterUsername) throws IOException {
        // 随机选择词典单词
        String word = Settings.WORD_DICTIONARY.get(new Random().nextInt(Settings.WORD_DICTIONARY.size()));
        // 发送该单词至绘画者
        LobbyWebSocketServer.sendMessageToSpecifiedUser(
                JSON.toJSONString(new WordMessage("word", painterUsername, word)),
                painterUsername);
        // 发送单词提示
        LobbyWebSocketServer.broadcastMessage(JSON.toJSONString(new WordPromptMessage("wordPrompt", "serverSide", word.length())));
        return word;
    }

    /**
     * 确定绘画者
     * @return 绘画者用户名
     */
    public static String whoIsPainter() throws IOException {
        // 顺序选择绘画者
        for (int i = 0; i < playerList.size(); i++) {
            // 若该用户为非绘画者,则命中,修改判断字段
            if (!playerMap.get(playerList.get(i))) {
                playerMap.put(playerList.get(i), true);
                log.info("当前回合绘画者为:" + playerList.get(i));
                // 发送确定绘画者消息
                LobbyWebSocketServer.broadcastMessage(
                        JSON.toJSONString(new PainterMessage("whoIsPainter", playerList.get(i))));
                if (i == playerList.size() - 1) {
                    log.info("此轮游戏结束,重置绘画者选取规则");
                    // 重置绘画者Map值
                    playerMap.replaceAll((k, v) -> false);
                }
                // 停止选择
                return playerList.get(i);
            }
        }
        log.info("异常情况发生,没有选中合适的绘画者!");
        return "";
    }

    /**
     * 初始化游戏资源
     */
    public static void initGameResource() {
        log.info("初始化游戏资源");
        // 修改游戏状态
        setGameStatus();
        // 初始化用户名列表
        playerList = LobbyWebSocketServer.getUsernameList();
        // 初始化绘画者Map
        playerMap = new HashMap<>();
        for (String username : playerList) {
            // 初始化所有玩家为非绘画者
            playerMap.put(username, false);
        }
        // 初始化游戏总回合数
        roundCount = getPlayerReadyCount() * 2;
    }


    /**
     * 游戏开始
     */
    public static void gameStart() throws IOException {
        log.info("游戏开始");
        // 游戏资源初始化
        initGameResource();
        // 第一回合开始
        roundStart();
    }
}

package cn.moodright.drawandguess.controller;

import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import cn.moodright.drawandguess.config.LobbyInterceptor;
import cn.moodright.drawandguess.logic.GameProcess;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;


/**
 * Created by moodright in 2021/5/16
 */

@Controller
public class IndexController {
    private static final Log log = LogFactory.get();

    @GetMapping("/index")
    public String index() {
        return "index";
    }

    /**
     * 验证游戏状态
     * @return boolean
     */
    @PostMapping("/game/status/")
    @ResponseBody
    public boolean getGameStatus() {
        log.info("验证当前游戏状态:" + GameProcess.getGameStatus());
        return GameProcess.getGameStatus();
    }

    /**
     * 验证口令
     * @param key 9418
     * @return boolean
     */
    @PostMapping("/game/key/{key}/{username}")
    @ResponseBody
    public int keyCheck(@PathVariable("key")String key, @PathVariable("username")String username) {
        if(key.equals("9418")) {
            // 拦截器验证字段
            boolean repeat = LobbyInterceptor.usernameSet.add(username);
            if(!repeat) {
                // 用户名重复
                return 3;
            }
            // 口令正确
            return 2;
        }
        // 口令错误
        return 1;
    }
}

源码下载

不会还有人没 点赞 + 关注 + 收藏 吧!

目录
相关文章
|
人工智能 安全 JavaScript
模拟“嫦娥五号”探月小游戏【附源码】
在实际的探月过程中,这些操作都是由程序精确测量和控制的。而在这个游戏里,则需要玩家手动完成 降落 和 上升对接 这两个操作。
|
2月前
|
C语言
猜数游戏(实现) 后附源码
本文介绍了如何使用C语言实现一个猜数游戏,包括游戏的逻辑流程、代码实现以及如何通过随机数生成器和时间戳生成一个1到100之间的随机数。
86 2
猜数游戏(实现) 后附源码
|
6月前
|
小程序
看图猜成语微信小程序源码
后台可以自行设置关卡、等级、也可以一键部署, 开通流量主之后实现躺赚,你懂得。 个人号也可以开通,审核一次性必过。 类目选择 教育,源码仅供您参考!
73 2
|
7月前
|
存储 算法 编译器
捣蛋小游戏——猜数字
捣蛋小游戏——猜数字
猜数字小游戏
猜数字小游戏
64 0
|
7月前
|
Python
python实现贪吃蛇小游戏(附源码)
python实现贪吃蛇小游戏(附源码)
118 0
|
7月前
|
Python
python实现掷骰子小游戏(附源码 简单易懂)
python实现掷骰子小游戏(附源码 简单易懂)
151 0
|
7月前
|
定位技术 Python
python实现迷宫小游戏(附源码 简单易懂)
python实现迷宫小游戏(附源码 简单易懂)
231 0
|
C++
你猜我猜不猜 (猜数字游戏) 快来小玩一把叭
你猜我猜不猜 (猜数字游戏) 快来小玩一把叭
108 0
|
JSON 移动开发 前端开发
程序员如何用“心“表白(结尾附源码)
程序员如何用“心“表白(结尾附源码)
101 0

相关实验场景

更多