[网页五子棋][匹配模式]创建房间类、房间管理器、验证匹配功能,匹配模式小结

06-02 1110阅读

文章目录

  • 创建房间类
    • 创建房间类
    • 实现房间管理器
    • 实现匹配器(3)
    • 验证匹配功能
      • 问题:匹配按钮不改变
      • 验证多开
      • 小结

        创建房间类

        LOL,通过匹配的方式,自动给你加入到一个房间,也可手动创建游戏房间

        • 这一局游戏,进行的“场所”就可以称为是一个“游戏房间”,游戏房间中最关键的信息,就是玩家信息
        • 一个游戏服务器,有同时存在了多个游戏房间

          我们就需要一个“游戏房间管理器”来管理多个游戏房间[网页五子棋][匹配模式]创建房间类、房间管理器、验证匹配功能,匹配模式小结

          • 键值对的方式,给每个 room 生成一个唯一的 roomId,以键值对 (哈希表) 在 room manager 中来进行管理

            创建房间类

            匹配成功之后,需要把对战的两个玩家放到同一个房间对象中

            创建 game.Room 类

            • 一个房间要包含一个房间 ID,使用 UUID 做为房间的唯一身份标识
            • 房间内要记录对弈的玩家双方信息

              UUID 表示“世界上唯一的身份标识”

              • 通过一系列的算法,能够生成一串字符串(一组十六进制表示的数字)
              • 两次/任意次调用这个算法,生产的这个字符串都是不同的
                package org.example.java_gobang.game;  
                  
                import org.example.java_gobang.model.User;  
                  
                import java.util.UUID;  
                  
                // 表示一个游戏房间  
                public class Room {  
                    // 此处我们使用字符串的类型来表示,方便生成唯一值  
                    private String roomId;  
                  
                    private User user1;  
                    private User user2;  
                  
                    public String getRoomId() {  
                        return roomId;  
                    }  
                  
                    public void setRoomId(String roomId) {  
                        this.roomId = roomId;  
                    }  
                  
                    public User getUser1() {  
                        return user1;  
                    }  
                  
                    public void setUser1(User user1) {  
                        this.user1 = user1;  
                    }  
                  
                    public User getUser2() {  
                        return user2;  
                    }  
                  
                    public void setUser2(User user2) {  
                        this.user2 = user2;  
                    }  
                  
                    public Room() {  
                        // 构造 Room 的时候,生成一个唯一的字符串来表示房间 id        roomId = UUID.randomUUID().toString();  
                    }  
                }
                

                实现房间管理器

                Room 对象会存在很多,每两个对弈的玩家,都对应一个 Room 对象,需要创建一个管理器对象来管理所有的 Room

                创建 game.RoomManager

                • 使用一个 Hash 表,保存所有房间对象
                  • key:roomId
                  • value:Room对象
                  • 再使用一个 Hash 表,保存 userId -> RoomId 的映射,方便根据玩家来查找所在的房间
                  • 提供增、删、查的 API
                    • 查询包含基于房间 ID 的查询和基于用户 ID 的查询
                      package org.example.java_gobang.game;  
                        
                      import org.springframework.stereotype.Component;  
                        
                      import java.util.concurrent.ConcurrentHashMap;  
                        
                      // 房间管理器,这个类也希望有唯一实例  
                      @Component  
                      public class RoomManager {  
                          private ConcurrentHashMap rooms = new ConcurrentHashMap();  
                          // 通过这个哈希表,把玩家和房间之间的关系维护起来  
                          private ConcurrentHashMap userIdToRoomId = new ConcurrentHashMap();  
                        
                          public void add(Room room, int userId1, int userId2) {  
                              rooms.put(room.getRoomId(), room);  
                              userIdToRoomId.put(userId1, room.getRoomId());  
                              userIdToRoomId.put(userId2, room.getRoomId());  
                          }  
                        
                          public void remove(String roomId, int userId1, int userId2) {  
                              rooms.remove(roomId);  
                              userIdToRoomId.remove(userId1);  
                              userIdToRoomId.remove(userId2);  
                          }  
                        
                          public Room getRoomByRoomId(String roomId) {  
                              return rooms.get(roomId);  
                          }  
                        
                          // 根据用户id 定位房间  
                          public Room getRoomByUserId(int userId) {  
                              String roomId = userIdToRoomId.get(userId);  
                              if(roomId == null) {  
                                  // userId -> roomId 映射关系不存在,直接返回 null            return null;  
                              }  
                              return rooms.get(roomId);  
                          }  
                      }
                      

                      实现匹配器(3)

                      完善刚才匹配逻辑中的 TODO,并把玩家放到一个房间中 [网页五子棋][匹配模式]创建房间类、房间管理器、验证匹配功能,匹配模式小结

                      • 先给 Matcher 注入 RoomManager 对象
                        @Component
                        public class Matcher {
                        	//......
                        	// 房间管理器
                        	@Autowired
                        	private RoomManager roomManager;
                        	// ......
                        }
                        然后修改 Matcher.handlerMatch,补完之前 TODO 的内容
                        private void handlerMatch(Queue matchQueue) {
                        	// 4. 把这两个玩家放到一个游戏房间中  
                        	Room room = new Room();  
                        	roomManager.add(room, player1.getUserId(), player2.getUserId());
                        	// ......
                        }
                        

                        验证匹配功能

                        问题:匹配按钮不改变

                        当前发现,玩家点击匹配之后,匹配按钮的文本不发生改变

                        • 分析之前写的代码,点击按钮的时候,仅仅是给服务器发送了一个 websocket 请求,告诉服务器我要开始匹配了
                        • 服务器会立即返回一个响应,“进入匹配队列成功”,然后页面再修改按钮的文本[网页五子棋][匹配模式]创建房间类、房间管理器、验证匹配功能,匹配模式小结

                          出现问题的原因:

                          • 服务器在处理匹配请求的时候,按理说是要立即就返回一个 websocket 响应的
                          • 实际上在服务器代码这里构造了响应对象,但是忘记 sendMessage,给发回去了[网页五子棋][匹配模式]创建房间类、房间管理器、验证匹配功能,匹配模式小结

                            在红框中加入如下逻辑代码

                            // 将 response 先转换成 JSON 字符串,然后将其通过 sendMessage 发回客户端  
                            String jsonString = objectMapper.writeValueAsString(response);  
                            session.sendMessage(new TextMessage(jsonString));
                            

                            就类似于:你网购买了个东西,商家都已经打包好了,但是最后忘记发货了

                            image.png

                            验证匹配功能的时候,模拟多个用户登录的情况,最好使用多个浏览器,避免同一个浏览器中的 cookie/session 信息互相干扰

                            • 如果只有一个浏览器,并且是 chrome 的话,chrome 有个无痕模式(不会记录历史记录,也不会记录 cookie,页面关闭的时候会自动清空)

                              验证多开

                              当我们打开两个页面,登录同一个账号的时候,后登录的页面的检查页面会出现提示,但是正常用户多开了在页面中却没有显示 image.png

                              • 当用户多开之后,连接就会直接关闭,不能再进行匹配了image.png

                                [网页五子棋][匹配模式]创建房间类、房间管理器、验证匹配功能,匹配模式小结

                                当前情况下,防多开机制起到了作用,但是又感觉差了点意思

                                • 要是在第二个账号登录的时候,在页面中直接有提示就更好了

                                  此时我们就可以调整前端代码,当检测到多开的时候,就给用户一个更加明确的提示 [网页五子棋][匹配模式]创建房间类、房间管理器、验证匹配功能,匹配模式小结

                                  这样,在我们登录的时候,要是出现了多开的情况,就直接报错了,返回重新登录页面[网页五子棋][匹配模式]创建房间类、房间管理器、验证匹配功能,匹配模式小结

                                  • 当我们修改了 css 样式/ JS 文件之后,往往要在浏览器中使用 cmd+shift+R(Windows:ctrl+f5)强制刷新,才能生效
                                  • 否则浏览器可能仍然在执行旧版本的代码(浏览器自带缓存)

                                    小结

                                    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

目录[+]

取消
微信二维码
微信二维码
支付宝二维码