Files
wnmj/Classes/Games/WNMJ/WN_GameScene.cpp
2026-02-13 14:34:15 +08:00

2844 lines
74 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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<Layout*>(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<std::string>& 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("用户%sscore = %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<void()>& 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<void()>& 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<void()>& 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<CMD_C_OutCard *>(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<CMD_C_OperateCard *>(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<CMD_C_MaterCheckCard *>(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;
}