#include "WN_GameScene.h" #include "cocostudio/CocoStudio.h" #include "SimpleAudioEngine.h" #include "Utility.h" #include "MainScene.h" #include "PopScene.h" #include "MissionWeiXin.h" #include "JniFun.h" #include "DismissScene.h" #include "UserInfo.h" #include "ImagicDownManager.h" #include "SetScene.h" #include "PlayerScene.h" #include "AutoReadyScene.h" using namespace WNMJ_SPACE; WN_GameScene::WN_GameScene() { m_pCardManager = nullptr; // 麻将管理类 m_pRootLayout = nullptr; // 根场景 m_pResultLayer = nullptr; // 结算面板 m_pPrivateScene = nullptr; // 私人场面板 m_pBtnLeave = nullptr; // 离开按钮 m_pBtnReady = nullptr; m_pBtnStartGame = nullptr; m_SpriteTimer = nullptr; // 时间界面 m_LableTime = nullptr; // 时间数字 m_ptxtCardNum = nullptr; // 剩余牌数量 m_btnDismiss = nullptr; // 解散房间 m_btnWeiXin = nullptr; // 微信分享按钮 m_pVoiceNode = nullptr; // 语音标志 m_txtRoomID = nullptr; // 房间号 m_txtGameTimes = nullptr; // 游戏局数 m_lBaseScore = 0; // 基础积分 m_cbGameStatus = GS_MJ_NULL; // 游戏状态 m_cbSurplusCard = MAX_REPERTORY; // 剩余牌数量 zeromemory(m_ptStartCard, sizeof(m_ptStartCard)); // 每个玩家第一张手牌 zeromemory(m_ptOutCard, sizeof(m_ptOutCard)); // 每个玩家第一张出牌 zeromemory(m_ptCurrentCard, sizeof(m_ptCurrentCard)); // 每个玩家当前出牌 zeromemory(m_ptWeaveCard, sizeof(m_ptWeaveCard)); // 每个玩家组合牌坐标 zeromemory(m_aryPlayer, sizeof(m_aryPlayer)); zeromemory(m_bActiveStatus, sizeof(m_bActiveStatus)); m_wBankerUser = INVALID_CHAIR; // 庄家用户 m_wCurrentUser = INVALID_CHAIR; // 当前用户 m_wEastUser = INVALID_CHAIR; // 东方位玩家 zeromemory(m_wUserPosition, sizeof(m_wUserPosition)); // 方位旋转角度 //发牌数据 zeromemory(m_cbSelfHandCardData, sizeof(m_cbSelfHandCardData)); // 初始化发牌数据 //定时器 m_nVoiceTimeID = 0; // 语音定时器ID m_dwTimerID = IDI_NULL; // 定时器ID m_nSecondCount = 0; // 当前计数 m_wTimeChairID = INVALID_CHAIR; // 正在计数玩家 // 规则; m_ptxtCardNum = nullptr; m_txtGameRule = nullptr; m_txtGameRuleScore = nullptr; m_txtGangRule = nullptr; m_strGameTitle = ""; m_strGameRuleInfo = ""; zeromemory(&m_PrivateRoomInfo, sizeof(m_PrivateRoomInfo)); m_IsRunEndAction = false; } WN_GameScene::~WN_GameScene() { } bool WN_GameScene::InitGameEvent() { addNetCBDefine(SUB_S_GAME_START, this, WN_GameScene::OnSubGameStart); // 游戏开始 addNetCBDefine(SUB_S_OUT_CARD, this, WN_GameScene::OnSubOutCard); // 玩家出牌 addNetCBDefine(SUB_S_SEND_CARD, this, WN_GameScene::OnSubSendCard); // 玩家摸牌 addNetCBDefine(SUB_S_OPERATE_NOTIFY, this, WN_GameScene::OnSubOperateNotify); // 操作提示 addNetCBDefine(SUB_S_OPERATE_RESULT, this, WN_GameScene::OnSubOperateResult); // 操作结果 addNetCBDefine(SUB_S_GAME_END, this, WN_GameScene::OnSubGameEnd); // 游戏结束 addNetCBDefine(SUB_S_MASTER_LEFTCARD, this, WN_GameScene::OnSubGetLeftCard); // 获取排堆 return true; } bool WN_GameScene::init() { if (!GameFrameBase::init()) { return false; } /***************************** 增加界面管理 *******************************************/ // 主界面 m_pRootLayout = static_cast(CSLoader::createNode("Games/WNMJ/GameScene.csb")); this->addChild(m_pRootLayout, ZO_DEFAULT); // 麻将管理 m_PanelCard = (Layout*)m_pRootLayout->getChildByName("PanelCard"); CC_ASSERT(m_PanelCard != nullptr); m_pCardManager = WN_CardManager::create(); m_PanelCard->addChild(m_pCardManager); // 结算面板 m_pResultLayer = WN_GameOver::create(); m_pResultLayer->setVisible(false); this->addChild(m_pResultLayer, ZO_END); // 私人场面皮 m_pPrivateScene = WN_PrivateScene::create(); m_pPrivateScene->setVisible(false); this->addChild(m_pPrivateScene, ZO_PRIVATE); /***************************** 主界面初始化 *******************************************/ // 房间号 m_txtRoomID = (Text*)m_pRootLayout->getChildByName("txtRoomID"); CC_ASSERT(m_txtRoomID != nullptr); m_txtRoomID->setVisible(false); // 游戏局数 m_txtGameTimes = (Text*)m_pRootLayout->getChildByName("txtGameTimes"); CC_ASSERT(m_txtGameTimes != nullptr); m_txtGameTimes->setVisible(false); //微信分享按钮 m_btnWeiXin = (Button*)m_pRootLayout->getChildByName("btnWeiXin"); CC_ASSERT(m_btnWeiXin != nullptr); m_btnWeiXin->setVisible(false); m_btnWeiXin->addClickEventListener(CC_CALLBACK_1(WN_GameScene::ShowRoomID, this)); // 语音标志 m_pVoiceNode = (Node*)m_pRootLayout->getChildByName("VoiceNode"); CC_ASSERT(m_pVoiceNode != nullptr); m_pVoiceNode->setVisible(false); //语音按钮 auto btnVoice = (Button*)m_pRootLayout->getChildByName("btnVoice"); CC_ASSERT(btnVoice != nullptr); //注册触摸事件 btnVoice->addTouchEventListener(CC_CALLBACK_2(WN_GameScene::OnButtonVoiceTouched, this)); // 菜单按钮; m_BtnMenu = (Button*)m_pRootLayout->getChildByName("btnMenu"); CC_ASSERT(m_BtnMenu != nullptr); m_BtnMenu->addClickEventListener([=](Ref*){ if (m_ImageMenu) { bool bVisble = !m_ImageMenu->isVisible(); m_ImageMenu->setVisible(bVisble); } }); // 菜单; m_ImageMenu = (ImageView*)m_pRootLayout->getChildByName("Image_menu"); CC_ASSERT(m_ImageMenu != nullptr); m_ImageMenu->setVisible(false); // 解散房间函数 auto callback = [this](){ onEventAgreeDismissRoom(true); }; // 离开按钮; m_btnDismiss = (Button*)m_ImageMenu->getChildByName("btnDismiss"); CC_ASSERT(m_btnDismiss != nullptr); m_btnDismiss->setVisible(false); m_btnDismiss->addClickEventListener([=](Ref *pSender){ YSAudioEngine::Instance().playBtnClickEffect(); std::string strTip; if (0 == m_PrivateRoomInfo.dwPlayCout && false == m_PrivateRoomInfo.bStartGame) { strTip = "解散房间不扣房卡,是否解散?"; } else { strTip = "您确定要解散房间吗?"; } PopScene::Instance().show(utility::a_u8(strTip.c_str()), callback, nullptr); }); // 离开按钮 m_pBtnLeave = (Button*)m_ImageMenu->getChildByName("btnLeave"); m_pBtnLeave->addClickEventListener(CC_CALLBACK_1(WN_GameScene::onLeaveClickEvent, this)); // 设置按钮 auto btnSet = (Button*)m_ImageMenu->getChildByName("btnSet"); ASSERT(btnSet); btnSet->addClickEventListener([this](Ref*){ YSAudioEngine::Instance().playBtnClickEffect(); TipNode* pNode = SetScene::create(); CC_ASSERT(pNode != nullptr); this->addChild(pNode, ZO_TRUSTEE); pNode->pushScene(); }); // 设置按钮 auto btnChat = (Button*)m_pRootLayout->getChildByName("btnChat"); ASSERT(btnChat); btnChat->addClickEventListener([this](Ref*){ YSAudioEngine::Instance().playBtnClickEffect(); const std::vector& chatList = getShortChatList(); TipNode* pNode = ChatLayer::create(chatList); CC_ASSERT(pNode != nullptr); this->addChild(pNode, ZO_TRUSTEE); pNode->pushScene(); }); // 公告; m_SystemInfo = (ImageView*)m_pRootLayout->getChildByName("PanelGongGao"); CC_ASSERT(m_SystemInfo); SetSystemNode(m_SystemInfo); // 获取网络延迟控件 m_txtNetWorkTime = (Text*)m_pRootLayout->getChildByName("txtNetWorkTime"); CC_ASSERT(m_txtNetWorkTime); // 初始化 this->uiLayerinit(); this->InitGameEvent(); this->onPlayerGetCard(); //对手机返回键的监听 auto keyListener = EventListenerKeyboard::create(); keyListener->onKeyReleased = CC_CALLBACK_2(WN_GameScene::onKeyReleased, this); _eventDispatcher->addEventListenerWithSceneGraphPriority(keyListener, this); loadShortChat("Platform/gamelist/ChatInfo.json"); return true; } //按键处理 void WN_GameScene::onKeyReleased(EventKeyboard::KeyCode keyCode, Event * pEvent) { //返回值处理 if (keyCode == EventKeyboard::KeyCode::KEY_ESCAPE) { YSAudioEngine::Instance().playBtnClickEffect(); #if CC_PLATFORM_WIN32 == CC_TARGET_PLATFORM if (m_kGameMission.isAlive()) { m_kGameMission.stop(); } else { this->ReconnectServer(); } return; #endif // 显示解散房间 if (m_btnDismiss->isVisible()) { // 解散房间函数 auto callback = [this](){ onEventAgreeDismissRoom(true); }; std::string strTip; if (0 == m_PrivateRoomInfo.dwPlayCout && false == m_PrivateRoomInfo.bStartGame) { strTip = "解散房间不扣房卡,是否解散?"; } else { strTip = "您确定要解散房间吗?"; } PopScene::Instance().show(utility::a_u8(strTip.c_str()), callback, nullptr); } else if (m_pBtnLeave->isVisible()) { GamePlayer* pGamePlayer = getSelfGamePlayer(); auto callback_ok = [=](){ if (pGamePlayer != nullptr) { CMD_GR_UserStandUp request; memset(&request, 0, sizeof(request)); request.wTableID = pGamePlayer->GetTableID(); request.wChairID = pGamePlayer->GetChairID(); request.cbForceLeave = true; SendUserData(SUB_GR_USER_STANDUP, &request, sizeof(request)); } this->runAction(Sequence::createWithTwoActions(DelayTime::create(0.2f), CallFunc::create([=]{ Director::getInstance()->getEventDispatcher()->dispatchCustomEvent(LEAVE_GAME); }))); }; if (m_cbGameStatus != GS_MJ_FREE) { PopScene::Instance().show(utility::a_u8("您正在游戏中,强行退出会被扣分,确定要强退吗?"), callback_ok, nullptr); } else { callback_ok(); } } } } void WN_GameScene::onEnterTransitionDidFinish() { GameFrameBase::onEnterTransitionDidFinish(); // 私人场不设置定时器 m_dwTimerID = IDI_NULL; m_nSecondCount = 0; schedule(schedule_selector(WN_GameScene::OnEventGameClock), 1.0f); //// 暂时停了测试 //CocosDenshion::SimpleAudioEngine::getInstance()->stopBackgroundMusic(true); //切换背景音乐 PlayBackMusic(EF_BackGround_Normal, true); // 录像模式; if (m_IsGameRecord) { StartRecord(GAME_PLAYER); } else { // 增加游戏内事件处理 auto dispatcher = Director::getInstance()->getEventDispatcher(); dispatcher->addCustomEventListener(NJSP_START_GAME, CC_CALLBACK_1(WN_GameScene::onStartClickEvent, this)); dispatcher->addCustomEventListener(SHOW_PRIVATE_END, CC_CALLBACK_1(WN_GameScene::onEventShowPrivate, this)); dispatcher->addCustomEventListener(CUSTOM_EVENT_OUT_CARD, CC_CALLBACK_1(WN_GameScene::onEventOutCard, this)); dispatcher->addCustomEventListener(CUSTOM_EVENT_OPER_CARD, CC_CALLBACK_1(WN_GameScene::onEventOperCard, this)); dispatcher->addCustomEventListener(CUSTOM_EVENT_GET_CARD, CC_CALLBACK_1(WN_GameScene::onEventGetCard, this)); CGameServerItem* pGameServerItem = GameMission::g_pGameServerItem; CC_ASSERT(pGameServerItem != nullptr); if (pGameServerItem != nullptr) { m_kGameMission.SetServerItem(pGameServerItem); m_kGameMission.start(); } } } void WN_GameScene::onExit() { GameFrameBase::onExit(); auto dispatcher = Director::getInstance()->getEventDispatcher(); dispatcher->removeCustomEventListeners(NJSP_START_GAME); dispatcher->removeCustomEventListeners(CUSTOM_EVENT_OUT_CARD); dispatcher->removeCustomEventListeners(CUSTOM_EVENT_OPER_CARD); dispatcher->removeCustomEventListeners(SHOW_PRIVATE_END); dispatcher->removeCustomEventListeners(CUSTOM_EVENT_GET_CARD); // 关闭定时器 m_dwTimerID = IDI_NULL; m_nSecondCount = 0; unschedule(schedule_selector(WN_GameScene::OnEventGameClock)); unschedule(schedule_selector(WN_GameScene::UpdateSystmeTime)); // 关闭网络 m_kGameMission.stop(); // 清理控件 m_pPrivateScene->removeFromParentAndCleanup(true); m_pPrivateScene = nullptr; m_pResultLayer->removeFromParentAndCleanup(true); m_pResultLayer = nullptr; m_pRootLayout->removeFromParentAndCleanup(true); m_pRootLayout = nullptr; } void WN_GameScene::ResetTable() { ResetScene(); ResetAllData(); // 从后台返回前台重置当前时间; if (m_txtCurrentTime) { std::string strSystemTime = JniFun::getSystemTime(); m_txtCurrentTime->setString(strSystemTime); } } void WN_GameScene::upSelfPlayerInfo() { } // 重置场景; void WN_GameScene::ResetScene() { this->stopAllActions(); //重置玩家UI; for (uint8 i = 0; i < GAME_PLAYER; i++) { m_aryPlayer[i]->resetUI(true); } } // 重置所有数据 void WN_GameScene::ResetAllData() { // 关闭定时器 KillGameClock(); m_cbGameStatus = GS_MJ_FREE; // 游戏状态 m_wBankerUser = INVALID_CHAIR; // 庄家用户 m_wCurrentUser = INVALID_CHAIR; // 当前用户 m_wEastUser = INVALID_CHAIR; // 东方位玩家 m_cbSurplusCard = MAX_REPERTORY; // 剩余牌数量 m_ptxtCardNum->setString("00"); // 剩余牌数量 zeromemory(m_cbSelfHandCardData, sizeof(m_cbSelfHandCardData)); //发牌数据 zeromemory(m_bActiveStatus, sizeof(m_bActiveStatus)); if (m_pCardManager) m_pCardManager->ResetAll(); // 麻将管理 if (m_pResultLayer) m_pResultLayer->setVisible(false); // 结束界面 //重置玩家UI; for (uint8 i = 0; i < GAME_PLAYER; i++) { m_aryPlayer[i]->resetUI(false); } AutoReadyScene::Instance().hide(); m_IsRunEndAction = false; } // 界面初始化 void WN_GameScene::uiLayerinit() { // 准备按钮; m_pBtnReady = (Button*)m_pRootLayout->getChildByName("btnReady"); ASSERT(m_pBtnReady); m_pBtnReady->setVisible(false); m_pBtnReady->addClickEventListener([this](Ref* ref){ YSAudioEngine::Instance().playBtnClickEffect(); onStartClickEvent(ref); m_pBtnReady->setVisible(false); }); // 准备按钮; m_pBtnStartGame = (Button*)m_pRootLayout->getChildByName("btnStartGame"); ASSERT(m_pBtnStartGame); m_pBtnStartGame->setVisible(false); m_pBtnStartGame->addClickEventListener([this](Ref* ref){ YSAudioEngine::Instance().playBtnClickEffect(); // 发送可以开始游戏请求; bool bAutoReady = true; m_kGameMission.SendSocketData(MDM_GF_FRAME, SUB_GF_USER_START_READY, &bAutoReady, sizeof(bAutoReady)); m_pBtnStartGame->setVisible(false); }); // 玩家信息 string ctrlID = ""; for (int i = 0; i < GAME_PLAYER; ++i) { // 准备 ctrlID = StringUtils::format("Ready_%d", i); auto pReadys = (Sprite*)m_pRootLayout->getChildByName(ctrlID); CC_ASSERT(pReadys!=nullptr); pReadys->setVisible(false); m_ptCurrentCard[i] = pReadys->getPosition(); // 用准备的坐标 // 玩家 ctrlID = StringUtils::format("Player_%d", i); auto player = (Node*)m_pRootLayout->getChildByName(ctrlID); CC_ASSERT(player != nullptr); if (player == nullptr) continue; // 初始化玩家气泡; m_aryPlayer[i] = new WNGamePlayer(i, player, pReadys); auto btnNode = (Button*)player->getChildByName("btnNode"); if (btnNode != nullptr) { btnNode->addClickEventListener([=](Ref* pSender){ if ((m_aryPlayer[i] != nullptr) && m_aryPlayer[i]->getUserItem(false) != nullptr) { PlayerScene* playerScene = PlayerScene::create(); playerScene->showPlayerInfo(m_aryPlayer[i]); this->addChild(playerScene, ZO_TRUSTEE); } }); } // 牌坐标 ctrlID = __String::createWithFormat("Stand_%d", i)->getCString(); Sprite* StandCard = (Sprite*)m_PanelCard->getChildByName(ctrlID); m_ptStartCard[i] = StandCard->getPosition(); StandCard->removeFromParent(); // 出牌 ctrlID = __String::createWithFormat("Out_%d", i)->getCString(); Sprite* OutCard = (Sprite*)m_PanelCard->getChildByName(ctrlID); m_ptOutCard[i] = OutCard->getPosition(); OutCard->removeFromParent(); // 打牌位置; ctrlID = __String::createWithFormat("Node_%d", i)->getCString(); Node* playerend = (Node*)m_pRootLayout->getChildByName(ctrlID); m_ptPlayerEnd[i] = playerend->getPosition(); playerend->removeFromParent(); } // 将麻将坐标传递给麻将管理类 memcpy(m_pCardManager->m_ptStartCard, m_ptStartCard, sizeof(m_ptStartCard)); memcpy(m_pCardManager->m_ptOutCard, m_ptOutCard, sizeof(m_ptOutCard)); memcpy(m_pCardManager->m_ptCurrentCard, m_ptCurrentCard, sizeof(m_ptCurrentCard)); memcpy(m_pCardManager->m_ptWeaveCard, m_ptStartCard, sizeof(m_ptWeaveCard)); // 时间界面 //m_SpriteTimeBg = (Sprite*)m_pRootLayout->getChildByName("paizhuo"); //ASSERT(m_SpriteTimeBg != nullptr); //m_SpriteTimeBg->setVisible(false); m_SpriteTimer = (Sprite*)m_pRootLayout->getChildByName("TimerCenter"); ASSERT(m_SpriteTimer != nullptr); m_SpriteTimer->setVisible(false); for (int i = 0; i < GAME_PLAYER; i++) { ctrlID = __String::createWithFormat("xz_clock_%d", i)->getCString(); Sprite* sp_clock = (Sprite*)m_SpriteTimer->getChildByName(ctrlID); sp_clock->setVisible(false); } Layout* PanelTimer = (Layout*)m_pRootLayout->getChildByName("PanelTimer"); if (PanelTimer) { m_LableTime = LabelAtlas::create("00", "Games/WNMJ/game/Timer_num.png", 23, 38, '0'); m_LableTime->setAnchorPoint(Point(0.5, 0.5)); m_LableTime->setPosition(Point(PanelTimer->getContentSize().width / 2, PanelTimer->getContentSize().height / 2)); m_LableTime->setVisible(false); PanelTimer->addChild(m_LableTime); } // 旋转方位 m_wUserPosition[0] = 270; m_wUserPosition[1] = 0; m_wUserPosition[2] = 90; m_wUserPosition[3] = 180; // 剩余张数 m_ptxtCardNum = (Text*)m_pRootLayout->getChildByName("AtlasLabel"); m_ptxtCardNum->setVisible(false); m_txtGameRule = (Text*)m_pRootLayout->getChildByName("txtGameRule"); m_txtGameRule->setVisible(false); m_txtGameRuleScore = (Text*)m_pRootLayout->getChildByName("txtGameRuleScore"); m_txtGameRuleScore->setVisible(false); m_txtGangRule = (Text*)m_pRootLayout->getChildByName("txtGangRule"); m_txtGangRule->setVisible(false); // 设置当前时间; m_txtCurrentTime = (Text*)m_pRootLayout->getChildByName("txtCurrentTime"); if (m_txtCurrentTime) { std::string strSystemTime = JniFun::getSystemTime(); m_txtCurrentTime->setString(strSystemTime); schedule(schedule_selector(WN_GameScene::UpdateSystmeTime), 10.0f); } // 设置版本号 auto txtVersion = (Text*)m_pRootLayout->getChildByName("txtVersion"); CC_ASSERT(txtVersion != nullptr); std::string strLocalVer = JniFun::getVersionName(); txtVersion->setString(strLocalVer); } // 椅子号视图转换 WORD WN_GameScene::SwitchViewChairID(WORD wChairID) { //参数判断 if (wChairID == INVALID_CHAIR) return INVALID_CHAIR; WORD wSelfChairID = getSelfChairID(); if (wSelfChairID == INVALID_CHAIR) return INVALID_CHAIR; WORD wViewChairID = INVALID_CHAIR; //转换椅子 if ((m_PrivateRoomInfo.bGameRuleIdex&eWNMJRuleEnum_PlayCount2) != 0) { if (wSelfChairID == wChairID) { return SELF_VIEW_CHAIRID; } else { return 0; } } else if ((m_PrivateRoomInfo.bGameRuleIdex&eWNMJRuleEnum_PlayCount3) != 0) { //转换椅子; WORD wChairCount = (GAME_PLAYER - 1); wViewChairID = (wChairID + wChairCount * 3 / 2 - wSelfChairID) % wChairCount; wViewChairID += 1; // 0位置不做人,所以要偏1个位置 ASSERT(wViewChairID < GAME_PLAYER); } //else if ((m_PrivateRoomInfo.bGameRuleIdex&eWNMJRuleEnum_PlayCount_auto) != 0) //{ // WORD wRealChairCount = GetRealChairCount(); // // if (wRealChairCount == 2) // { // if (wSelfChairID == wChairID) // { // return SELF_VIEW_CHAIRID; // } // else // { // return 0; // } // } // else if (wRealChairCount == 3) // { // //转换椅子; // wViewChairID = (wChairID + GAME_PLAYER * 3 / 2 - wSelfChairID) % GAME_PLAYER; // ASSERT(wViewChairID < GAME_PLAYER); // // // 如果座位是0,进行二次调整; // if (wViewChairID == 0) // { // // 座位使用情况; // bool bArrViewChairID[GAME_PLAYER] = { false, false, false, false }; // for (WORD j = 0; j < GAME_PLAYER; j++) // { // if (!m_bActiveStatus[j]) continue; // WORD wChairCount = GAME_PLAYER; // WORD wTmpViewChairID = (wChairID + wChairCount * 3 / 2 - wSelfChairID) % wChairCount; // bArrViewChairID[wTmpViewChairID] = true; // } // WORD n = 0; // 未使用的座位; // for (WORD n = 0; n < GAME_PLAYER; n++) // { // if (!bArrViewChairID[n]) // { // break; // } // } // wViewChairID = n; // } // } // else // { // WORD wChairCount = GAME_PLAYER; // wViewChairID = (wChairID + wChairCount * 3 / 2 - wSelfChairID) % wChairCount; // } // return wViewChairID; //} else { WORD wChairCount = GAME_PLAYER; wViewChairID = (wChairID + wChairCount * 3 / 2 - wSelfChairID) % wChairCount; } return wViewChairID; } // 真实椅子数量 uint16 WN_GameScene::GetRealChairCount() { if ((m_PrivateRoomInfo.bGameRuleIdex&eWNMJRuleEnum_PlayCount2) != 0) { return 2; } else if ((m_PrivateRoomInfo.bGameRuleIdex&eWNMJRuleEnum_PlayCount3) != 0) { return 3; } else if ((m_PrivateRoomInfo.bGameRuleIdex&eWNMJRuleEnum_PlayCount_auto) != 0) { WORD wRealChairCount = 0; for (int i = 0; i < GAME_PLAYER; i++) { if (m_bActiveStatus[i]) { wRealChairCount++; } } return wRealChairCount; } return GAME_PLAYER; } // 设置当前玩家 void WN_GameScene::SetCurrentUser(WORD wCurrentUser) { m_wCurrentUser = wCurrentUser; if (m_pCardManager) { m_pCardManager->SetCurrentUser(SwitchViewChairID(wCurrentUser)); } } /**************************************************** 按钮点击事件处理 BEGIN ****************************************************/ // 玩家离开 void WN_GameScene::onLeaveClickEvent(cocos2d::Ref *pSender) { YSAudioEngine::Instance().playBtnClickEffect(); GamePlayer* pGamePlayer = getSelfGamePlayer(); auto callback_ok = [=](){ if (pGamePlayer != nullptr) { CMD_GR_UserStandUp request; memset(&request, 0, sizeof(request)); request.wTableID = pGamePlayer->GetTableID(); request.wChairID = pGamePlayer->GetChairID(); request.cbForceLeave = true; SendUserData(SUB_GR_USER_STANDUP, &request, sizeof(request)); } this->runAction(Sequence::createWithTwoActions(DelayTime::create(0.2f), CallFunc::create([=]{ Director::getInstance()->getEventDispatcher()->dispatchCustomEvent(LEAVE_GAME); }))); }; if (m_cbGameStatus != GS_MJ_FREE) { PopScene::Instance().show(utility::a_u8("您正在游戏中,强行退出会被扣分,确定要强退吗?"), callback_ok, nullptr); } else { callback_ok(); } } // 开始游戏 void WN_GameScene::onStartClickEvent(cocos2d::Ref *pSender) { //ResetAllData(); this->stopAllActions(); if (m_pResultLayer) { m_pResultLayer->ResetDlg(); m_pResultLayer->stopAllActions(); } //// 自由场并且游戏没开始; //if (!m_PrivateRoomInfo.bStartGame && (m_PrivateRoomInfo.bGameRuleIdex&eWNMJRuleEnum_PlayCount_auto) != 0) //{ // ResetAllData(); // // 申请准备; // m_kGameMission.SendSocketData(MDM_GF_FRAME, SUB_GF_USER_START_READY, 0, 0); // //m_kGameMission.SendSocketData(MDM_GR_PRIVATE, SUB_GR_PRIVATE_DISMISS, &kNetInfo, sizeof(kNetInfo)); //} //else { // 发送准备消息 SendUserReady(); } } /**************************************************** 网络消息处理 BEGIN ****************************************************/ //场景消息 bool WN_GameScene::OnEventSceneMessage(uint8 cbGameStatus, bool bLookonUser, void* data, int dataSize) { log("OnEventSceneMessage State:%d", cbGameStatus); switch (cbGameStatus) { case GS_MJ_FREE: { CMD_S_StatusFree * pStatusFree = (CMD_S_StatusFree *)data; onGameSceneFree(pStatusFree); break; } case GS_MJ_PLAY: { CMD_S_StatusPlay* pStatusPlay = (CMD_S_StatusPlay*)data; onGameScenePlay(pStatusPlay); break; } default: m_cbGameStatus = GS_MJ_NULL; break; } // 权限在玩家登陆成功之后才能获得; onPlayerGetCard(); return true; } // 空闲场景 void WN_GameScene::onGameSceneFree(CMD_S_StatusFree* pStatusFree) { //设置数据 m_cbGameStatus = GS_MJ_FREE; m_wEastUser = 0; } // 游戏场景 void WN_GameScene::onGameScenePlay(CMD_S_StatusPlay* pStatusPlay) { //重置变量 ResetAllData(); //删除定时器 KillGameClock(); //初始UI; onGameStartInitUI(false); m_pBtnReady->setVisible(false); //设置变量 m_cbGameStatus = GS_MJ_PLAY; m_wBankerUser = pStatusPlay->wBankerUser; CopyMemory(m_bActiveStatus, pStatusPlay->bActiveStatus, sizeof(m_bActiveStatus)); // 当前出牌用户 SetCurrentUser(pStatusPlay->wCurrentUser); if (m_wEastUser == INVALID_CHAIR) { // 东家显示 m_wEastUser = 0; SetTimerByEast(m_wEastUser); } //辅助变量 WORD wArrViewChairID[GAME_PLAYER] = { INVALID_CHAIR, INVALID_CHAIR, INVALID_CHAIR, INVALID_CHAIR }; for (WORD j = 0; j < GAME_PLAYER; j++) { if (!m_bActiveStatus[j]) continue; wArrViewChairID[j] = SwitchViewChairID(j); } m_pCardManager->SetActiveStatus(m_bActiveStatus, wArrViewChairID, GetRealChairCount()); // 自己椅子号 WORD wSelfChairID = getSelfChairID(); // 庄家设置 WORD wBankerUser = wArrViewChairID[m_wBankerUser]; if (wBankerUser != INVALID_CHAIR && m_aryPlayer[wBankerUser] != nullptr) { m_aryPlayer[wBankerUser]->setZhuangVisible(true); } // 玩家信息 for (WORD i = 0; i < GAME_PLAYER; i++) { if (m_bActiveStatus[i] == false) continue; GamePlayer* pPlayer = getPlayerByChairID(i); if (pPlayer == nullptr)continue; WORD wViewChairID = wArrViewChairID[i]; if (wViewChairID == INVALID_CHAIR) continue; // 组合牌 m_pCardManager->SceneWeaveCard(wViewChairID, pStatusPlay->cbWeaveCount[i], pStatusPlay->WeaveItemArray[i], wArrViewChairID); //丢弃牌 m_pCardManager->SceneOutCard(wViewChairID, pStatusPlay->cbDiscardCount[i], pStatusPlay->cbDiscardCard[i]); } // 当前出牌 if (pStatusPlay->cbOutCardData != 0 && pStatusPlay->wOutCardUser != INVALID_CHAIR) { //变量定义 WORD wOutViewChairID = SwitchViewChairID(pStatusPlay->wOutCardUser); m_pCardManager->ShowCurrentCard(wOutViewChairID, pStatusPlay->cbOutCardData); } /***************************** 手牌设置必须在组合牌之后,这样位置定位才准确 *******************************************/ // 自己手牌数据十四张牌 if (pStatusPlay->cbSendCardData != 0x0 && wSelfChairID == m_wCurrentUser) { //调整牌 把第十四张牌从手牌中删除再显示 BYTE cbCardCount = 0; //牌数量 BYTE cbSendCardData = pStatusPlay->cbSendCardData; //当前发牌 BYTE cbTmpCardData[MAX_COUNT]; //临时牌列表 zeromemory(cbTmpCardData, sizeof(cbTmpCardData)); for (int h = 0; h < pStatusPlay->cbCardCount; h++) { // 找到当前发牌 if (cbSendCardData != pStatusPlay->cbCardData[h]) { cbTmpCardData[cbCardCount++] = pStatusPlay->cbCardData[h]; } else { cbSendCardData = 0x0; // 出现一次就设置为0,后面不再过滤 } } m_pCardManager->SceneHandCard(SELF_VIEW_CHAIRID, cbCardCount, cbTmpCardData); //第十四张牌(必须找到之后才单独显示); if (cbSendCardData == 0x0) { m_pCardManager->SendCard(pStatusPlay->cbSendCardData, SELF_VIEW_CHAIRID); } } else { //设置牌 BYTE cbCardCount = __min(MAX_COUNT - 1, pStatusPlay->cbCardCount); m_pCardManager->SceneHandCard(SELF_VIEW_CHAIRID, cbCardCount, pStatusPlay->cbCardData); } //其他玩家手牌数据 for (WORD i = 0; i < GAME_PLAYER; i++) { if (m_bActiveStatus[i] == false) continue; //用户牌 if (i != wSelfChairID) { WORD wTmpChairID = wArrViewChairID[i]; if (wTmpChairID == INVALID_CHAIR) continue; BYTE cbCardCount = (MAX_COUNT -1) - pStatusPlay->cbWeaveCount[i] * 3; m_pCardManager->SceneHandCard(wTmpChairID, cbCardCount, nullptr); // 是当前出牌玩家 if (m_wCurrentUser == i && pStatusPlay->cbSendCardData != 0) { m_pCardManager->SendCard(0xff, wTmpChairID); } } } CCLOG("WN_NotifyDlg SetNoticeData...WN_CardManager::onGameScenePlay()...wCurrentUser = %d, wActionMask = 0x%0x。", m_wCurrentUser, pStatusPlay->dwActionMask); // 当前玩家是自己; if ((m_wCurrentUser == wSelfChairID) || (m_wCurrentUser == INVALID_CHAIR)) { //获取变量 if (IsHaveOperateCard(pStatusPlay->dwActionMask)) { CMD_S_OperateNotify operateNotify; zeromemory(&operateNotify, sizeof(operateNotify)); operateNotify.cbActionCard = pStatusPlay->cbActionCard; operateNotify.dwActionMask = pStatusPlay->dwActionMask; operateNotify.wResumeUser = pStatusPlay->wCurrentUser; CopyMemory(&operateNotify.GangPaiResult, &pStatusPlay->GangPaiResult, sizeof(tagGangCardResult)); CCLOG("WN_NotifyDlg SetNoticeData...WN_CardManager::onGameScenePlay()"); m_pCardManager->SetNoticeData(operateNotify); } //有操作,启动操作定时器 SetGameClock(SELF_VIEW_CHAIRID, IDI_USER_OPERATE, IDT_USER_OPERATE); } // 提示操作人操作; else { SetGameClock(wArrViewChairID[m_wCurrentUser], IDI_USER_OPERATE, IDT_USER_OPERATE); } // 统计剩余牌数 m_cbSurplusCard = pStatusPlay->cbLeftCardCount; SetSurplusCardCount(0); // 隐藏微信邀请 if (m_btnWeiXin) m_btnWeiXin->setVisible(false); } // 发送框架消息 void WN_GameScene::SendFrameData(WORD wSubCmdID, void* buffer, WORD wSize) { m_kGameMission.SendSocketData(MDM_GF_FRAME, wSubCmdID, buffer, wSize); } // 发送游戏消息 void WN_GameScene::SendGameData(WORD wSubCmdID, void* buffer, WORD wSize) { m_kGameMission.SendSocketData(MDM_GF_GAME, wSubCmdID, buffer, wSize); } // 发送用户消息 void WN_GameScene::SendUserData(WORD wSubCmdID, void* buffer, WORD wSize) { m_kGameMission.SendSocketData(MDM_GR_USER, wSubCmdID, buffer, wSize); } /**************************************************** 消息处理 ****************************************************/ // 游戏开始 void WN_GameScene::OnSubGameStart(const void *pBuffer, WORD wDataSize) { //效验数据 ASSERT(wDataSize == sizeof(CMD_S_GameStart)); if (wDataSize != sizeof(CMD_S_GameStart)) return; AutoReadyScene::Instance().hide(); //变量定义 CMD_S_GameStart *pGameStart = (CMD_S_GameStart *)pBuffer; //设置状态 m_cbGameStatus = GS_MJ_PLAY; m_wBankerUser = pGameStart->wBankerUser; CopyMemory(m_bActiveStatus, pGameStart->bActiveStatus, sizeof(m_bActiveStatus)); // UI设置; onGameStartInitUI(); //辅助变量 WORD wArrViewChairID[GAME_PLAYER] = { INVALID_CHAIR, INVALID_CHAIR, INVALID_CHAIR, INVALID_CHAIR }; for (WORD j = 0; j < GAME_PLAYER; j++) { if (!m_bActiveStatus[j]) continue; wArrViewChairID[j] = SwitchViewChairID(j); } m_pCardManager->SetActiveStatus(m_bActiveStatus, wArrViewChairID, GetRealChairCount()); SetCurrentUser(pGameStart->wCurrentUser); if (m_wEastUser == INVALID_CHAIR) { // 东家显示 m_wEastUser = 0; SetTimerByEast(m_wEastUser); } // 显示庄家 WORD wBankerUser = SwitchViewChairID(m_wBankerUser); if (m_aryPlayer[wBankerUser] != nullptr) { m_aryPlayer[wBankerUser]->setZhuangVisible(true); } //if (m_btnPlayer[wBankerUser]) //{ // Sprite* BankerFlag = (Sprite*)m_btnPlayer[wBankerUser]->getChildByName("BankerFlag"); // BankerFlag->setVisible(true); //} //初始化发牌数据 memset(m_cbSelfHandCardData, 0x0, sizeof(m_cbSelfHandCardData)); memcpy(m_cbSelfHandCardData, pGameStart->cbCardData, sizeof(pGameStart->cbCardData)); // 开始发牌 WORD wSendChairID = SwitchViewChairID(m_wBankerUser); m_pCardManager->SetAllCard(m_cbSelfHandCardData, wSendChairID); // 获取高级操作信息; CMD_S_OperateNotify operateNotify; zeromemory(&operateNotify, sizeof(operateNotify)); operateNotify.cbActionCard = pGameStart->cbCardData[MAX_COUNT - 1]; operateNotify.dwActionMask = pGameStart->wUserAction; operateNotify.wResumeUser = pGameStart->wCurrentUser; CopyMemory(&operateNotify.GangPaiResult, &pGameStart->GangPaiResult, sizeof(operateNotify.GangPaiResult)); // 利用动画延迟来显示麻将牌; //CallFunc* tmpBack = CallFunc::create([operateNotify, wBankerUser, wSendChairID, this](){ //m_pCardManager->SendAllCard(0); // 显示第十四张牌 if (m_wBankerUser == getSelfChairID()) { m_pCardManager->SendCard(m_cbSelfHandCardData[MAX_COUNT - 1], SELF_VIEW_CHAIRID); } else { m_pCardManager->SendCard(0xff, wBankerUser); } // 首次操作; if (m_wBankerUser == getSelfChairID()) { if (IsHaveOperateCard(operateNotify.dwActionMask)) { CCLOG("WN_NotifyDlg SetNoticeData...WN_CardManager::OnSubGameStart()"); m_pCardManager->SetNoticeData(operateNotify); } } //设置时间 SetGameClock(wSendChairID, IDI_USER_OPERATE, IDT_USER_OPERATE); // 统计剩余牌数 WORD wGetRealChairCount = GetRealChairCount(); m_cbSurplusCard -= (MAX_COUNT - 1)*wGetRealChairCount; SetSurplusCardCount(0); //}); //m_SpriteReadys[SELF_VIEW_CHAIRID]->runAction(Sequence::create(DelayTime::create(0.4f), tmpBack, nullptr)); playGameEffect(EF_GameStart); return; } // 录像开始; void WN_GameScene::OnSubRecordGameStart(const void *pBuffer, WORD wDataSize) { //效验数据 ASSERT(wDataSize == sizeof(CMD_R_GameStart)); if (wDataSize != sizeof(CMD_R_GameStart)) return; // UI设置; onGameStartInitUI(); //变量定义 CMD_R_GameStart GameStart; memcpy(&GameStart, pBuffer, sizeof(CMD_R_GameStart)); //设置状态 m_cbGameStatus = GS_MJ_PLAY; m_wBankerUser = GameStart.wBankerUser; CopyMemory(m_bActiveStatus, GameStart.bActiveStatus, sizeof(m_bActiveStatus)); //辅助变量 WORD wArrViewChairID[GAME_PLAYER] = { INVALID_CHAIR, INVALID_CHAIR, INVALID_CHAIR, INVALID_CHAIR }; for (WORD j = 0; j < GAME_PLAYER; j++) { if (!m_bActiveStatus[j]) continue; wArrViewChairID[j] = SwitchViewChairID(j); } m_pCardManager->SetActiveStatus(m_bActiveStatus, wArrViewChairID, GetRealChairCount()); SetCurrentUser(GameStart.wCurrentUser); if (m_wEastUser == INVALID_CHAIR) { // 东家显示 m_wEastUser = 0; SetTimerByEast(m_wEastUser); } // 显示庄家 WORD wBankerUser = SwitchViewChairID(m_wBankerUser); if (m_aryPlayer[wBankerUser] != nullptr) { m_aryPlayer[wBankerUser]->setZhuangVisible(true); } //if (m_btnPlayer[wBankerUser]) //{ // Sprite* BankerFlag = (Sprite*)m_btnPlayer[wBankerUser]->getChildByName("BankerFlag"); // BankerFlag->setVisible(true); //} // 利用动画延迟来显示麻将牌; //CallFunc* tmpBack = CallFunc::create([GameStart, wBankerUser, this](){ // 显示所有人手牌; for (BYTE i = 0; i < GAME_PLAYER; i++) { if (!m_bActiveStatus[i]) continue; WORD wViewChairID = SwitchViewChairID(i); m_pCardManager->ShowAllHandCard(wViewChairID, MAX_COUNT, GameStart.cbCardData[i]); } // 首次操作; if (m_wBankerUser == getSelfChairID()) { if (IsHaveOperateCard(GameStart.wUserAction)) { // 获取高级操作信息; CMD_S_OperateNotify operateNotify; zeromemory(&operateNotify, sizeof(operateNotify)); operateNotify.cbActionCard = GameStart.cbCardData[GameStart.wCurrentUser][MAX_COUNT - 1]; operateNotify.dwActionMask = GameStart.wUserAction; operateNotify.wResumeUser = GameStart.wCurrentUser; CopyMemory(&operateNotify.GangPaiResult, &GameStart.GangPaiResult, sizeof(operateNotify.GangPaiResult)); CCLOG("WN_NotifyDlg SetNoticeData...WN_CardManager::OnSubRecordGameStart()"); m_pCardManager->SetNoticeData(operateNotify); } } // 统计剩余牌数 WORD wGetRealChairCount = GetRealChairCount(); m_cbSurplusCard -= (MAX_COUNT - 1)*wGetRealChairCount; SetSurplusCardCount(0); //}); //m_SpriteReadys[SELF_VIEW_CHAIRID]->runAction(Sequence::create(DelayTime::create(0.4f), tmpBack, nullptr)); playGameEffect(EF_GameStart); return; } // 发第十四张牌 void WN_GameScene::OnSubSendCard(const void *pBuffer, WORD wDataSize) { //效验数据 ASSERT(wDataSize == sizeof(CMD_S_SendCard)); if (wDataSize != sizeof(CMD_S_SendCard)) return; //删除定时器 KillGameClock(); //变量定义 CMD_S_SendCard *pSendCard = (CMD_S_SendCard *)pBuffer; //重置当前玩家 SetCurrentUser(pSendCard->wCurrentUser); // 抓牌玩家 WORD wViewChairID = SwitchViewChairID(pSendCard->wCurrentUser); m_pCardManager->SendCard(pSendCard->cbCardData, wViewChairID); CCLOG("WN_NotifyDlg SetNoticeData...WN_CardManager::OnSubSendCard()...wCurrentUser = %d, wActionMask = 0x%0x。", pSendCard->wCurrentUser, pSendCard->wActionMask); // 自己摸牌 if (wViewChairID == SELF_VIEW_CHAIRID) { //动作处理 if (IsHaveOperateCard(pSendCard->wActionMask)) { CMD_S_OperateNotify operateNotify; zeromemory(&operateNotify, sizeof(operateNotify)); operateNotify.cbActionCard = pSendCard->cbCardData; operateNotify.dwActionMask = pSendCard->wActionMask; operateNotify.wResumeUser = pSendCard->wCurrentUser; CopyMemory(&operateNotify.GangPaiResult, &pSendCard->GangPaiResult, sizeof(tagGangCardResult)); CCLOG("WN_NotifyDlg SetNoticeData...WN_CardManager::OnSubSendCard()"); m_pCardManager->SetNoticeData(operateNotify); } } //设置时间 SetGameClock(wViewChairID, IDI_USER_OPERATE, IDT_USER_OPERATE); //播放摸牌音效 playGameEffect(EF_SendCard); // 统计剩余牌数 SetSurplusCardCount(1); return; } //用户出牌 void WN_GameScene::OnSubOutCard(const void *pBuffer, WORD wDataSize) { //效验消息 ASSERT(wDataSize == sizeof(CMD_S_OutCard)); if (wDataSize != sizeof(CMD_S_OutCard)) return; //删除定时器 KillGameClock(); //清除玩家可操作 SetCurrentUser(INVALID_CHAIR); //消息处理 CMD_S_OutCard *pOutCard = (CMD_S_OutCard *)pBuffer; //变量定义 WORD wOutViewChairID = SwitchViewChairID(pOutCard->wOutCardUser); //设置出牌 m_pCardManager->SubOutCard(pOutCard->cbOutCardData, wOutViewChairID); //播放出牌音效 playGameEffect(SD_OutCard, pOutCard->wOutCardUser, pOutCard->cbOutCardData); return; } //操作提示 void WN_GameScene::OnSubOperateNotify(const void *pBuffer, WORD wDataSize) { //效验数据 ASSERT(wDataSize == sizeof(CMD_S_OperateNotify)); if (wDataSize != sizeof(CMD_S_OperateNotify)) return; // 清楚定时器 KillGameClock(); //变量定义 CMD_S_OperateNotify *pOperateNotify = (CMD_S_OperateNotify *)pBuffer; //用户界面(服务端只把高级操作发给自己,所以不需要过滤其他人的情况) if (pOperateNotify->dwActionMask != WIK_WN_NULL) { CCLOG("WN_NotifyDlg SetNoticeData...WN_CardManager::OnSubOperateNotify()"); m_pCardManager->SetNoticeData(*pOperateNotify); SetGameClock(SELF_VIEW_CHAIRID, IDI_USER_OPERATE, IDT_USER_OPERATE); } return; } //操作结果 void WN_GameScene::OnSubOperateResult(const void *pBuffer, WORD wDataSize) { //效验消息 ASSERT(wDataSize == sizeof(CMD_S_OperateResult)); if (wDataSize != sizeof(CMD_S_OperateResult)) return; //消息处理 CMD_S_OperateResult *pOperateResult = (CMD_S_OperateResult *)pBuffer; WORD wViewChairID = SwitchViewChairID(pOperateResult->wOperateUser); if ((pOperateResult->dwOperateCode&WIK_WN_GANG) != 0) { SetPayAniShowMode(AT_GANG, m_ptCurrentCard[wViewChairID], nullptr); playGameEffect(SD_GangCard, pOperateResult->wOperateUser); SetCurrentUser(INVALID_CHAIR); } else if ((pOperateResult->dwOperateCode&WIK_WN_PENG) != 0) { SetPayAniShowMode(AT_PENG, m_ptCurrentCard[wViewChairID], nullptr); playGameEffect(SD_PengCard, pOperateResult->wOperateUser); SetCurrentUser(pOperateResult->wOperateUser); } else { // 清楚定时器 KillGameClock(); } // 服务器椅子号转客户端椅子号 pOperateResult->wOperateUser = SwitchViewChairID(pOperateResult->wOperateUser); pOperateResult->wProvideUser = SwitchViewChairID(pOperateResult->wProvideUser); m_pCardManager->SubWeaveCard(pOperateResult); } //用户托管 void WN_GameScene::OnSubUserTrust(const void *pBuffer, WORD wDataSize) { //效验数据 ASSERT(wDataSize == sizeof(CMD_S_Trustee)); if (wDataSize != sizeof(CMD_S_Trustee)) return; } // 游戏结束 void WN_GameScene::OnSubGameEnd(const void *pBuffer, WORD wDataSize) { //效验数据 ASSERT(wDataSize == sizeof(CMD_S_GameEnd)); if (wDataSize != sizeof(CMD_S_GameEnd)) return; m_IsRunEndAction = true; KillGameClock(); m_pCardManager->HideNoticeDlg(); bool IsShowResultLayer = false; //消息处理 CMD_S_GameEnd *pGameEnd = (CMD_S_GameEnd *)pBuffer; //设置状态 m_cbGameStatus = GS_MJ_FREE; SetCurrentUser(INVALID_CHAIR); // 进行视图转换 for (int i = 0; i < GAME_PLAYER; i++) { if (!m_bActiveStatus[i]) continue; // 无一炮多响; if (pGameEnd->dwChiHuKind[i] != CHK_NULL) { WORD wViewChairID = SwitchViewChairID(i); if (wViewChairID == INVALID_CHAIR) continue; // 只显示胡牌玩家牌 BYTE cbCardCount = 0; //牌数目 BYTE cbCardData[MAX_COUNT] = { 0 }; //牌数据 cbCardCount = pGameEnd->cbCardCount[i]; memcpy(cbCardData, &pGameEnd->cbCardData[i][0], sizeof(BYTE)*MAX_COUNT); m_pCardManager->ShowAllHandCard(wViewChairID, cbCardCount, cbCardData); break; } } // 结算界面 if (m_pResultLayer) { tagClientScoreInfo stClientScoreInfoEx; bool isSelfData = false; for (WORD i = 0; i < GAME_PLAYER; i++) { if (!m_bActiveStatus[i]) continue; zeromemory(&stClientScoreInfoEx, sizeof(stClientScoreInfoEx)); GamePlayer* pPlayer = getPlayerByChairID(i); if (pPlayer == nullptr) continue; if (i != getSelfChairID()) { isSelfData = false; } else { isSelfData = true; } stClientScoreInfoEx.wChairID = i; stClientScoreInfoEx.dwGameID = getPlayerByChairID(i)->GetGameID(); stClientScoreInfoEx.dwUserID = pPlayer->GetUserID(); strncpy(stClientScoreInfoEx.szHeadHttp, pPlayer->GetHeadHttp().c_str(), countarray(stClientScoreInfoEx.szHeadHttp)); std::string strNickName = getPlayerByChairID(i)->GetNickName(false); strncpy(stClientScoreInfoEx.szNickName, (strNickName.c_str()), countarray(stClientScoreInfoEx.szNickName)); std::string strUnionName = getPlayerByChairID(i)->GetUnionName(false); strncpy(stClientScoreInfoEx.szUnionName, (strUnionName.c_str()), countarray(stClientScoreInfoEx.szUnionName)); stClientScoreInfoEx.wProvideUser = pGameEnd->wProvideUser; stClientScoreInfoEx.wBankerUser = m_wBankerUser; stClientScoreInfoEx.cbChiHuCard = pGameEnd->cbChiHuCard; stClientScoreInfoEx.dwChiHuKind = pGameEnd->dwChiHuKind[i]; stClientScoreInfoEx.dwChiHuRight = pGameEnd->dwChiHuRight[i]; stClientScoreInfoEx.lGameScore = pGameEnd->lGameScore[i]; stClientScoreInfoEx.cbCardCount = pGameEnd->cbCardCount[i]; CopyMemory(stClientScoreInfoEx.cbCardData, &pGameEnd->cbCardData[i][0], sizeof(stClientScoreInfoEx.cbCardData)); stClientScoreInfoEx.cbWeaveItemCount = pGameEnd->cbWeaveItemCount[i]; CopyMemory(stClientScoreInfoEx.WeaveItemArray, &pGameEnd->WeaveItemArray[i][0], sizeof(stClientScoreInfoEx.WeaveItemArray)); m_pResultLayer->SetGameResultData(i, stClientScoreInfoEx, isSelfData); } } //是否自摸胡牌 m_cbHuaAniCout = 0; for (WORD i = 0; i < GAME_PLAYER; i++) { //播放音效和动画 if (pGameEnd->dwChiHuKind[i] != CHK_NULL) { if (i == pGameEnd->wProvideUser) { playGameEffect(SD_ZiMoHu, i); } else { playGameEffect(SD_HuCard, i); } WORD wViewChairID = SwitchViewChairID(i); SetPayAniShowMode(AT_HU, m_ptCurrentCard[wViewChairID], [this](){ m_cbHuaAniCout++; if (m_cbHuaAniCout >= GAME_PLAYER) { m_pResultLayer->ShowGameResult(m_IsGameRecord); m_pResultLayer->setVisible(true); } }); IsShowResultLayer = true; } else { m_cbHuaAniCout++; } } // 流局; if (!IsShowResultLayer) { //doHuangAnimation(m_ptCurrentCard[SELF_VIEW_CHAIRID].x, m_ptCurrentCard[SELF_VIEW_CHAIRID].y, [this](){ // m_pResultLayer->ShowGameResult(m_IsGameRecord); // m_pResultLayer->setVisible(true); //}); SetPayAniShowMode(AT_HU, m_ptCurrentCard[SELF_VIEW_CHAIRID], [this](){ m_pResultLayer->ShowGameResult(m_IsGameRecord); m_pResultLayer->setVisible(true); }); } } //踢出消息处理 void WN_GameScene::OnSubKickOut(const void *pBuffer, WORD wDataSize) { return; } // 游戏开始移动玩家; void WN_GameScene::onGameStartInitUI(bool IsMove /*= true*/) { // 隐藏微信邀请 if (m_btnWeiXin) m_btnWeiXin->setVisible(false); // 当前没显示东南西北,就表示第一次开始游戏,要设置玩家位置; if (!m_SpriteTimer->isVisible()) { // 每个玩家位置重置; for (int i = 0; i < GAME_PLAYER; i++) { if (m_aryPlayer[i] != nullptr) { auto pNode = m_aryPlayer[i]->getRootNode(); if (IsMove) { auto act = MoveTo::create(0.2f, m_ptPlayerEnd[i]); pNode->runAction(act); } else { pNode->setPosition(m_ptPlayerEnd[i]); } } } //m_SpriteTimeBg->setVisible(true); m_SpriteTimer->setVisible(true); m_LableTime->setVisible(true); } } // 显示骰子 void WN_GameScene::onShowDice() { } //是否有高级操作 bool WN_GameScene::IsHaveOperateCard(WORD dwUserAction) { #if (CC_PLATFORM_WIN32 != CC_TARGET_PLATFORM) if (m_IsGameRecord) { return false; } #endif if (/*(dwUserAction&WIK_WN_CHI) != 0 || */(dwUserAction&WIK_WN_PENG) != 0 || (dwUserAction&WIK_WN_GANG) != 0 || (dwUserAction&WIK_WN_CHI_HU) != 0) { return true; } return false; } // 设置剩余排数 void WN_GameScene::SetSurplusCardCount(BYTE cbUseingCount) { // 统计剩余牌数 m_cbSurplusCard -= cbUseingCount; string strSurplusCard = StringUtils::format("%d", m_cbSurplusCard); m_ptxtCardNum->setString(strSurplusCard); if (m_ptxtCardNum->isVisible() == false) { m_ptxtCardNum->setVisible(true); } } /**************************************************** 玩家信息处理 ****************************************************/ // 玩家状态 void WN_GameScene::OnEventUserEnter(GamePlayer * pPlayer) { if (pPlayer == nullptr) return; cocos2d::log(a_u8c("用户%s 进入,status = %d, chair = %d."), pPlayer->GetNickName().c_str(), pPlayer->GetUserStatus(), pPlayer->GetChairID()); // 玩家桌子号和椅子号 if (pPlayer->GetTableID() == INVALID_TABLE || pPlayer->GetChairID() == INVALID_CHAIR) return; // 自己进入; if (pPlayer->GetUserID() == getSelfGamePlayer()->GetUserID()) { m_pBtnReady->setVisible(pPlayer->GetUserStatus() == US_SIT); } } // 玩家状态 void WN_GameScene::OnEventUserStatus(GamePlayer * pPlayer) { if (pPlayer == nullptr) return; cocos2d::log(a_u8c("用户 %s 状态,status = %d, chair = %d."), pPlayer->GetNickName().c_str(), pPlayer->GetUserStatus(), pPlayer->GetChairID()); if (pPlayer->GetChairID() == getSelfChairID()) { //更新准备按钮状态; if (pPlayer->GetUserStatus() >= US_READY) { m_pBtnReady->setVisible(false); } } } // 玩家离开; void WN_GameScene::OnEventUserLeave(GamePlayer * pPlayer) { if (pPlayer == nullptr) return; cocos2d::log(a_u8c("用户%s 离开, 用户ID:%d."), pPlayer->GetNickName().c_str(), pPlayer->GetUserID()); } // 玩家积分 void WN_GameScene::OnUserScore(GamePlayer* pPlayer) { CC_ASSERT(pPlayer != nullptr); if (pPlayer == nullptr) return; // 不再桌子上; CC_ASSERT(pPlayer->GetTableID() != INVALID_TABLE && pPlayer->GetChairID() != INVALID_CHAIR); if (pPlayer->GetTableID() == INVALID_TABLE || pPlayer->GetChairID() == INVALID_CHAIR) return; // 不是同一桌子玩家; CC_ASSERT(pPlayer->GetTableID() == getSelfGamePlayer()->GetTableID()); if (pPlayer->GetTableID() != getSelfGamePlayer()->GetTableID()) return; cocos2d::log(a_u8c("用户%s,score = %d"), pPlayer->GetNickName().c_str(), pPlayer->GetUserScore()); ((WNGamePlayer*)pPlayer)->updateScore(); } // 玩家坐标 Vec2 WN_GameScene::GetPlayerPosByUserID(uint32 dwUserID) { WNGamePlayer* pPlayer = (WNGamePlayer*)getPlayerByUserID(dwUserID); if (pPlayer == nullptr) { return Vec2(); } const Vec2& ptHeadPos = pPlayer->getHeadPos(); return Vec2(ptHeadPos); } string WN_GameScene::getGoldStr(string _str, char insertChar) { std::string tScorestr = ""; int strSize = _str.length(); int index = 0; index = _str.find_first_of('.'); if (index >= strSize - 1) { index = strSize - 1; } //金钱字符加逗号 int nCount = 1; for (int i = strSize - 1; i >= 0; i--) { std::string tStr = ""; if (i <= index) { if (nCount % 3 == 0 && i != 0) { tStr.push_back(insertChar); } nCount++; } tStr.push_back(_str[i]); tScorestr = tStr + tScorestr; } return tScorestr; } /************************************************************************/ // 补花 游戏中结算动画 void WN_GameScene::SetPayAniShowMode(ANI_TYPE aType, Point pos, const std::function& callback) { string strFileName = ""; switch (aType) { case WNMJ_SPACE::AT_PENG: strFileName = "Games/Sparrow/Animation/eff_peng.png"; break; case WNMJ_SPACE::AT_GANG: strFileName = "Games/Sparrow/Animation/eff_gang.png"; break; case WNMJ_SPACE::AT_TING: strFileName = "Games/Sparrow/Animation/eff_ting.png"; break; case WNMJ_SPACE::AT_HU: strFileName = "Games/Sparrow/Animation/eff_hu.png"; break; case WNMJ_SPACE::AT_ZIMO: strFileName = "Games/Sparrow/Animation/eff_hu.png"; break; default: break; } Texture2D* pTexture = Director::getInstance()->getTextureCache()->addImage(strFileName); if (pTexture) { CallFunc* tmpBack = CallFunc::create(callback); auto spritAni = Sprite::createWithTexture(pTexture); spritAni->setAnchorPoint(Point(0.5, 0.5)); spritAni->setScale(1.0f); spritAni->setPosition(pos); m_pRootLayout->addChild(spritAni, ZO_ANI); auto act = EaseElasticOut::create(ScaleTo::create(0.6f, 0.6f)); spritAni->runAction(Sequence::create(act, DelayTime::create(0.3f), RemoveSelf::create(true), tmpBack, nullptr)); } } //胡动画 void WN_GameScene::doHuAnimation(float fEndX, float fEndY, const std::function& fnCallback) { auto pSpriteFrameCache = SpriteFrameCache::getInstance(); pSpriteFrameCache->addSpriteFramesWithFile("Games/WNMJ/hu/hu_light_png_01.plist"); pSpriteFrameCache->addSpriteFramesWithFile("Games/WNMJ/hu/hu_light_png_02.plist"); float fStartX = Director::getInstance()->getWinSize().width / 2.f; float fStartY = Director::getInstance()->getWinSize().height / 2.f; auto pSprHu = Sprite::createWithSpriteFrameName("hu_light1.png"); pSprHu->setPosition(fStartX, fStartY); pSprHu->setScale(1.5f); m_pRootLayout->addChild(pSprHu, ZO_ANI); auto sprWord = Sprite::createWithSpriteFrameName("hu_hu2.png"); auto sprWithinWrod = Sprite::createWithSpriteFrameName("hu_huword.png"); sprWithinWrod->setPositionX(sprWord->getContentSize().width / 2.f); sprWithinWrod->setPositionY(sprWord->getContentSize().height / 2.f); sprWord->addChild(sprWithinWrod); sprWord->setVisible(false); m_pRootLayout->addChild(sprWord, ZO_ANI); sprWord->setPositionX(fStartX - 200.f); sprWord->setPositionY(fStartY); Animation* pHuAni = nullptr; AnimationCache* pAnimationCache = AnimationCache::getInstance(); pHuAni = pAnimationCache->getAnimation("hu_ani"); if (pHuAni == nullptr) { pHuAni = Animation::create(); pHuAni->setDelayPerUnit(0.1f); for (uint8 i = 2; i <= 44; i++) { auto pSpriteFrame = pSpriteFrameCache->getSpriteFrameByName(StringUtils::format("hu_light%d.png", i)); pHuAni->addSpriteFrame(pSpriteFrame); } pAnimationCache->addAnimation(pHuAni, "hu_ani"); } CC_ASSERT(pHuAni != nullptr); pSprHu->runAction(Sequence::create(Animate::create(pHuAni), RemoveSelf::create(), nullptr)); ccBezierConfig bcMovePos; bcMovePos.controlPoint_1 = Vec2(sprWord->getPosition()); bcMovePos.controlPoint_2 = Vec2(fStartX - 400.f, fStartY + 400.f); bcMovePos.endPosition = Vec2(fStartX, fStartY + 200.f); sprWord->runAction(Sequence::create(DelayTime::create(0.5f), Show::create(), BezierTo::create(1.2f, bcMovePos), DelayTime::create(0.5f), MoveTo::create(0.8f, Vec2(fEndX, fEndY)), DelayTime::create(2.0f), RemoveSelf::create(), CallFunc::create(fnCallback), nullptr )); CocosDenshion::SimpleAudioEngine::getInstance()->playEffect("Games/WNMJ/hu/huwind.mp3"); } //荒庄 void WN_GameScene::doHuangAnimation(float fEndX, float fEndY, const std::function& fnCallback) { auto pSpriteFrameCache = SpriteFrameCache::getInstance(); pSpriteFrameCache->addSpriteFramesWithFile("Games/WNMJ/hu/huang.plist"); auto pHuAni = Animation::create(); pHuAni->setDelayPerUnit(0.1f); for (uint8 i = 0; i < 12; i++) { auto pSpriteFrame = pSpriteFrameCache->getSpriteFrameByName(StringUtils::format("huang_%03d.png", i)); pHuAni->addSpriteFrame(pSpriteFrame); } auto pSprHu = Sprite::create(); pSprHu->setPosition(fEndX, fEndY); m_pRootLayout->addChild(pSprHu, ZO_ANI); pSprHu->runAction(Sequence::create(Animate::create(pHuAni), DelayTime::create(0.3f), RemoveSelf::create(), CallFunc::create(fnCallback), nullptr)); } /**************************************************** 游戏定时器 ****************************************************/ // 根据东方位玩家设置时钟TAG void WN_GameScene::SetTimerByEast(WORD wEastUser) { // 东家显示 WORD wViewEastChairID = SwitchViewChairID(m_wEastUser); if (m_SpriteTimer && (wViewEastChairID != INVALID_CHAIR)) { m_SpriteTimer->setRotation(m_wUserPosition[wViewEastChairID]); // 设置东南西北的TAG --> 根据视图ID设置TAG for (int i = 0; i < GAME_PLAYER; i++) { // 注意资源中要指针控件名称从0~3为东南西北 string ctrlID = __String::createWithFormat("xz_clock_%d", i)->getCString(); Sprite* sp_clock = (Sprite*)m_SpriteTimer->getChildByName(ctrlID); if (sp_clock == nullptr) continue; WORD wTag = (wViewEastChairID + i) % GAME_PLAYER; sp_clock->setTag(wTag); } } } // 设置时间(秒) void WN_GameScene::SetGameClock(WORD wChairID, DWORD dwTimerID, DWORD dwElapse) { m_nSecondCount = dwElapse > 99 ? 99 : dwElapse; m_dwTimerID = dwTimerID; m_wTimeChairID = wChairID; if ((m_wTimeChairID != INVALID_CHAIR) && m_SpriteTimer && m_LableTime) { Sprite* sp_clock = (Sprite*)m_SpriteTimer->getChildByTag(m_wTimeChairID); if (sp_clock) sp_clock->setVisible(true); string strTime = __String::createWithFormat("%02d", m_nSecondCount)->getCString(); m_LableTime->setString(strTime); } } //删除时间 void WN_GameScene::KillGameClock() { if ((m_wTimeChairID != INVALID_CHAIR) && m_SpriteTimer && m_LableTime) { Sprite* sp_clock = (Sprite*)m_SpriteTimer->getChildByTag(m_wTimeChairID); if (sp_clock) sp_clock->setVisible(false); string strTime = __String::createWithFormat("%02d", 00)->getCString(); m_LableTime->setString(strTime); } m_nSecondCount = 0; m_dwTimerID = IDI_NULL; m_wTimeChairID = INVALID_CHAIR; } // 游戏定时器 void WN_GameScene::OnEventGameClock(float dt) { if (m_dwTimerID == IDI_NULL || m_nSecondCount <= 0) return; m_nSecondCount--; // 计数 if (m_wTimeChairID != INVALID_CHAIR) { string strTime = __String::createWithFormat("%02d", m_nSecondCount)->getCString(); m_LableTime->setString(strTime); } //播放提示声音 if (m_nSecondCount <= 5) { playGameEffect(EF_GameWarn); } switch (m_dwTimerID) { case IDI_StartGame: //开始游戏 { if (m_wTimeChairID == SELF_VIEW_CHAIRID) { CGameServerItem* pGameServerItem = GameMission::g_pGameServerItem; //定时器到,退出 if (m_nSecondCount <= 0 && pGameServerItem && (GAME_GENRE_PRIVATE != pGameServerItem->m_GameServer.wServerType)) { Director::getInstance()->getEventDispatcher()->dispatchCustomEvent(LEAVE_GAME); } } } case IDI_USER_OPERATE: //case IDI_OUT_CARD: { //提示声音 if (m_nSecondCount <= 5 && m_wTimeChairID == SELF_VIEW_CHAIRID) { playGameEffect(EF_GameWarn); } } default: break; } if (m_nSecondCount <= 0) { CGameServerItem* pGameServerItem = GameMission::g_pGameServerItem; //定时器到,退出 if (pGameServerItem && (GAME_GENRE_PRIVATE != pGameServerItem->m_GameServer.wServerType)) { KillGameClock(); } } } // 更新系统时间; void WN_GameScene::UpdateSystmeTime(float dt) { if (m_txtCurrentTime) { std::string strSystemTime = JniFun::getSystemTime(); m_txtCurrentTime->setString(strSystemTime); } } /**************************************************** 声音控制 ****************************************************/ // 播放背景音乐 void WN_GameScene::PlayBackMusic(BYTE cbType, bool ispool) { //m_cbBackMusicType = cbType; if (false == GAME_MUISCBG) { return; } CocosDenshion::SimpleAudioEngine::getInstance()->playBackgroundMusic("Games/WNMJ/game/muicsbg.mp3", true); } // 播放游戏音效 void WN_GameScene::playGameEffect(BYTE cbType) { __String strFilePath = "common/sound/Public"; log("strFilePath=%s", strFilePath.getCString()); switch (cbType) { case EF_GameStart: strFilePath.append("Public/GameStart.mp3"); break; case EF_ShootDice: strFilePath.append("Public/ShootDice.mp3"); break; case EF_TakeCard: strFilePath.append("Public/TakeCard.mp3"); break; case EF_SendCard: strFilePath.append("Public/SendCard.mp3"); break; case EF_GameWarn: strFilePath.append("Public/GameWarn.mp3"); break; case EF_OutCard: strFilePath.append("Public/OutCard.mp3"); break; case EF_GameEnd: strFilePath.append("Public/GameEnd.mp3"); break; case EF_GameWin: strFilePath.append("Public/GameWin.mp3"); break; case EF_GameLose: strFilePath.append("Public/GameLose.mp3"); break; case EF_GameHuang: strFilePath.append("Public/HuangZhuang.mp3"); break; case EF_GameRun: strFilePath.append("Public/Run.mp3"); break; case EF_HitChime: strFilePath.append("Public/HitChime.mp3"); break; default: break; } log("strFilePath=%s", strFilePath.getCString()); CocosDenshion::SimpleAudioEngine::getInstance()->playEffect(strFilePath.getCString()); } // 播放游戏音效(wChairID服务器椅子号) void WN_GameScene::playGameEffect(BYTE cbSoundType, WORD wChairID, BYTE cbOutCard /*= 0*/) { __String strFilePath = ""; // 方言 if (YSAudioEngine::Instance().getSoundType() == 1) { strFilePath = "Games/WNMJ/WanNianMJ/"; } else { strFilePath = "Games/Sparrow/PuTongHua/"; } //获取性别 WORD wViewChairID = SwitchViewChairID(wChairID); GamePlayer* pGamePlayer = getPlayerByChairID(wChairID); if (pGamePlayer == nullptr) return; if (pGamePlayer->GetUserInfo()->cbGender == enMan) { strFilePath.append("Man/"); } else { strFilePath.append("Woman/"); } log("strFilePath=%s", strFilePath.getCString()); switch (cbSoundType) { case SD_OutCard: { strFilePath.appendWithFormat("%x.mp3", cbOutCard); } break; case SD_PengCard: { BYTE cbRandIndex = std::rand() % 3; strFilePath.appendWithFormat("peng%d.mp3", cbRandIndex); } break; case SD_GangCard: { BYTE cbRandIndex = std::rand() % 3; strFilePath.appendWithFormat("gang%d.mp3", cbRandIndex); } break; case SD_HuCard: { BYTE cbRandIndex = std::rand() % 3; strFilePath.appendWithFormat("hu%d.mp3", cbRandIndex); } break; case SD_ChiCard: { BYTE cbRandIndex = std::rand() % 3; strFilePath.appendWithFormat("chi%d.mp3", cbRandIndex); } break; case SD_ZiMoHu: { BYTE cbRandIndex = std::rand() % 3; strFilePath.appendWithFormat(("zimo%d.mp3"), cbRandIndex); } break; default: break; } log("strFilePath=%s", strFilePath.getCString()); CocosDenshion::SimpleAudioEngine::getInstance()->playEffect(strFilePath.getCString()); } /************************************* 语音 ***********************************************************/ // 按住语音按钮 void WN_GameScene::OnButtonVoiceTouched(Ref*, Widget::TouchEventType type) { if (Widget::TouchEventType::BEGAN == type) { // 暂停播放背景音乐; CocosDenshion::SimpleAudioEngine::getInstance()->pauseBackgroundMusic(); if (m_pVoiceNode->isVisible()) { m_pVoiceNode->setVisible(false); m_pVoiceNode->stopAllActions(); YvVoiceManager::GetInstance()->StopRecord(); return; } m_pVoiceNode->setVisible(true); // 启动帧动画; auto action = CSLoader::createTimeline("Games/WNMJ/VoiceNode.csb"); action->gotoFrameAndPlay(0); m_pVoiceNode->runAction(action); YvVoiceManager::GetInstance()->StartRecord(); } else if ((Widget::TouchEventType::CANCELED == type) || (Widget::TouchEventType::ENDED == type)) { // 继续播放背景音乐; CocosDenshion::SimpleAudioEngine::getInstance()->resumeBackgroundMusic(); if (!m_pVoiceNode->isVisible()) { return; } m_pVoiceNode->setVisible(false); m_pVoiceNode->stopAllActions(); YvVoiceManager::GetInstance()->StopRecord(); } } /************************************* 房间信息 ***********************************************************/ // 房间信息消息 void WN_GameScene::OnSocketSubPrivateRoomInfo(CMD_GF_Private_Room_Info* pNetInfo) { m_PrivateRoomInfo = *pNetInfo; m_txtRoomID->setVisible(true); m_txtGameTimes->setVisible(true); std::string strText = StringUtils::format("房号:%u", pNetInfo->dwRoomNum); m_txtRoomID->setString(utility::a_u8(strText.c_str())); uint32 dwPlayCout = __max((int)pNetInfo->dwPlayCout+1, 1); dwPlayCout = __min(dwPlayCout, pNetInfo->dwPlayTotal); strText = StringUtils::format("%u/%u 局", dwPlayCout, pNetInfo->dwPlayTotal); cocos2d::log("dwPlayCout = %d", pNetInfo->dwPlayCout); m_txtGameTimes->setString(utility::a_u8(strText.c_str())); SetChairs(); if (pNetInfo->bStartGame) { //如果游戏已开始则隐藏“返回大厅”按钮,显示“解散房间”按钮 m_btnWeiXin->setVisible(false); m_pBtnLeave->setVisible(false); m_btnDismiss->setVisible(true); } else { GamePlayer* pPlayer = getSelfGamePlayer(); //如果房间主人是自已则隐藏“返回大厅”按钮,显示“解散房间”按钮 if (pPlayer != nullptr && pNetInfo->dwCreateUserID == pPlayer->GetUserID()) { m_pBtnLeave->setVisible(false); m_btnDismiss->setVisible(true); } //游戏未开始显示微信分享按钮 if (pNetInfo->dwPlayCout <= 0) { m_btnWeiXin->setVisible(true); } } ShowGameRule(pNetInfo); } // 根据配置显示椅子; void WN_GameScene::SetChairs() { if (m_PrivateRoomInfo.bStartGame) return; if ((m_PrivateRoomInfo.bGameRuleIdex&eWNMJRuleEnum_PlayCount2) != 0) { for (WORD i = 0; i < GAME_PLAYER; i++) { if (i == 1 || i == 3) continue; WNGamePlayer* pPlayer = m_aryPlayer[i]; if (pPlayer == nullptr)continue; pPlayer->setVisible(true); } } else if ((m_PrivateRoomInfo.bGameRuleIdex&eWNMJRuleEnum_PlayCount3) != 0) { for (WORD i = 1; i < GAME_PLAYER; i++) { WNGamePlayer* pPlayer = m_aryPlayer[i]; if (pPlayer == nullptr)continue; pPlayer->setVisible(true); } } else if ((m_PrivateRoomInfo.bGameRuleIdex&eWNMJRuleEnum_PlayCount_auto) != 0) { for (WORD i = 0; i < GAME_PLAYER; i++) { WORD wViewID = SwitchViewChairID(i); GamePlayer* pPlayer = getPlayerByChairID(i); WNGamePlayer* pwnPlayer = m_aryPlayer[wViewID]; if (pwnPlayer == nullptr)continue; if (pPlayer == nullptr) { pwnPlayer->setVisible(false); } else { pwnPlayer->setVisible(true); } } } else { for (WORD i = 0; i < GAME_PLAYER; i++) { WNGamePlayer* pPlayer = m_aryPlayer[i]; if (pPlayer == nullptr)continue; pPlayer->setVisible(true); } } } // 分享房间; void WN_GameScene::ShowRoomID(Ref *pSender) { YSAudioEngine::Instance().playBtnClickEffect(); //房间号:【857252】8局,分庄闲,爬楼,回头一笑,同一首歌。 std::string strText = StringUtils::format("房间号:[%u] %d 局, %s.", m_PrivateRoomInfo.dwRoomNum, m_PrivateRoomInfo.dwPlayTotal, m_strGameRuleInfo.c_str()); std::string strFriendUrl = GlobalJosn::getInstance()->getShareInfoByKind(SH_KIND_FRIEND_RUL); std::string strUrl = StringUtils::format("%s?param=%d", strFriendUrl.c_str(), m_PrivateRoomInfo.dwRoomNum); MissionWeiXin::Instance().shareUrlWeiXin(strUrl, m_strGameTitle, utility::a_u8(strText)); //SelectShareScene::Instance().shareRoomInfo(strUrl, utility::a_u8(m_strGameTitle), strText, 0); } // 游戏规则 void WN_GameScene::ShowGameRule(CMD_GF_Private_Room_Info* pNetInfo) { if (pNetInfo == nullptr) return; m_strGameRuleInfo = ""; std::string strGameRule = ""; std::string strGameRuleScore = ""; std::string strGangRule = ""; std::string strPlayCount = ""; std::string strBaseScore = StringUtils::format("底分:%d", pNetInfo->cbBaseScore); // 保存规则; if ((pNetInfo->bGameRuleIdex&eWNMJRuleEnum_OneTwoFAN)!= 0) { strGameRuleScore = "1,2翻倍"; } else { strGameRuleScore = "2,3翻倍"; } if (m_txtGameRuleScore) { m_txtGameRuleScore->setString(utility::a_u8(strGameRuleScore)); m_txtGameRuleScore->setVisible(true); } if ((pNetInfo->bGameRuleIdex&eWNMJRuleEnum_YingHU) != 0) { strGameRule = "硬胡"; m_strGameTitle = "麻将~硬胡"; } else if ((pNetInfo->bGameRuleIdex&eWNMJRuleEnum_YiBianDaoHU) != 0) { strGameRule = "一边倒"; m_strGameTitle = "麻将~一边倒"; } else { strGameRule = "混子"; m_strGameTitle = "麻将~混子"; } if (m_txtGameRule) { std::string strGR = StringUtils::format("%s,%s", strGameRule.c_str(), strBaseScore.c_str()); m_txtGameRule->setString(utility::a_u8(strGR)); m_txtGameRule->setVisible(true); } // 杠规则; if ((pNetInfo->bGameRuleIdex&eWNMJRuleEnum_ZhiAnGang) != 0) { strGangRule = "直暗杠翻倍"; } else { strGangRule = "直暗杠不翻倍"; } if (m_txtGangRule) { m_txtGangRule->setString(utility::a_u8(strGangRule)); m_txtGangRule->setVisible(true); } if ((pNetInfo->bGameRuleIdex&eWNMJRuleEnum_PlayCount2) != 0) { strPlayCount = ",2人"; } else if ((pNetInfo->bGameRuleIdex&eWNMJRuleEnum_PlayCount3) != 0) { strPlayCount = ",3人"; } else if ((pNetInfo->bGameRuleIdex&eWNMJRuleEnum_PlayCount_auto) != 0) { strPlayCount = ",2~4人"; } else { strPlayCount = ",4人"; } m_strGameRuleInfo = strGameRule + ", " + strBaseScore + strPlayCount + ", " + strGameRuleScore + ", " + strGangRule; } // 私人场结束 void WN_GameScene::OnSocketSubPrivateEnd(void* data, int dataSize) { m_bPrivateEnd = true; // 申请解散界面 DismissScene::Instance().hide(); GamePlayer* players[GAME_PLAYER]; for (int i = 0; i < GAME_PLAYER; i++) { players[i] = getPlayerByChairID(i); } if (m_pPrivateScene) { DataStream kDataStream(data, dataSize); CMD_S_Private_End_Info kNetInfo; kNetInfo.StreamValue(kDataStream, false); // 欢乐场 if (m_PrivateRoomInfo.cbUnionGoldOpen == 1) { //SCORE lGameGold = m_PrivateRoomInfo.lGameGold*m_PrivateRoomInfo.dwPlayCost; //m_pPrivateScene->ShowGameResult(&kNetInfo, players, (m_PrivateRoomInfo.cbUnionGoldOpen == 1), lGameGold, m_PrivateRoomInfo.lScoreMultiple); m_pPrivateScene->ShowGameResult(&kNetInfo, players, m_PrivateRoomInfo, m_PrivateScoreInfo); } else { m_pPrivateScene->ShowGameResult(&kNetInfo, players, m_PrivateRoomInfo.cbBaseScore); } //SCORE lGameGold = m_PrivateRoomInfo.lGameGold*m_PrivateRoomInfo.dwPlayCost; //m_pPrivateScene->ShowGameResult(&kNetInfo, players, (m_PrivateRoomInfo.cbUnionGoldOpen == 1), lGameGold, m_PrivateRoomInfo.lScoreMultiple); // 如果正在执行结束动画或者已经显示了当局结算信息,则不显示结算信息 m_pResultLayer->SetShowPrivate(); m_pPrivateScene->setVisible(!m_IsRunEndAction); } // 游戏结束停止网络; PrivateRoomEnd(); } void WN_GameScene::onEventShowPrivate(cocos2d::EventCustom *event) { if (m_pPrivateScene) { m_pPrivateScene->setVisible(true); } } // 请求解散房间 void WN_GameScene::OnSocketSubPrivateDismissInfo(CMD_GF_Private_Dismiss_Info* pNetInfo) { std::string aryName[TABLE_PLAYER_COUNT]; BYTE aryResult[TABLE_PLAYER_COUNT] = { 0 }; // 0 未选择 1 同意 2 不同意 bool bHasSelf = false; uint32 dwMyChairID = getSelfChairID(); for (uint32 i = 0; i < pNetInfo->dwDissUserCout; i++) { uint32 dwChairID = pNetInfo->dwDissChairID[i]; GamePlayer* pPlayer = getPlayerByChairID(dwChairID); if (pPlayer != nullptr && dwChairID < TABLE_PLAYER_COUNT) { aryResult[dwChairID] = 1; } if (dwMyChairID == dwChairID) { bHasSelf = true; } } for (uint32 i = 0; i < pNetInfo->dwNotAgreeUserCout; i++) { uint32 dwChairID = pNetInfo->dwNotAgreeChairID[i]; GamePlayer* pPlayer = getPlayerByChairID(dwChairID); if (pPlayer != nullptr && dwChairID < TABLE_PLAYER_COUNT) { aryResult[dwChairID] = 2; } if (dwMyChairID == dwChairID) { bHasSelf = true; } } GamePlayer* players[GAME_PLAYER]; for (int i = 0; i < GAME_PLAYER; i++) { players[i] = getPlayerByChairID(i); } DismissScene::Instance().show(aryResult, players, !bHasSelf, GAME_PLAYER); } void WN_GameScene::OnSocketSubPrivateDismissResult(CMD_GF_Private_Dismiss_Result* pNetInfo) { if (pNetInfo->bSuccess && false == m_PrivateRoomInfo.bStartGame) { EventLeaveGame(nullptr); } else { DismissScene::Instance().hide(); } } // 自场玩家状态; void WN_GameScene::OnSocketSubPrivateAutoUserStatus(tagAutoUserStatus* pNetInfo) { uint16 wReadyUserCount = 0; for (uint16 i = 0; i < GAME_PLAYER; i++) { WNGamePlayer* pPlayer = (WNGamePlayer*)getPlayerByChairID(i); if (pPlayer == nullptr) { WORD wViewID = SwitchViewChairID(i); if (wViewID != INVALID_CHAIR) { m_aryPlayer[wViewID]->setVisible(false); } continue; } //if (pPlayer->GetUserStatus() != US_READY) return; wReadyUserCount++; } // 显示准备界面; if (pNetInfo->bStartGame) { std::string strUserCount = StringUtils::format("%d人开始", wReadyUserCount);; m_pBtnStartGame->setTitleText(utility::a_u8(strUserCount)); m_pBtnStartGame->setVisible(true); } else // 隐藏准备界面; { m_pBtnStartGame->setVisible(false); } AutoReadyScene::Instance().hide(); } // 自由人数玩家开始状态; void WN_GameScene::OnSocketSubPrivateAutoUserReady(CMD_GR_Private_ReadyInfo* pNetInfo) { uint8 wSelfChairID = getSelfChairID(); ASSERT(wSelfChairID != INVALID_CHAIR); bool bHasSelf = (pNetInfo->cbReady[wSelfChairID] == 0); bool bHasRefused = false; GamePlayer* players[GAME_PLAYER]; for (int i = 0; i < GAME_PLAYER; i++) { players[i] = getPlayerByChairID(i); // 拒绝 if (pNetInfo->cbReady[i] == 2) { bHasRefused = true; } } m_pBtnStartGame->setVisible(bHasRefused); AutoReadyScene::Instance().show(pNetInfo, players, bHasSelf, GAME_PLAYER); } //自定义事件出牌 void WN_GameScene::onEventOutCard(EventCustom* event) { CMD_C_OutCard* pCard = static_cast(event->getUserData()); m_kGameMission.SendSocketData(MDM_GF_GAME, SUB_C_OUT_CARD, pCard, sizeof(CMD_C_OutCard)); } //自定义事件操作牌 void WN_GameScene::onEventOperCard(EventCustom* event) { CMD_C_OperateCard* pCard = static_cast(event->getUserData()); // 验证杠的牌是否正确; //pCard->cbOperateCard = m_pCardManager->CheckOperateCard(pCard->dwOperateCode, pCard->cbOperateCard); if (WN_CGameLogic::IsValidCard(pCard->cbOperateCard)) { m_kGameMission.SendSocketData(MDM_GF_GAME, SUB_C_OPERATE_CARD, pCard, sizeof(CMD_C_OperateCard)); } } ////////////////////////////////////////////////////////////////////////// // 玩家要牌 void WN_GameScene::onPlayerGetCard() { if (m_pRootLayout == nullptr) return; auto btnGetCard = (Button*)m_pRootLayout->getChildByName("btnGetCard"); ASSERT(btnGetCard); btnGetCard->setVisible(false); #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) // 要牌权限; if (CUserRight::CanGetCard(CGlobalUserInfo::GetInstance()->GetUserRigh())) { // 要牌面板; m_pGetCardLayer = GetCardCtrl::create(); m_pGetCardLayer->setVisible(false); this->addChild(m_pGetCardLayer, ZO_TRUSTEE); btnGetCard->setVisible(true); btnGetCard->addClickEventListener([=](Ref *pSender){ SendGameData(SUB_C_MASTER_LEFTCARD, nullptr, 0); }); } #endif // DEBUG } // 获取排堆; void WN_GameScene::OnSubGetLeftCard(const void *pBuffer, WORD wDataSize) { //效验消息 ASSERT(wDataSize == sizeof(MasterLeftCard)); if (wDataSize != sizeof(MasterLeftCard)) return; //消息处理 MasterLeftCard *pLeftCard = (MasterLeftCard *)pBuffer; if (m_pGetCardLayer) { m_pGetCardLayer->ShowCardData(pLeftCard); } } //自定义事件操作牌 void WN_GameScene::onEventGetCard(EventCustom* event) { CMD_C_MaterCheckCard* MaterCheckCard = static_cast(event->getUserData()); m_kGameMission.SendSocketData(MDM_GF_GAME, SUB_C_MASTER_CHEAKCARD, MaterCheckCard, sizeof(CMD_C_MaterCheckCard)); } //////////////////////////////// 游戏录像 ////////////////////////////////////////// // 开始录像播放 void WN_GameScene::StartGameRecord() { if (m_GameRecord.playersVec.size() < 2) { return; } // 东家显示 m_wBankerUser = m_GameRecord.wBankerUser; m_wEastUser = m_GameRecord.wEastUser; SetTimerByEast(m_wEastUser); // 初始化房间信息; OnSocketSubPrivateRoomInfo(&m_GameRecord.roomInfo); m_iActRecordIdex = 0; m_txtRecordPercent->setString(utility::toString(m_iActRecordIdex * 100 / m_GameRecord.actionVec.size(), "%")); // 设置录像模式; m_pCardManager->SetGameRecord(true); schedule(schedule_selector(GameFrameBase::NextRecordAction), m_RecordTime); return; } void WN_GameScene::NextRecordAction(float dt) { cocos2d::log("NextRecordAction...m_iActRecordIdex = %d", m_iActRecordIdex); // 已经播放完了 if (m_iActRecordIdex >= (int)m_GameRecord.actionVec.size() || !isVisible()) { m_txtRecordPercent->setString("100%"); m_btnPlay->setVisible(true); m_btnPause->setVisible(false); unschedule(schedule_selector(GameFrameBase::NextRecordAction)); return; } // 下一个操作记录; tagGameRecordOperateResult& kAction = m_GameRecord.actionVec[m_iActRecordIdex]; // 游戏开始; if (kAction.wSubCmdID == SUB_S_GAME_START) { CMD_S_GameStart gameStart; kAction.subMessageData.popValue(&gameStart, sizeof(CMD_S_GameStart)); // 组织回放数据; CMD_R_GameStart r_GameStart; zeromemory(&r_GameStart, sizeof(r_GameStart)); r_GameStart.wSiceCount = gameStart.wSiceCount; r_GameStart.wCurrentUser = gameStart.wCurrentUser; r_GameStart.wBankerUser = gameStart.wBankerUser; r_GameStart.wUserAction = gameStart.wUserAction; CopyMemory(&r_GameStart.GangPaiResult, &gameStart.GangPaiResult, sizeof(gameStart.GangPaiResult)); CopyMemory(&r_GameStart.bActiveStatus, &gameStart.bActiveStatus, sizeof(gameStart.bActiveStatus)); // 复制牌; for (int i = 0; i < GAME_PLAYER; i++) { if (!r_GameStart.bActiveStatus[i]) continue; tagGameRecordPlayer& kRecordPlayer = m_GameRecord.playersVec[i]; for (int j = 0; j < MAX_COUNT; j++) { r_GameStart.cbCardData[i][j] = kRecordPlayer.cbCardData[j]; } } OnSubRecordGameStart(&r_GameStart, sizeof(CMD_R_GameStart)); } // 玩家出牌; else if (kAction.wSubCmdID == SUB_S_OUT_CARD) { CMD_S_OutCard outCard; kAction.subMessageData.popValue(&outCard, sizeof(CMD_S_OutCard)); OnSubOutCard(&outCard, sizeof(CMD_S_OutCard)); } // 玩家摸牌; else if (kAction.wSubCmdID == SUB_S_SEND_CARD) { CMD_S_SendCard sendCard; kAction.subMessageData.popValue(&sendCard, sizeof(CMD_S_SendCard)); OnSubSendCard(&sendCard, sizeof(CMD_S_SendCard)); } // 操作结果; else if (kAction.wSubCmdID == SUB_S_OPERATE_RESULT) { CMD_S_OperateResult OperateResult; kAction.subMessageData.popValue(&OperateResult, sizeof(CMD_S_OperateResult)); OnSubOperateResult(&OperateResult, sizeof(CMD_S_OperateResult)); } // 游戏结束; else if (kAction.wSubCmdID == SUB_S_GAME_END) { CMD_S_GameEnd GameEnd; kAction.subMessageData.popValue(&GameEnd, sizeof(CMD_S_GameEnd)); OnSubGameEnd(&GameEnd, sizeof(CMD_S_GameEnd)); } m_iActRecordIdex++; m_txtRecordPercent->setString(utility::toString(m_iActRecordIdex * 100 / m_GameRecord.actionVec.size(), "%")); } //调用; GamePlayer* WN_GameScene::CreatePlayer(IClientUserItem * pIClientUserItem) { if (pIClientUserItem == NULL || pIClientUserItem->GetChairID() == INVALID_CHAIR) { return NULL; } if (pIClientUserItem->GetUserID() == UserInfo::Instance().getUserID()) { WNGamePlayer* pPlayer = m_aryPlayer[SELF_VIEW_CHAIRID]; pPlayer->setUserItem(pIClientUserItem); return pPlayer; } else { WORD wViewID = SwitchViewChairID(pIClientUserItem->GetChairID()); CC_ASSERT(wViewID != INVALID_CHAIR); if (wViewID != INVALID_CHAIR) { WNGamePlayer* pPlayer = m_aryPlayer[wViewID]; pPlayer->setUserItem(pIClientUserItem); return pPlayer; } } return NULL; } std::string WN_GameScene::getGameRule(uint32 dwGameRule) { std::string strGameRuleIdex = ""; std::string strGameRule = ""; std::string strGameRuleScore = ""; std::string strGangRule = ""; std::string strPlayCount = ""; if ((dwGameRule&eWNMJRuleEnum_YingHU) != 0) { strGameRule = "硬胡"; } else if ((dwGameRule&eWNMJRuleEnum_YiBianDaoHU) != 0) { strGameRule = "一边倒"; } else { strGameRule = "万年混子"; } // 保存规则; if ((dwGameRule&eWNMJRuleEnum_OneTwoFAN) != 0) { strGameRuleScore = "1,2翻倍"; } else { strGameRuleScore = "2,3翻倍"; } // 杠规则; if ((dwGameRule&eWNMJRuleEnum_ZhiAnGang) != 0) { strGangRule = "直暗杠翻倍"; } else { strGangRule = "直暗杠不翻倍"; } if ((dwGameRule&eWNMJRuleEnum_PlayCount2) != 0) { strPlayCount = ",2人"; } else if ((dwGameRule&eWNMJRuleEnum_PlayCount3) != 0) { strPlayCount = ",3人"; } else if ((dwGameRule&eWNMJRuleEnum_PlayCount_auto) != 0) { strPlayCount = ",2~4人"; } else { strPlayCount = ",4人"; } strGameRuleIdex = strGameRule + strPlayCount + ", " + strGameRuleScore + ", " + strGangRule; return strGameRuleIdex; } int WN_GameScene::GetRealChairCount(uint32 dwGameRule) { if ((dwGameRule&eWNMJRuleEnum_PlayCount2) != 0) { return 2; } else if ((dwGameRule&eWNMJRuleEnum_PlayCount3) != 0) { return 3; } return GAME_PLAYER; }