go游戏后端开发22:游戏房间功能

房间创建功能

(一)功能描述

玩家启动游戏后,可通过界面点击"创建房间"按钮,触发房间创建流程。系统自动生成房间号,并将房间相关信息存储于服务器,同时将房间号推送给房间创建者,便于其邀请其他玩家加入。

(二)实现细节

  1. 房间号生成:服务器采用特定算法生成唯一房间号,确保不同房间间无冲突。

  2. 房间信息存储:房间创建时,服务器记录房间号、创建者用户ID、房间初始状态(如空闲、游戏进行中等)等关键信息。

  3. 房间号推送:房间创建成功后,服务器通过已建立的网络连接,将房间号及相关基本信息以数据包形式推送给创建者客户端,客户端收到后显示房间号,供创建者使用。

进入房间通知功能

(一)功能描述

当玩家创建房间或加入房间时,系统需通知该玩家进入房间,同时告知其房间内当前的游戏类型等关键信息,以便玩家知晓并进行后续操作,如准备游戏等。

(二)实现细节

  1. 通知触发:玩家完成房间创建或加入操作后,系统自动触发进入房间通知流程。

  2. 信息推送:系统从服务器获取房间当前游戏类型等信息,将其封装为特定格式的数据包,通过网络推送给对应玩家客户端。

  3. 客户端处理:客户端收到通知后,解析数据包,提取游戏类型等信息,在界面上显示相关提示,如"您已进入房间,当前游戏类型为[具体类型]",并根据游戏类型加载相应资源,为进入游戏做好准备。

踢出房间机制

(一)功能描述

为避免玩家长时间停留在房间内不进行准备操作,影响其他玩家游戏体验,系统设置踢出房间机制。若玩家在规定时间内(如30秒)未准备,系统自动将其踢出房间,并通知房间内其他玩家该玩家被踢出,同时清理房间内该玩家相关数据。

(二)实现细节

  1. 定时任务设置:玩家进入房间后,系统为其设置定时任务,开始计时。

  2. 准备状态检测:定时任务运行期间,系统持续检测玩家是否完成准备操作。若玩家准备,取消定时任务;若定时任务完成时玩家仍未准备,执行踢出操作。

  3. 踢出操作执行:系统将被踢出玩家的房间ID置为空,通知房间内其他玩家该玩家被踢出,清理房间内该玩家数据,如座位信息等。

  4. 房间解散判断:踢出玩家后,系统检查房间内剩余玩家数量。若无玩家,自动解散房间,释放房间资源。

用户准备功能

(一)功能描述

玩家进入房间后,需点击"准备"按钮表明已准备好开始游戏。系统记录玩家准备状态,并通知房间内其他玩家该玩家已准备,当所有玩家均准备完毕后,可触发游戏开始逻辑。

(二)实现细节

  1. 准备状态记录:玩家点击"准备"按钮后,客户端向服务器发送准备请求,服务器接收后更新该玩家在房间内的准备状态为"已准备"。

  2. 状态通知:服务器将该玩家准备状态更新信息推送给房间内其他玩家,其他玩家客户端收到后更新界面显示,如显示该玩家头像旁的"已准备"标识。

  3. 游戏开始判断:系统持续检测房间内所有玩家准备状态,当所有玩家均准备完毕时,满足游戏开始条件,可触发发牌等游戏开始相关操作。

加入房间功能

(一)功能描述

已有房间存在时,其他玩家可通过输入房间号申请加入该房间。系统验证房间号有效性、房间是否已满等条件,若满足则允许玩家加入,并通知房间内所有玩家有新玩家加入,同步新玩家相关信息,如用户名、头像等。

(二)实现细节

  1. 房间查找:玩家输入房间号后,客户端将房间号发送至服务器,服务器根据房间号查找对应房间。

  2. 条件判断:服务器检查房间是否存在、是否已满等条件。若房间不存在或已满,返回错误信息给申请加入的玩家;若条件满足,允许加入。

  3. 玩家加入处理:新玩家加入后,服务器更新房间内玩家列表,将新玩家信息推送给房间内所有玩家,同时将房间内已有游戏相关信息(如当前游戏阶段、其他玩家准备状态等)推送给新加入玩家,实现信息同步。

    复制代码
    func (r *Room) userReady(uid string, session *remote.Session) {
    	if r.gameStarted {
    		return
    	}
    	//1. push用户的座次,修改用户的状态,取消定时任务
    	user, ok := r.users[uid]
    	if !ok {
    		return
    	}
    	//首局判断玩家积分,如果积分不够则直接踢出游戏
    	if r.hasStartedOneBureau && user.UserInfo.Score < r.GameRule.ScoreLowLimit {
    		r.sendPopDialogContent(biz.LeaveRoomGoldExceedLimit, []string{user.UserInfo.Uid}, session)
    		r.kickUser(user, session)
    		return
    	}
    	if user.UserStatus&enums.Ready == 0 {
    		user.UserStatus |= enums.Ready
    		user.UserStatus |= enums.Dismiss
    	} else {
    		return
    	}
    	r.sendData(proto.UserReadyPushData(user.ChairID), session.GetMsg())
    	efficacyStartRoom := r.efficacyStartRoom()
    	if efficacyStartRoom {
    		r.startGame(session, user)
    	} else {
    		if r.hasStartedOneBureau {
    			return
    		}
    		if r.gameStarted {
    			return
    		}
    		if r.startSchedulerID != nil {
    			return
    		}
    		start := r.isShouldSchedulerStart()
    		if start {
    			tick := 10
    			r.startSchedulerID = tasks.NewTask("startSchedulerID", 1*time.Second, func() {
    				if r.isDismissing() {
    					return
    				}
    				tick--
    				if tick >= 0 {
    					return
    				}
    				if !r.isShouldSchedulerStart() {
    					return
    				}
    				//开始游戏
    				if r.gameStarted {
    					return
    				}
    				//没准备的玩家转为旁观
    				for _, v := range r.users {
    					if v.ChairID >= r.chairCount {
    						continue
    					}
    					if v.UserStatus&enums.Ready == 0 {
    						r.userChangeSeat(session, v.ChairID, r.getEmptyChairID("", true))
    					}
    				}
    				r.startGame(session, user)
    				r.stopStartSchedulerID <- struct{}{}
    			})
    		}
    	}
    }
    
    func (r *Room) JoinRoom(session *remote.Session, data *entity.User) *msError.Error {
    
    	return r.UserEntryRoom(session, data)
    }
    
    func (r *Room) OtherUserEntryRoomPush(session *remote.Session, uid string) {
    	others := make([]string, 0)
    	for _, v := range r.users {
    		if v.UserInfo.Uid != uid {
    			others = append(others, v.UserInfo.Uid)
    		}
    	}
    	user, ok := r.users[uid]
    	if ok {
    		r.SendData(session.GetMsg(), others, proto.OtherUserEntryRoomPushData(user))
    	}
    }
相关推荐
uhakadotcom12 小时前
云计算与开源工具:基础知识与实践
后端·面试·github
uhakadotcom13 小时前
BPF编程入门:使用Rust监控CPU占用
后端·面试·github
uhakadotcom13 小时前
GHSL-2024-252: Cloudflare Workers SDK 环境变量注入漏洞解析
后端·面试·github
uhakadotcom13 小时前
GHSL-2024-264_GHSL-2024-265: 了解 AWS CLI 中的正则表达式拒绝服务漏洞 (ReDoS)
后端·面试·github
uhakadotcom13 小时前
了解Chainlit:简化AI应用开发的Python库
后端·面试·github
小华同学ai14 小时前
1K star!这个开源项目让短信集成简单到离谱,开发效率直接翻倍!
后端·程序员·github
ON.LIN14 小时前
Git提交本地项目到Github
git·github
uhakadotcom15 小时前
使用 Model Context Protocol (MCP) 构建 GitHub PR 审查服务器
后端·面试·github
uhakadotcom15 小时前
Apache Airflow入门指南:数据管道的强大工具
算法·面试·github
uhakadotcom15 小时前
Ruff:Python 代码分析工具的新选择
后端·面试·github