全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

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

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

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

          实话讲,好久没用过 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++; 
  ... 
} 


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

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


# 牌局回放  # 麻将牌局回放的功能  # 房卡麻将分析系列 "牌局回放" 之 数据设计详解及实例  # 麻将游戏算法深入解析及实现代码  # 客户端  # 可以看到  # 会再  # 会向  # 会在  # 这条  # 希望能  # 这样一个  # 想看  # 来做  # 这套  # 谢谢大家  # 转化为  # 讲了  # 数据库中  # 好后  # 中与  # 存储过程  # 有一个  # 没用过 


相关文章: 平台云上自主建站:模板化设计与智能工具打造高效网站  如何批量查询域名的建站时间记录?  建站之星如何实现PC+手机+微信网站五合一建站?  建站主机解析:虚拟主机配置与服务器选择指南  建站之星图片链接生成指南:自助建站与智能设计教程  网站制作大概多少钱一个,做一个平台网站大概多少钱?  内网网站制作软件,内网的网站如何发布到外网?  如何在自有机房高效搭建专业网站?  郑州企业网站制作公司,郑州招聘网站有哪些?  北京网站制作的公司有哪些,北京白云观官方网站?  美食网站链接制作教程视频,哪个教做美食的网站比较专业点?  已有域名能否直接搭建网站?  PHP正则匹配日期和时间(时间戳转换)的实例代码  制作电商网页,电商供应链怎么做?  如何通过智能用户系统一键生成高效建站方案?  江苏网站制作公司有哪些,江苏书法考级官方网站?  我的世界制作壁纸网站下载,手机怎么换我的世界壁纸?  关于BootStrap modal 在IOS9中不能弹出的解决方法(IOS 9 bootstrap modal ios 9 noticework)  建站之星安装步骤有哪些常见问题?  广州网站制作公司哪家好一点,广州欧莱雅百库网络科技有限公司官网?  存储型VPS适合搭建中小型网站吗?  建站主机助手选型指南:2025年热门推荐与高效部署技巧  个人网站制作流程图片大全,个人网站如何注销?  网站制作的方法有哪些,如何将自己制作的网站发布到网上?  如何将凡科建站内容保存为本地文件?  如何高效利用亚马逊云主机搭建企业网站?  家庭服务器如何搭建个人网站?  C++如何将C风格字符串(char*)转换为std::string?(代码示例)  手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?  宁波免费建站如何选择可靠模板与平台?  如何挑选优质建站一级代理提升网站排名?  c++怎么编写动态链接库dll_c++ __declspec(dllexport)导出与调用【方法】  建站主机服务器选购指南:轻量应用与VPS配置解析  c++如何打印函数堆栈信息_c++ backtrace函数与符号名解析【方法】  如何通过虚拟主机空间快速建站?  建站之星CMS五站合一模板配置与SEO优化指南  微网站制作教程,不会写代码,不会编程,怎么样建自己的网站?  网站制作中优化长尾关键字挖掘的技巧,建一个视频网站需要多少钱?  高防服务器如何保障网站安全无虞?  制作农业网站的软件,比较好的农业网站推荐一下?  seo网站制作优化,网站SEO优化步骤有哪些?  电商平台网站制作流程,电商网站如何制作?  广州网站制作的公司,现在专门做网站的公司有没有哪几家是比较好的,性价比高,模板也多的?  网站制作价目表怎么做,珍爱网婚介费用多少?  图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?  Android自定义控件实现温度旋转按钮效果  网站app免费制作软件,能免费看各大网站视频的手机app?  北京营销型网站制作公司,可以用python做一个营销推广网站吗?  php能控制zigbee模块吗_php通过串口与cc2530 zigbee通信【介绍】  如何通过多用户协作模板快速搭建高效企业网站? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。