技术复盘:指令帧同步Unity RTS手游(2)Java Web服务器匹配房间(1)

本文讨论了网络游戏中的房间匹配机制,包括一键匹配和创建/加入房间两种模式。介绍了房间类的设计,涉及房间对象的属性、创建方法、玩家进出房间操作以及超时处理等关键点。
摘要由CSDN通过智能技术生成

        房间匹配这块就没那么简单了,涉及到的东西掠夺,可能要分好几个部分才能复盘完整。

        首先整理一下大体思路。网游一般是一键匹配,即玩家点击匹配,系统自动匹配。换成代码思路就是玩家向服务器提交匹配请求,服务器根据玩家的一些数据比如ip地址,玩家等级等,将玩家组成一个“房间队列”。当房间队列内的玩家已经满员且就绪后,开始游戏。

       另一种就是类似于红警那种,玩家创建/加入房间。前者是商业化落地的考虑,这里只是复盘一个简单的房间系统。

      首先明确:一个“房间”的主要责任:向一个房间内的所有玩家转发每个玩家的全部指令。

房间类

     1.定义一个房间对象,其主要的一些属性及其备注。
public class Room {
    //房间总数,从0开始按创建顺序增长
    public static int roomCount = 0;
    //房间哈希码列表,key是房间哈希值,value是房间号
    public static Hashtable<Integer, Room> roomHashMap = new Hashtable<Integer,Room>();
    public static Hashtable<Integer, Room> roomIdMap = new Hashtable<>();
    //房主名称
    public String hostName;
    //房间容量:几v几
    public int roomSize;
    //当前玩家数量
    public int playerCount = 0;
    //房间序号
    public int roomID;
    //满员标识:满员后大厅不显示该房间
    public boolean ifFull = false;
    //空房标识:空房间大厅不显示该房间
    public boolean ifEmpty = true;
    //开始游戏标志:开始游戏后大厅不显示该房间
    public boolean ifStartGame = false;
    //当前房间的玩家的Id列表
    public ArrayList<String> userIdsList;
    //当前房间的玩家的名称列表
    public ArrayList<String> userNameList;
    //当前房间哈希值(唯一标志)
    public int hashCode;
    //当前房间线程池
    private ScheduledExecutorService executorService = Executors.newScheduledThreadPool(3);
    //每个玩家最后访问该房间的时间,用于超时判定
    private Hashtable<String, Long> lastAccessTime = new Hashtable<>(); // 记录每个用户的最后访问时间
    private static final long TIMEOUT = 10000; // 用户超时时间,单位为毫秒
    //所有玩家最后访问的时间(一个房间超过多少秒没有任何玩家访问,则重置房间)
    private long lastCmdTime = System.currentTimeMillis();
2.创建一个新的房间,创建的时候指定房间容量和房主名称
// 初始化
    public Room(int roomSize,String hostName) {
        synchronized (Room.class) {
            Room.roomCount++;
        }
        roomID = Room.roomCount;
        this.hashCode = generateUniqueHashCode();
        roomHashMap.put(this.hashCode,this);
        this.roomSize = roomSize;
        this.userIdsList = new ArrayList<>();
        this.userNameList = new ArrayList<>();
        roomIdMap.put(roomID, this);
    }
3.玩家进入房间,

将玩家注册到房间的玩家列表。当进入后玩家数量达到房间容量后,启动一个开始计时线程,准备开始

// 进房间
public synchronized boolean InRoom(String userId,String userName) {
    if (ifFull)
        return false;
    else {
        //首个进入房间的是房主
        if (userNameList.size()==0)
            hostName=userName;
        //添加用户Id和用户名称
        userIdsList.add(userId);
        userNameList.add(userName);
        playerCount++;
        ifEmpty=false;
        lastAccessTime.put(userId, System.currentTimeMillis()); // 更新用户的最后访问时间
        if (userIdsList.size() >= roomSize) {
            System.out.println("房间:" + roomID + "准备开始!当前玩家数量" + userIdsList.size());
            LaterSetStartFlag(true, 5);
            ifFull = true;
        }
        return true;
    }
}
4.退出房间

删除该玩家数据

// 出房间
    public synchronized void OutRoom(String userId) {
        if (userIdsList.contains(userId)) {
            playerCount--;
            if (!ifStartGame)
                ifFull = false;
            userNameList.remove(userIdsList.indexOf(userId));
            userIdsList.remove(userId);
            lastAccessTime.remove(userId); // 移除用户的最后访问时间

        }
        System.out.println(userId+"退出房间");
        if (userIdsList.size() <= 0)
            resetRoom();
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值