房卡麻将分析系列 "牌局回放" 之 播放处理

2023-05-16

持续放出房卡麻将设计与研发讲解。敬请关注微信共众号:红孩儿的游戏开发之路


                       房卡麻将分析系列 "牌局回放" 之 播放处理



           昨天红孩儿给大伙讲了讲”牌局回放“的数据记录处理,有了数据的存储,下面就是数据的显示了。


          实话讲,好久没用过 SQL Server 来做数据库了, 网狐的服务器是基于WIN,IOCP,  SQL Server 这套路子。配置好后,可以在QPTreasureDB数据库中看到三个牌局相关的表。




         其中dbo.PrivateGameRecord是存储当前游戏的房间及玩家,最终胜负信息的。

        dbo.PrivateGameRecordChild是存储当前游戏的每一局的牌局回放,也就是咱们上篇文中所讲述的每一场牌局详情和操作数据。

       dbo.PrivateGameRecordUserRecordID是记录ID与玩家ID的对应关系。


      我们打开dbo.PrivateGameRecord,可以看到有一个属性字段UserData存储着一堆二进制数据。也就是我们上节中通过Stream_VALUE来将结构数据填充为字节流后存进来的。


      当客户端在进入战绩界面时,会向登录服务器发送SUB_GP_GAME_RECORD_LIST消息,请求当前玩家的所有参与过的房间据,也就是dbo.PrivateGameRecord中与玩家相关的数据列表。这个可以在CGPGameRecord.cpp的CB_GetGameRecordList函数中看到。


       在登录服务器的AttemperEngineSink.cpp中,我们可以看到登录服务器会在收到消息后转发数据库请求,数据库再通过存储过程拉数据出来。之后返回给客户端。


     客户端收到后通过StreamValue将数据流解析到结构tagPrivateRandTotalRecord中显示出来。




        当玩家看到这条信息后,如果想查看每一局的战局,会再点击"详情"按钮,这时客户端会向登录服务器再次发送SUB_GP_GAME_RECORD_CHILD消息,同上面的流程大体一致,经过这样一个来回,客户端会得到房间中每局的详细数据,收到后通过StreamValue将数据流解析到结构tagPrivateRandRecordChild中显示出来。




   玩家现在能看到每一局的详情了,他如果想看牌局回放,会再调用GameScene的StartRecord(datastream kDataStream)来将tagPrivateRandRecordChild中的数据流转化为当前玩家牌局信息和操作信息。之后显示游戏场景和回放操作按钮菜单。有了具体的数据,通过按钮菜单来控制播放的速度,上一步,下一步并不复杂。在GameScene的NextRecordAction函数中,我们可以看到如何根据当前的操作类型来进行相应的操作复现玩家的出牌和操作。

void GameScence::NextRecordAction()
{
     ...
	GameRecordOperateResult& kAction = m_pGameRecord->kAction[m_iActRecordIdex];
	int iChairID = (m_wRecordSelfChairID-kAction.wOperateUser+MAX_PLAYER)%MAX_PLAYER;
	int iProvideUser = (m_wRecordSelfChairID-kAction.wProvideUser+MAX_PLAYER)%MAX_PLAYER;
	if (kAction.cbActionType == GameRecordOperateResult::TYPE_OperateResult)
	{
		Player* pPlayer = m_pPlayer[iChairID];
		CMD_S_OperateResult kTempCMD;
		kTempCMD.cbOperateCard = kAction.cbOperateCard;
		kTempCMD.cbOperateCode = kAction.cbOperateCode;
		kTempCMD.wOperateUser = kAction.wOperateUser;
		kTempCMD.wProvideUser = kAction.wProvideUser;
		Player* pProvidePlayer = m_pPlayer[iProvideUser];
		if (pProvidePlayer &&(kAction.cbOperateCode == WIK_PENG 
			|| kAction.cbOperateCode == WIK_LEFT
			|| kAction.cbOperateCode == WIK_CENTER
			|| kAction.cbOperateCode == WIK_RIGHT
			|| (kAction.cbOperateCode == WIK_GANG && kAction.wOperateUser != kAction.wProvideUser )))
		{
			pProvidePlayer->removeHandOutCard(kAction.cbOperateCard);
			pProvidePlayer->setActOutCard(-1);

			//设置当前玩家
			for (int i = 0; i<MAX_PLAYER; i++)
			{
				m_pPlayer[i]->stopAniCurrPlayer();
			}
			pProvidePlayer->runAniCurrPlayer();
		}

		pPlayer->setOperateResoult(&kTempCMD);
		pPlayer->showCard();
	}
	if (kAction.cbActionType == GameRecordOperateResult::TYPE_SendCard)
	{
		XPlayer* pPlayer = m_pPlayer[iChairID];
		if (kAction.cbOperateCard != 0)
		{
			pPlayer->addNewInCard(kAction.cbOperateCard);
		}
		pPlayer->showCard();

		//设置当前玩家
		for (int i = 0; i<MAX_PLAYER; i++)
		{
			m_pPlayer[i]->stopAniCurrPlayer();
		}
		pPlayer->runAniCurrPlayer();
	}
	if (kAction.cbActionType == GameRecordOperateResult::TYPE_OutCard)
	{
		Player* pPlayer = m_pPlayer[iChairID];
		for (int i = 0;i<MAX_PLAYER;i++)
		{
			m_pPlayer[i]->setActOutCard(-1);
		}
		pPlayer->sendOutCard(kAction.cbOperateCard);
		pPlayer->showCard();
	}
	if (kAction.cbActionType == GameRecordOperateResult::TYPE_ChiHu)
	{
		Player* pPlayer = m_pPlayer[iChairID];
		for (int i = 0;i<MAX_PLAYER;i++)
		{
			m_pPlayer[i]->setActOutCard(-1);
		}

		pPlayer->setChiHuCard(kAction.cbOperateCard);
		pPlayer->showEffect("Hu");
		if (kAction.wOperateUser != kAction.wProvideUser)
		{
			XZDDPlayer* pDestPlayer = m_pPlayer[iChairID];
			pPlayer->showHandCard();
			pPlayer->showStatusImagic("Hu");
			pDestPlayer->runAniHu();
		}
		else
		{
			pPlayer->showStatusImagic("ZiMo");
			pPlayer->runAniZiMo();
		}
		pPlayer->showCard();
	}

	m_iActRecordIdex++;
	...
}





于是,一场精彩的牌局就被完完整整的回放了。



                                           

扫一扫,关注红孩儿共众号,每天获取更多房卡麻将技术文章

                                        

                                                                                                                



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

房卡麻将分析系列 "牌局回放" 之 播放处理 的相关文章

  • C++ STL set和multiset的使用 hunst_xiehonghao 总结

    C 43 43 STL set和multiset的使用 std set lt int gt s 那个s这个对象里面存贮的元素是从小到大 排序的 xff0c 因为用std less作为比较工具 1 xff0c set的含义是集合 xff0c
  • 数据结构之车厢调度 思路很重要

    问题描述 假设停在铁路调度站入口处的车厢序列的编号依次为1 xff0c 2 xff0c 3 N 设计一个程序 xff0c 求出所有由此输出的长度为N的车厢序列 要求3节车厢调度的方法 xff0c 1代表进栈 xff0c 0代表出栈 有几点要
  • 判断N 数码是否有解 牛人总结 归并排序

    作者 力的博客 先介绍八数码问题 xff1a 我们首先从经典的八数码问题入手 xff0c 即对于八数码问题的任意一个排列是否有解 xff1f 有解的条件是什么 xff1f 我在网上搜了半天 xff0c 找到一个十分简洁的结论 八数码问题原始
  • 爬虫技术概览

    爬虫介绍 简介 自动化 半自动化从互联网上采集数据的程序 爬虫框架 一个简单的爬虫框架 外链图片转存失败 源站可能有防盗链机制 建议将图片保存下来直接上传 img 7ifdLU0V 1625273924704 http m qpic cn
  • 怎样在github上发布pre-release和release?

    请参考 xff1a https jingyan baidu com album ad310e80e0c1d11848f49e7f html picindex 61 2 以上是通过网页进行操作的 xff1b 能通过GUI进行操作吗 xff1f
  • git fatal: unrecognized input ^[

    原因是安装了一个vim的插件NREDTREE xff0c 另外需要退出当前用户然后重新登录
  • keil main之前执行过程

    硬件复位后 第一步是执行复位处理程序 这个程序的入口在启动代码里 默认 摘录一段cortex m3的复位处理入口代码 Reset Handler PROC PROC等同于FUNCTION 表示一个函数的开始 与ENDP相对 EXPORT R
  • 蓝牙物理链路类型:SCO和ACL链路与A2DP

    转载于https blog csdn net wenzongliang article details 84689377 蓝牙链路分两种同步链路 SCO 和异步链路 xff08 ACL xff09 A2DP xff08 Advanced A
  • FreeRTOS源码分析-异常处理

    asm void vPortSVCHandler void PRESERVE8 ldr r3 61 pxCurrentTCB Restore the context ldr r1 r3 Use pxCurrentTCBConst to ge
  • FreeRTOS源码分析-代码结构

    FreeRTOS作为开源的轻量级实时性操作系统 xff0c 不仅实现了基本的实时调度 信号量 队列和存储管理 xff0c 而且在商业应用上不需要授权费 FreeRTOS的实现主要由list c queue c croutine c和task
  • 建站基础:WordPress安装教程图解

    http www metsky com archives 430 html 本文介绍WordPress xff08 WP xff09 安装方法 xff0c 虽然很多IDC都会主动帮站长安装 xff0c 安装过程也很简单 xff0c 但毕竟是
  • 国内众筹

    http www zhihu com question 21022884 rf 61 20050061 非股权众筹网站 xff1a 点名时间 中国最大众筹平台 支持创新的力量 国内领先的众筹网站 xff0c 主打科技新硬件的综合类众筹网站
  • I2C slave address

    1 同一 I2C bus device 之 I2C slaver address 不可一样 2 检查 这些 devices 是否可以变更 I2C slaver address hardware pin control or software
  • FreeRTOS Task switch

    vTaskSwitchContext中看pxCurrentTCB traceTASK SWITCHED OUT 切出 taskSELECT HIGHEST PRIORITY TASK traceTASK SWITCHED IN 切入新的ta
  • cocoapods install

    http blog csdn net home zhang article details 47317751
  • UITableView

    http www cnblogs com kenshincui p 3931948 html
  • 一些网址

    http www chanpin100 com 点击打开链接
  • win10下的docker桌面端配置ubuntu进行访问

    前言 xff1a win10下安装了docker桌面端 xff0c 想使用linux系统来访问docker 1 win10下docker安装好之后 xff0c 可以直接使用powershell来访问docker环境 xff0c 如下 xff
  • ROS的基本用法二 服务通信

    第一节 xff1a ROS的服务 摘要 xff1a 介绍ROS的服是双向的通信 xff0c 客户端提交 xff0c 服务端处理后返回到客户端 1 理论介绍 自定义数据类型 xff0c 根据自定义数据类型进行处理 xff0c 客户端请求 xf
  • Ubuntu22安装docker-ce

    阿里云 span class token function sudo span span class token function apt get span remove span class token function docker s

随机推荐

  • C语言之字符数组和字符串末尾加‘\0‘情况浅述

    在字符数组中 xff0c 以字符串形式存入 xff0c 机器会自动加上 39 0 xff1b 在字符数组中 xff0c 以字符形式存入 xff0c 机器不会自动加上 39 0 39 在字符串中 xff0c 效果一样 在C语言中 xff1a
  • Ubuntu 16.04+ROS kinetic+rviz模拟turtlebot机器人时出现的问题-

    鉴于ROS kinetic 版本主能兼容 ubuntu 16 04和15 01版本 xff0c 而16 04的版本由于环境比较新 xff0c 感觉还有很多问题需要解决 博主在进行RVIZ模拟仿真机器人跑时 xff0c 出现了以下问题 xff
  • Win10下 Ubuntun1604LTS双系统安装

    1 下载Ubuntu 16 04 https www ubuntu com download alternative downloads 下载 16 04LTS版 2018 03 10 Ubuntu 16 04 4 LTS Ubuntu 1
  • 主祷文

    主 祷 文 我们在天上的父 xff0c 愿人都尊你的名为圣 愿你的国降临 愿你的旨意行在地上 xff0c 如同行在天上 我们日用的饮食 xff0c 今日赐给我们 免我们的债 xff0c 如同我们免了人的债 不叫我们遇见试探 xff0c 救我
  • 嵌入式Linux系统串口通信协议设计

    1 设计基础 这里指的协议是应用层协议 xff0c 针对应用协议的设计 xff0c 需要注意的有几个基本点 xff1a 可识别 xff0c 兼容性 xff0c 访问控制 xff0c 可追溯 xff0c 数据完整性校验 首先是可识别 xff0
  • 什么是导航?导航具有什么样的作用?

    导航 xff08 Navigation xff09 是引导载体从起始点安全 可靠地引导到目的地的过程 xff0c 导航的基本作用就是回答我在哪里 xff1f 通常用载体在空间的即时位置 速度 姿态和航向等参数来描述导航过程 xff0c 这些
  • 一个失败的程序员

    一个失败的程序员 第一次写博客 xff0c 看了别人的很久 xff0c 也想了很久 xff0c 觉得无论文笔有多不好 xff0c 分享的内容有多糟糕 xff0c 都应该有这个勇气迈出第一步 xff0c 记录生活 抒写回忆 xff0c 等到回
  • 学习FreeRTOS前的准备工作

    转自 http bbs armfly com read php tid 61 1552 了解FreeRTOS之前 xff0c 一定要搞清楚FreeRTOS xff0c SafeRTOS和OpenRTOS之间的关系 1 先说FreeRTOS和
  • Linux网络编程(一)

    Linux网络编程博文均选自 unix网络编程 Richard Stevens xff0c 仅限于学习与查漏补缺只用 xff0c 原址 xff1a http blog csdn net hongchangfirst article deta
  • vscode配合gitee同步云设置

    更换开发设备后 xff0c 新安装的vscode软件 xff0c 是没有原先的配置的 xff0c 诸如快捷键 xff0c 快捷代码段生成 安装的各个插件 xff0c 插件的配置等都木大了 xff0c 开发起来会很别扭 xff0c 网上最多的
  • 升压减压以及充电电路设计

    供电电路在整个硬件系统中都是极其重要的 xff0c 只有能产生稳定电压与电流的供电电路才能保证整个硬件系统的正常工作 在本系统中 xff0c STM32F103C8T6需要的电压为3 3V xff0c 同时还有其他的模块需要5V的电压 xf
  • Java枚举详解及常见用法

    1 枚举的使用场景 枚举是一个被命名的整型常数的集合 xff0c 用于声明一组带标识符的常数 枚举在曰常生活中很常见 xff0c 例如一个人的性别只能是 男 或者 女 xff0c 一周的星期只能是 7 天中的一个等 类似这种当一个变量有几种
  • ros编译时与opencv发生冲突的解决办法 opencv_imgcodecs3.so.3.3.1: undefined reference to `TIFFReadDirectory@LIBTIFF

    在编译ros项目的时候 xff0c 遇到下面的错误 xff1a 38 Building CXX object cube slam detect 3d cuboid CMakeFiles detect 3d cuboid dir src ma
  • ROS的一些常用的命令

    下面是ros下面的一些常用操作 xff0c 先做个总结 xff0c 方便后续使用 1 只编译工作空间下面的一个包 catkin make DCATKIN WHITELIST PACKAGES span class token operato
  • realsense相机两种获取相机内外参的方式

    realsense相机出厂的时候一般都标定好了 xff0c 直接读取他们的内参即可 终端输入 xff1a rs sensor control 然后按照提示操作即可 方法 xff1a https blog csdn net mystyle a
  • 【Python开发利器-TKinterDesigner 】 :第一讲:TkinterDesigner的基本功能介绍

    Python开发利器 TKinterDesigner xff1a 第一讲 xff1a TkinterDesigner的基本功能介绍
  • 基于Spine动画的AVATAR换装系统优化

    大家好 xff0c 我是红孩儿 xff0c 目前在玩吧技术专家组负责技术研发工作 xff0c 好久不见 xff0c 作为一名引擎开发者 xff0c 这次我给大家分享一下基于Spine动画的AVATAR换装优化 xff0c 希望能够对有类似需
  • TKinterDesigner v1.6.4 前瞻- 即将开启Python移动开发时代

    TKinterDesigner v1 6 4 前瞻 即将开启Python移动开发时代 我想 xff1a 这可能是一个新时代的开启吧
  • TKinterDesigner从入门到精通视频教程

    想使用TKinter开发桌面应用 xff1f 想使用TKinter开发移动应用 xff1f TKinterDesigner来帮助你吧 xff01 欢迎使用TKinterDesigner xff01 以下是 TKinterDesigner从入
  • 房卡麻将分析系列 "牌局回放" 之 播放处理

    持续放出房卡麻将设计与研发讲解 敬请关注微信共众号 xff1a 红孩儿的游戏开发之路 房卡麻将分析系列 34 牌局回放 34 之 播放处理 昨天红孩儿给大伙讲了讲 牌局回放 的数据记录处理 xff0c 有了数据的存储 xff0c 下面就是数