#include "WN_CardManager.h" #include "cocos2d.h" #include "ui/CocosGUI.h" #include "cocostudio/CocoStudio.h" #include "YSAudioEngine.h" #include "PopScene.h" using namespace WNMJ_SPACE; /////////////////////////////// 麻将管理 /////////////////////////////////////////// WN_CardManager::WN_CardManager() { m_IsGameRecord = false; m_bOutCardStatus = false; } WN_CardManager::~WN_CardManager() { memset(m_cbOutCarCount, 0x0, sizeof(m_cbOutCarCount)); memset(m_cbWeaveCount, 0x0, sizeof(m_cbWeaveCount)); memset(m_cbHandCardCount, 0x0, sizeof(m_cbHandCardCount)); for (int i = 0; i < GAME_PLAYER; i++) { ClearCardList(i); for (int l = 0; l < MAX_WEAVE; l++) { if (m_pWeaveCard[i][l]) { m_pWeaveCard[i][l]->removeFromParentAndCleanup(true); m_pWeaveCard[i][l] = nullptr; } } } for (std::list::iterator it = m_pOutCardSprite.begin(); it != m_pOutCardSprite.end(); it++) { WN_SparrowCard* card = *it; if (card) { card->removeFromParentAndCleanup(true); card = nullptr; } } m_pOutCardSprite.clear(); for (int j = 0; j < 2; j++) { if (m_pKingCardSprite[j]) { m_pKingCardSprite[j]->removeFromParentAndCleanup(true); m_pKingCardSprite[j] = nullptr; } } if (m_pCurrentOutCard) { m_pCurrentOutCard->removeFromParent(); m_pCurrentOutCard = nullptr; } } bool WN_CardManager::init() { if (!Layer::init()) { return false; } // 设置大小; this->setContentSize(Size(1136, 640)); memset(m_cbOutCarCount, 0x0, sizeof(m_cbOutCarCount)); memset(m_pWeaveCard, 0x0, sizeof(m_pWeaveCard)); memset(m_cbWeaveCount, 0x0, sizeof(m_cbWeaveCount)); memset(m_pKingCardSprite, 0x0, sizeof(m_pKingCardSprite)); memset(m_cbHandCardCount, 0x0, sizeof(m_cbHandCardCount)); zeromemory(m_pLastHandCard, sizeof(m_pLastHandCard)); zeromemory(m_bActiveStatus, sizeof(m_bActiveStatus)); m_pCurrentOutCard = nullptr; m_wCurrentUser = INVALID_CHAIR; m_wRealChairCount = GAME_PLAYER; // 高级操作界面 m_pNoticelayer = WN_NotifyDlg::create(); m_pNoticelayer->setVisible(false); this->addChild(m_pNoticelayer, MAX_REPERTORY); return true; } // 重置 void WN_CardManager::ResetAll() { SetCurrentUser(INVALID_CHAIR); memset(m_cbOutCarCount, 0x0, sizeof(m_cbOutCarCount)); memset(m_cbWeaveCount, 0x0, sizeof(m_cbWeaveCount)); memset(m_cbHandCardCount, 0x0, sizeof(m_cbHandCardCount)); zeromemory(m_bActiveStatus, sizeof(m_bActiveStatus)); m_wRealChairCount = GAME_PLAYER; for (int i = 0; i < GAME_PLAYER; i++) { if (m_pLastHandCard[i]) { m_pLastHandCard[i]->removeFromParent(); m_pLastHandCard[i] = nullptr; } ClearCardList(i); for (int l = 0; l < MAX_WEAVE; l++) { if (m_pWeaveCard[i][l]) { m_pWeaveCard[i][l]->removeFromParentAndCleanup(true); m_pWeaveCard[i][l] = nullptr; } } m_cbHandCardCount[i] = 0; m_cbOutCarCount[i] = 0; m_cbWeaveCount[i] = 0; } for (std::list::iterator it = m_pOutCardSprite.begin(); it != m_pOutCardSprite.end(); it++) { WN_SparrowCard* card = *it; if (card) { card->removeFromParentAndCleanup(true); card = nullptr; } } m_pOutCardSprite.clear(); if (m_pCurrentOutCard) { m_pCurrentOutCard->removeFromParent(); m_pCurrentOutCard = nullptr; } if (m_pNoticelayer) { CCLOG("WN_NotifyDlg HideNotifyDlg...WN_CardManager::ResetAll()"); m_pNoticelayer->HideNotifyDlg(); } for (int j = 0; j < 2; j++) { if (m_pKingCardSprite[j]) { m_pKingCardSprite[j]->removeFromParentAndCleanup(true); m_pKingCardSprite[j] = nullptr; } } } // 设置玩家状态 void WN_CardManager::SetActiveStatus(bool bActiveStatus[], WORD wArrViewChairID[], WORD wRealChairCount) { m_wRealChairCount = wRealChairCount; for (int i = 0; i < GAME_PLAYER; i++) { WORD wViewChairID = wArrViewChairID[i]; if (wViewChairID == INVALID_CHAIR) continue; m_bActiveStatus[wViewChairID] = bActiveStatus[i]; //m_wRealChairCount++; // 统计游戏玩家数量; } } // 设置当前玩家 void WN_CardManager::SetCurrentUser(WORD wChairID) { m_wCurrentUser = wChairID; if (m_pNoticelayer) { m_pNoticelayer->m_wCurrentUser = wChairID; } m_bOutCardStatus = (m_wCurrentUser == SELF_VIEW_CHAIRID); } // 设置录像模式; void WN_CardManager::SetGameRecord(bool isGameRecord) { m_IsGameRecord = isGameRecord; } // 设置高级操作界面 void WN_CardManager::SetNoticeData(CMD_S_OperateNotify &OperateNotify) { if (m_pNoticelayer) { CCLOG("WN_NotifyDlg SetNoticeData...WN_CardManager::SetNoticeData()"); m_pNoticelayer->SetNoticeData(&OperateNotify); } } void WN_CardManager::HideNoticeDlg() { if (m_pNoticelayer) { CCLOG("WN_NotifyDlg HideNotifyDlg...WN_CardManager::HideNoticeDlg()"); m_pNoticelayer->HideNotifyDlg(); } } //是否有高级操作 bool WN_CardManager::IsHaveOperateCard(DWORD dwUserAction) { 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; } // 检查操作牌是否正确; bool WN_CardManager::CheckOperateCard(uint8 cbOperateCard) { if (!WN_CGameLogic::IsValidCard(cbOperateCard)) { return false; } // 是不杠(组合牌里有个碰,手里还有一张); for (int i = 0; i < MAX_WEAVE; i++) { if (m_pWeaveCard[SELF_VIEW_CHAIRID][i] && (m_pWeaveCard[SELF_VIEW_CHAIRID][i]->m_dwOperateCode == WIK_WN_PENG) && (m_pWeaveCard[SELF_VIEW_CHAIRID][i]->m_cbCardData == cbOperateCard)) { return true; } } // 暗杠校验(手里有四张); uint8 cbCardCount = 0; for (std::list::iterator it = m_SelfHandCardList.begin(); it != m_SelfHandCardList.end(); it++) { WN_SparrowCard* card = *it; if (card && (card->GetCardData() == cbOperateCard)) { cbCardCount++; } } // 第十四张牌; if (m_pLastHandCard[SELF_VIEW_CHAIRID] && (m_pLastHandCard[SELF_VIEW_CHAIRID]->GetCardData() == cbOperateCard)) { cbCardCount++; } // 暗杠必须4张牌 if (cbCardCount == 4) { return true; } //// 明杠看其他玩家打出牌是否和操作牌相同; //else if (cbCardCount == 3) //{ // if (m_pCurrentOutCard && (m_pCurrentOutCard->GetCardData() == cbOperateCard)) // { // return true; // } //} // //// 摸牌时,未杠下次摸牌提醒杠操作; //// 补杠:查看手中是否有碰组合; //for (int l = 0; l < MAX_WEAVE; l++) //{ // if (m_pWeaveCard[SELF_VIEW_CHAIRID][l] && (m_pWeaveCard[SELF_VIEW_CHAIRID][l]->m_dwOperateCode == WIK_WN_PENG)) // { // for (std::list::iterator it = m_SelfHandCardList.begin(); it != m_SelfHandCardList.end(); it++) // { // WN_SparrowCard* card = *it; // if (card && (card->GetCardData() == m_pWeaveCard[SELF_VIEW_CHAIRID][l]->m_cbCardData)) // { // return m_pWeaveCard[SELF_VIEW_CHAIRID][l]->m_cbCardData; // } // } // } //} // //// 暗杠:查看手中是否有四张一样牌; //uint8 cbIndexArr[MAX_INDEX] = {0}; //for (std::list::iterator it = m_SelfHandCardList.begin(); it != m_SelfHandCardList.end(); it++) //{ // WN_SparrowCard* card = *it; // if (card) // { // uint8 cbIndex = WN_CGameLogic::getInstance()->SwitchToCardIndex(card->GetCardData()); // cbIndexArr[cbIndex]++; // } //} // //for (int i = 0; i < MAX_INDEX; i++) //{ // if (cbIndexArr[i] == 4) // { // return WN_CGameLogic::getInstance()->SwitchToCardData(i); // } //} return false; } /******************************* 麻将牌操作 *****************************************/ // 发所有牌 float WN_CardManager::SetAllCard(uint8 cbCardData[], WORD wStartID) { // 自己发明牌,其他玩家暗牌,调整每个牌属性 for (int i = 0; i < GAME_PLAYER; i++) { if (!m_bActiveStatus[i]) continue; // 没人发13张牌 for (int j = 0; j < MAX_COUNT - 1; j++) { WN_SparrowCard* card = nullptr; // 自己牌 if (i == SELF_VIEW_CHAIRID) { uint8 CardValue = cbCardData[j]; if (WN_CGameLogic::getInstance()->IsValidCard(CardValue)) { card = WN_SparrowCard::createWithDirection(CardValue, SP_SELFSTAND); card->addClickEventListener(CC_CALLBACK_2(WN_CardManager::onSendCardEvent, this)); card->setPosition(GetCardPoint(i, j)); this->addChild(card); m_SelfHandCardList.push_back(card); } // 打印自己牌 log("DEBUG CARD game start my card_%d = 0x%0x ", j, CardValue); } // 对家牌 else if (i == 0) { card = WN_SparrowCard::createWithDirection(0xff, SP_OPPSTAND); card->setPosition(GetCardPoint(i, j)); this->addChild(card); m_OppHandCardList.push_back(card); } // 左边牌 else if (i == 3) { card = WN_SparrowCard::createWithDirection(0xff, SP_LSTAND); card->setPosition(GetCardPoint(i, j)); this->addChild(card, j + SP_LSTAND); m_LeftHandCardList.push_back(card); } // 右边牌 else { card = WN_SparrowCard::createWithDirection(0xff, SP_RSTAND); card->setPosition(GetCardPoint(i, j)); this->addChild(card, SP_RSTAND + MAX_COUNT - j); m_RightHandCardList.push_back(card); } m_cbHandCardCount[i]++; //if (card)card->setVisible(false); } } SortSelfCard(); return 0.0f; } // 发所有牌 float WN_CardManager::SendAllCard(WORD wStartID) { // 发牌从庄家开始,先发三轮每人4张,然后每人发一张 float fDelaytimer = 0.0f; // 延迟时间 for (int i = 0; i < GAME_PLAYER; i++) { std::list* __list = GetCardList(i); for (std::list::iterator it = __list->begin(); it != __list->end(); it++) { WN_SparrowCard* card = *it; if (card) { card->setVisible(true); } } } return fDelaytimer; } // 得到手牌坐标 Point WN_CardManager::GetCardPoint(WORD wChairID, uint8 cbIndex) { // 根据组合牌数量进行偏移 Point pos = GetWaveCardPoint(wChairID); // 自己牌 if (wChairID == SELF_VIEW_CHAIRID) { pos.x = pos.x + NCMJ_SELF_HAND_CARD_WIDHT*cbIndex; pos.y = pos.y; } // 对家牌 else if (wChairID == 0) { pos.x = pos.x - NCMJ_OPP_HAND_CARD_WIDHT*cbIndex; pos.y = pos.y; } // 左边牌 else if (wChairID == 3) { pos.x = pos.x; pos.y = pos.y - NCMJ_LR_HAND_CARD_HIGHT*cbIndex; } // 右边牌 else { pos.x = pos.x; pos.y = pos.y + NCMJ_LR_HAND_CARD_HIGHT*cbIndex; } return pos; } // 发第十四张牌 牌数据,抓牌玩家,前后抓牌 void WN_CardManager::SendCard(uint8 cbCardData, WORD wGetCardUser) { // 打印自己牌 log("DEBUG CARD send card wGetCardUser = %d, card = 0x%0x ", wGetCardUser, cbCardData); WN_SparrowCard* pCard = nullptr; pCard = WN_SparrowCard::createWithDirection(cbCardData, (EN_SPARROW_TYPE)wGetCardUser); if (pCard == nullptr) return; // 录像模式明牌; if (m_IsGameRecord) { pCard->ShowCardValue(cbCardData); } // 清除第十四张牌; if (m_pLastHandCard[wGetCardUser] != nullptr) { m_pLastHandCard[wGetCardUser]->removeFromParentAndCleanup(true); m_pLastHandCard[wGetCardUser] = nullptr; } m_pLastHandCard[wGetCardUser] = pCard; // 未选择出牌之前,不放入玩家手牌中 // 控制添加后的层次关系和坐标 int localZOrder = 0; Point pos; switch (wGetCardUser) { case 0: { int _ind = m_OppHandCardList.size(); pos = GetCardPoint(wGetCardUser, _ind); pos.x = pos.x - NCMJ_OPP_HAND_CARD_WIDHT / 3; localZOrder = 0; break; } case 3: { int _ind = m_LeftHandCardList.size(); pos = GetCardPoint(wGetCardUser, _ind); pos.y = pos.y - NCMJ_LR_HAND_CARD_HIGHT / 3; localZOrder = (MAX_COUNT - 1) + SP_LSTAND; break; } case 2: { int _ind = m_SelfHandCardList.size(); pos = GetCardPoint(wGetCardUser, _ind); pos.x = pos.x + NCMJ_SELF_HAND_CARD_WIDHT / 3; localZOrder = 0; pCard->addClickEventListener(CC_CALLBACK_2(WN_CardManager::onSendCardEvent, this)); break; } case 1: { int _ind = m_RightHandCardList.size(); pos = GetCardPoint(wGetCardUser, _ind); pos.y = pos.y + NCMJ_LR_HAND_CARD_HIGHT / 3; localZOrder = SP_RSTAND + 1; break; } default: ASSERT(false); break; } pCard->setPosition(pos); this->addChild(pCard, localZOrder); auto moveto = MoveTo::create(0.2f, pos); auto ani = EaseBackOut::create(moveto); pCard->runAction(ani); log("send card pos.x = %f, pos.y = %f, z = %d", pos.x, pos.y, localZOrder); } //排序牌 void WN_CardManager::SortSelfCard(WORD wChairID/* = SELF_VIEW_CHAIRID*/) { function funSort; funSort = [](WN_SparrowCard* cardA, WN_SparrowCard* cardB){ if (cardA->GetCardData() < cardB->GetCardData()) { return true; } return false; }; std::list* __list = GetCardList(wChairID); if (__list) { __list->sort(funSort); // 填放位置 ResetHandCard(wChairID); } } // 点击出牌 bool WN_CardManager::onSendCardEvent(cocos2d::Ref *pSender, Vec2 pos) { if (pSender == nullptr) return false; //ImageView* btnRoot = (ImageView*)pSender; WN_SparrowCard* pCardSprite = (WN_SparrowCard*)pSender; if (pCardSprite == nullptr) return false; // 滑动出牌 if (pos.y < (pCardSprite->getPositionY() + pCardSprite->getContentSize().height + TOP_CARD_HEIGHT - 5)) { if (pCardSprite->getPositionY() < TOP_CARD_HEIGHT - 5) { pCardSprite->setPositionY(pCardSprite->getPositionY() + TOP_CARD_HEIGHT); // 把其他已点击的牌落下 for (std::list::iterator it = m_SelfHandCardList.begin(); it != m_SelfHandCardList.end(); it++) { WN_SparrowCard* card = *it; if (card != pCardSprite) { if (card->getPositionY() >= (TOP_CARD_HEIGHT - 5)) { card->setPositionY(card->getPositionY() - TOP_CARD_HEIGHT); } } } return false; } } // 已经弹起,但当前出牌玩家不是自己,麻将收回 if (m_wCurrentUser != SELF_VIEW_CHAIRID) { if (pCardSprite->getPositionY() > TOP_CARD_HEIGHT - 5) { pCardSprite->setPositionY(pCardSprite->getPositionY() - TOP_CARD_HEIGHT); } return false; } else if (m_bOutCardStatus) { // 如果高级界面限制,执行过处理 if (m_pNoticelayer->isVisible()) { m_pNoticelayer->onEventGuo(nullptr); } // 得到出牌值; uint8 cbCardData = pCardSprite->GetCardData(); // 检测是否是杠牌; if (CheckOperateCard(cbCardData)) { auto callback = [cbCardData, this](){ //发送数据 CMD_C_OutCard OutCard; OutCard.cbCardData = cbCardData; EventCustom event(CUSTOM_EVENT_OUT_CARD); event.setUserData(&OutCard); Director::getInstance()->getEventDispatcher()->dispatchEvent(&event); m_bOutCardStatus = false; }; PopScene::Instance().show(utility::a_u8("确定要丢弃杠吗?"), callback, nullptr); } else { //发送数据 CMD_C_OutCard OutCard; OutCard.cbCardData = cbCardData; EventCustom event(CUSTOM_EVENT_OUT_CARD); event.setUserData(&OutCard); Director::getInstance()->getEventDispatcher()->dispatchEvent(&event); m_bOutCardStatus = false; } log("self out card %d", pCardSprite->GetCardData()); } return true; } // 用户出牌 void WN_CardManager::SubOutCard(uint8 cbCardData, WORD wOutCardUser, bool isShow/* = true*/) { if (wOutCardUser == INVALID_CHAIR) return; if (!WN_CGameLogic::getInstance()->IsValidCard(cbCardData)) return; std::list* __list = GetCardList(wOutCardUser); if (__list) { // 插入新牌 if (m_pLastHandCard[wOutCardUser]) { __list->push_back(m_pLastHandCard[wOutCardUser]); m_pLastHandCard[wOutCardUser] = nullptr; } uint8 cbDelCardData = cbCardData; // 游戏模式,删除其他人手牌; if (!m_IsGameRecord && (wOutCardUser != SELF_VIEW_CHAIRID)) { cbDelCardData = 0x0; } // 遍历手牌删除 for (std::list::iterator it = __list->begin(); it != __list->end(); it++) { WN_SparrowCard* card = *it; if (card && (card->GetCardData() == cbDelCardData)) { card->removeFromParentAndCleanup(true); card = nullptr; __list->remove(*it); break; } } // 排序 SortSelfCard(wOutCardUser); } if (isShow) { ShowCurrentCard(wOutCardUser, cbCardData); } } // 组合牌 void WN_CardManager::SubWeaveCard(CMD_S_OperateResult *pOperateResult) { if (m_pNoticelayer->isVisible()) { CCLOG("WN_NotifyDlg HideNotifyDlg...WN_CardManager::SubWeaveCard()"); m_pNoticelayer->HideNotifyDlg(); } if (pOperateResult == nullptr) return; if ((pOperateResult->dwOperateCode&WIK_WN_GANG) != 0) { SetGangWeave(pOperateResult); } else if ((pOperateResult->dwOperateCode&WIK_WN_PENG) != 0) { SetPengWeave(pOperateResult); } else { CCLOG("no operate code %d", pOperateResult->dwOperateCode); } // 重置位置 ResetHandCard(pOperateResult->wOperateUser); // 提供者出的最后一张牌就是操作牌 DelOutCard(pOperateResult->wProvideUser, pOperateResult->cbOperateCard); } void WN_CardManager::SetGangWeave(CMD_S_OperateResult *pOperateResult) { if (pOperateResult == nullptr) return; if ((pOperateResult->dwOperateCode&WIK_WN_GANG) == 0) return; WN_WeaveCard* pWeaveCard = nullptr; bool IsBuGang = false; uint8 cbWeaveCount = m_cbWeaveCount[pOperateResult->wOperateUser]; // 先看是否是补杠 for (uint8 i = 0; i < cbWeaveCount; i++) { if (m_pWeaveCard[pOperateResult->wOperateUser] != nullptr) { WN_WeaveCard* pTmpWeaveCard = m_pWeaveCard[pOperateResult->wOperateUser][i]; if ((pTmpWeaveCard != nullptr) && ((pTmpWeaveCard->m_dwOperateCode&WIK_WN_PENG) != 0) && (pTmpWeaveCard->m_cbCardData == pOperateResult->cbOperateCard)) { pWeaveCard = pTmpWeaveCard; IsBuGang = true; break; } } } // 补杠 if (nullptr != pWeaveCard) { pWeaveCard->SetBuGang(pOperateResult->cbOperateCard); // 补杠:一般情况删除第十四张牌即可,二般情况别人打出的牌可以杠,却选择了碰,碰完之后又选择补杠 SubOutCard(pOperateResult->cbOperateCard, pOperateResult->wOperateUser, false); } else { pWeaveCard = WN_WeaveCard::create(); if (pWeaveCard == nullptr) return; // 设置杠组合; pWeaveCard->ShowCardData(pOperateResult->wOperateUser, pOperateResult->cbOperateCard, pOperateResult->dwOperateCode, pOperateResult->wProvideUser); // 位置计算 Point pos = GetWaveCardPoint(pOperateResult->wOperateUser); pWeaveCard->setPosition(pos); // 右手边玩家注意控制Z轴 if (pOperateResult->wOperateUser == 1) { this->addChild(pWeaveCard, SP_RSTAND + MAX_COUNT - cbWeaveCount); } else { this->addChild(pWeaveCard); } // 记录组合牌 m_pWeaveCard[pOperateResult->wOperateUser][cbWeaveCount] = pWeaveCard; m_cbWeaveCount[pOperateResult->wOperateUser]++; // 删除手牌(杠的时候只需要三张手牌,另一种是别人出牌,如果自己抓牌杠,需要三张手牌,第十四张牌会被新发的牌覆盖) for (int i = 0; i < 3; i++) { SubOutCard(pOperateResult->cbOperateCard, pOperateResult->wOperateUser, false); } // 暗杠再删一张; if (pOperateResult->wProvideUser == pOperateResult->wOperateUser) { SubOutCard(pOperateResult->cbOperateCard, pOperateResult->wOperateUser, false); } } } void WN_CardManager::SetPengWeave(CMD_S_OperateResult *pOperateResult) { if (pOperateResult == nullptr) return; if ((pOperateResult->dwOperateCode&WIK_WN_PENG) == 0) return; WN_WeaveCard* pWeaveCard = WN_WeaveCard::create(); //pWeaveCard->SetCardData(pOperateResult); pWeaveCard->ShowCardData(pOperateResult->wOperateUser, pOperateResult->cbOperateCard, pOperateResult->dwOperateCode, pOperateResult->wProvideUser); // 位置计算 Point pos = GetWaveCardPoint(pOperateResult->wOperateUser); pWeaveCard->setPosition(pos); uint8 cbWeaveCount = m_cbWeaveCount[pOperateResult->wOperateUser]; // 右手边玩家注意控制Z轴 if (pOperateResult->wOperateUser == 1) { this->addChild(pWeaveCard, SP_RSTAND + MAX_COUNT - cbWeaveCount); } else { this->addChild(pWeaveCard); } // 记录组合牌 m_pWeaveCard[pOperateResult->wOperateUser][cbWeaveCount] = pWeaveCard; m_cbWeaveCount[pOperateResult->wOperateUser]++; // 删除手牌(碰的时候只需要删除两张手牌,另一种是别人出牌) //DelHandCard(pOperateResult->wOperateUser, pOperateResult->cbOperateCard, 2); for (int i = 0; i < 2; i++) { SubOutCard(pOperateResult->cbOperateCard, pOperateResult->wOperateUser, false); } } // 组合牌坐标 Point WN_CardManager::GetWaveCardPoint(WORD wChairID) { uint8 cbWeaveCount = m_cbWeaveCount[wChairID]; // 位置计算 Point pos; pos.x = m_ptWeaveCard[wChairID].x; pos.y = m_ptWeaveCard[wChairID].y; // 自己合对家 if (0 == wChairID) { pos.x = pos.x - NCMJ_WEAVE_OPP*cbWeaveCount; } else if (1 == wChairID) { pos.y = pos.y + NCMJ_WEAVE_RIGHT*cbWeaveCount; // 位置偏移 } else if (2 == wChairID) { pos.x = pos.x + NCMJ_WEAVE_SELF*cbWeaveCount; } else if (3 == wChairID) { pos.y = pos.y - NCMJ_WEAVE_LEFT*cbWeaveCount; // 位置偏移 } return pos; } // 删除出牌 void WN_CardManager::DelOutCard(WORD wChairID, uint8 cbCardData) { // 提供者出的最后一张牌就是操作牌 if (m_pCurrentOutCard && m_pCurrentOutCard->GetCardData() == cbCardData) { m_pCurrentOutCard->removeFromParentAndCleanup(true); m_pCurrentOutCard = nullptr; m_cbOutCarCount[wChairID]--; } } // 重置手牌坐标 void WN_CardManager::ResetHandCard(WORD wChairID) { std::list* __list = GetCardList(wChairID); if (__list) { uint8 cbWeaveCout = m_cbWeaveCount[wChairID]; int _Cout = 0; // 非空牌个数 for (std::list::iterator it = __list->begin(); it != __list->end(); it++) { WN_SparrowCard* card = *it; if (card) { Point pos = GetCardPoint(wChairID, _Cout); card->setPosition(pos); // 右边牌 if (wChairID == SP_RSTAND) { card->setLocalZOrder(SP_RSTAND + MAX_COUNT - _Cout - cbWeaveCout); } else if (wChairID == SP_LSTAND) { card->setLocalZOrder(cbWeaveCout + _Cout); } _Cout++; } } } } // 显示当前打出的牌 void WN_CardManager::ShowCurrentCard(WORD wChairID, uint8 cbCardData) { if (wChairID < 0 || wChairID >= GAME_PLAYER) return; if (!WN_CGameLogic::IsValidCard(cbCardData)) return; log("DEBUG CARD wChairID = %d out card = 0x%0x", wChairID, cbCardData); if (m_pCurrentOutCard != nullptr) { m_pCurrentOutCard->SetCurrentOutCard(false); m_pCurrentOutCard = nullptr; } // 显示出牌 WN_SparrowCard* pOutCard = WN_SparrowCard::createWithDirection(cbCardData, (EN_SPARROW_TYPE)(SP_O_OUT + wChairID)); if (pOutCard == nullptr) return; Point endpos = GetOutPoint(wChairID); pOutCard->setPosition(endpos); m_pOutCardSprite.push_back(pOutCard); m_cbOutCarCount[wChairID]++; if (wChairID == SELF_VIEW_CHAIRID) { auto localZ = NCMJ_MAX_DISCARD_COUNT * 4 - m_cbOutCarCount[SELF_VIEW_CHAIRID]; this->addChild(pOutCard, localZ); } else { this->addChild(pOutCard); } pOutCard->SetCurrentOutCard(true); // 当前出牌 m_pCurrentOutCard = pOutCard; } // 显示单个玩家牌 void WN_CardManager::ShowAllHandCard(WORD wChairID, uint8 cbCardCount, const uint8 cbCardData[MAX_COUNT]) { if (cbCardCount <= 0) return; cocos2d::log("game end Chair = %d, Hand card number = %d", wChairID, cbCardCount); // 暴力清空; ClearCardList(wChairID); if (m_pLastHandCard[wChairID] != nullptr) { m_pLastHandCard[wChairID]->removeFromParentAndCleanup(true); m_pLastHandCard[wChairID] = nullptr; } // 重新创建; std::list* __list = GetCardList(wChairID); if (__list) { int __index = 0; uint8 cbWeaveCout = m_cbWeaveCount[wChairID]; for (int i = 0; i < cbCardCount; i++) { // 不是有效值; if (!WN_CGameLogic::IsValidCard(cbCardData[i])) { continue; } WN_SparrowCard* card = nullptr; if (SELF_VIEW_CHAIRID == wChairID) { card = WN_SparrowCard::createWithDirection(cbCardData[i], (EN_SPARROW_TYPE)wChairID); } else { card = WN_SparrowCard::createWithDirection(0, (EN_SPARROW_TYPE)wChairID); } if (card) { card->ShowCardValue(cbCardData[i]); card->setPosition(GetCardPoint(wChairID, __index)); // 右边牌 if (wChairID == SP_RSTAND) { this->addChild(card, SP_RSTAND + MAX_COUNT - __index - cbWeaveCout); } else { this->addChild(card); } __list->push_back(card); __index++; } } } } // 显示最后牌 void WN_CardManager::ShowLastCard(uint8 cbCardData, WORD wGetCardUser, uint8 cbDirection) { if (wGetCardUser == SELF_VIEW_CHAIRID) { SendCard(cbCardData, wGetCardUser); } else { SendCard(0x00, wGetCardUser); } if (m_pLastHandCard[wGetCardUser] != nullptr) { m_pLastHandCard[wGetCardUser]->ShowCardValue(cbCardData); } } /****************************************** 场景恢复 **********************************************************************/ // 组合牌处理 void WN_CardManager::SceneWeaveCard(WORD wViewChairID, uint8 cbWeaveCount, tagWeaveItem WeaveItemArray[MAX_WEAVE], WORD wArrViewChairID[GAME_PLAYER]) { ASSERT(cbWeaveCount <= MAX_WEAVE); for (int i = 0; i < cbWeaveCount; i++) { DWORD dwOperateCode = WeaveItemArray[i].wWeaveKind; uint8 cbTmpWeaveCount = m_cbWeaveCount[wViewChairID]; WN_WeaveCard* pWeaveCard = WN_WeaveCard::create(); if (nullptr == pWeaveCard) continue; // 提供者视图装换; WeaveItemArray[i].wProvideUser = wArrViewChairID[WeaveItemArray[i].wProvideUser]; pWeaveCard->ShowCardData(wViewChairID, WeaveItemArray[i].cbCenterCard, WeaveItemArray[i].wWeaveKind, WeaveItemArray[i].wProvideUser); // 位置计算 Point pos = GetWaveCardPoint(wViewChairID); pWeaveCard->setPosition(pos); // 右手边玩家注意控制Z轴 if (1 == wViewChairID) { this->addChild(pWeaveCard, SP_RSTAND + MAX_COUNT - cbTmpWeaveCount); } else { this->addChild(pWeaveCard); } // 记录组合牌 m_pWeaveCard[wViewChairID][cbTmpWeaveCount] = pWeaveCard; m_cbWeaveCount[wViewChairID]++; } } // 玩家手牌 void WN_CardManager::SceneHandCard(WORD wViewChairID, uint8 cbCardCount, uint8 cbCardData[]) { uint8 cbAllCount = m_cbWeaveCount[wViewChairID] * 3 + cbCardCount; ASSERT((cbAllCount == MAX_COUNT) || (cbAllCount == MAX_COUNT - 1)); if ((cbAllCount != MAX_COUNT) && (cbAllCount != MAX_COUNT - 1)) { return; } int _ind = m_cbWeaveCount[wViewChairID] * 3; // 每个组合都算3张牌 // 显示手牌 for (int j = 0; j < cbCardCount; j++) { // 自己牌处理 if (wViewChairID == 2) { uint8 CardValue = cbCardData[j]; WN_SparrowCard* card = WN_SparrowCard::createWithDirection(CardValue, SP_SELFSTAND); card->addClickEventListener(CC_CALLBACK_2(WN_CardManager::onSendCardEvent, this)); card->setPosition(GetCardPoint(wViewChairID, j)); this->addChild(card); m_SelfHandCardList.push_back(card); } // 对家牌 else if (wViewChairID == 0) { WN_SparrowCard* card = WN_SparrowCard::createWithDirection(0xff, SP_OPPSTAND); card->setPosition(GetCardPoint(wViewChairID, j)); this->addChild(card); m_OppHandCardList.push_back(card); } // 左边牌 else if (wViewChairID == 3) { WN_SparrowCard* card = WN_SparrowCard::createWithDirection(0xff, SP_LSTAND); card->setPosition(GetCardPoint(wViewChairID, j)); this->addChild(card, j + _ind + SP_LSTAND); m_LeftHandCardList.push_back(card); } // 右边牌 else { WN_SparrowCard* card = WN_SparrowCard::createWithDirection(0xff, SP_RSTAND); card->setPosition(GetCardPoint(wViewChairID, j)); this->addChild(card, SP_RSTAND + MAX_COUNT - j - _ind); m_RightHandCardList.push_back(card); } } } // 玩家出牌 void WN_CardManager::SceneOutCard(WORD wViewChairID, uint8 cbCardCount, uint8 cbOutCardData[]) { if (wViewChairID == INVALID_CHAIR) return; // 显示出牌 for (int i = 0; i < cbCardCount; i++) { if (!WN_CGameLogic::getInstance()->IsValidCard(cbOutCardData[i])) continue; // 显示出牌 WN_SparrowCard* pOutCard = WN_SparrowCard::createWithDirection(cbOutCardData[i], (EN_SPARROW_TYPE)((int)SP_O_OUT + wViewChairID)); if (pOutCard == nullptr) continue; Point pos = GetOutPoint(wViewChairID); pOutCard->setPosition(pos); if (wViewChairID == SELF_VIEW_CHAIRID) { auto localZ = NCMJ_MAX_DISCARD_COUNT * 2 - m_cbOutCarCount[SELF_VIEW_CHAIRID]; this->addChild(pOutCard, localZ); } else { this->addChild(pOutCard); } //m_pOutCardSprite[wViewChairID][m_cbOutCarCount[wViewChairID]++] = pOutCard; m_pOutCardSprite.push_back(pOutCard); m_cbOutCarCount[wViewChairID]++; } } // 出牌坐标 Point WN_CardManager::GetOutPoint(WORD wViewChairID) { uint8 cbOutCardCount = m_cbOutCarCount[wViewChairID]; // 根据真实玩家数量,调整出牌排列; WORD wSelfDisCardCount = NCMJ_MAX_DISCARD_COUNT; WORD wOppDisCardCount = NCMJ_MAX_DISCARD_COUNT + 1; WORD wLRDisCardCount = NCMJ_LR_DISCARD_COUNT; int nROutCardY = m_ptOutCard[3].y; int nLOutCardY = m_ptOutCard[1].y; int nSOutCardX = m_ptOutCard[2].x; //// 2人; //if (m_wRealChairCount == 2) //{ // wSelfDisCardCount = NCMJ_MAX_DISCARD_COUNT + 3; //} //else if (m_wRealChairCount == 3) // 3人; //{ // wSelfDisCardCount = NCMJ_MAX_DISCARD_COUNT + 3; // wLRDisCardCount = NCMJ_LR_DISCARD_COUNT + 4; // // 偏移四张牌; // nLOutCardY += NCMJ_LROUT_CARD_HIGHT * 4; // nROutCardY += NCMJ_LROUT_CARD_HIGHT * 4; //} // 两人情况; if (m_wRealChairCount == 2) { // 对家没人左右可加牌; if (!m_bActiveStatus[0]) { wLRDisCardCount = NCMJ_LR_DISCARD_COUNT + 4; // 偏移四张牌; nLOutCardY += NCMJ_LROUT_CARD_HIGHT * 6 + NCMJ_LROUT_CARD_HIGHT / 2; nROutCardY += NCMJ_LROUT_CARD_HIGHT * 6 + NCMJ_LROUT_CARD_HIGHT / 2; } wSelfDisCardCount = NCMJ_MAX_DISCARD_COUNT + 5; // 左侧无人调整起始位置; if (!m_bActiveStatus[3]) { nSOutCardX -= NCMJ_OUT_CARD_WIDHT * 2; } } else if (m_wRealChairCount == 3) // 3人; { wSelfDisCardCount = NCMJ_MAX_DISCARD_COUNT + 3; // 对家没人左右可加牌; if (!m_bActiveStatus[0]) { wLRDisCardCount = NCMJ_LR_DISCARD_COUNT + 4; // 偏移四张牌; nLOutCardY += NCMJ_LROUT_CARD_HIGHT * 6; nROutCardY += NCMJ_LROUT_CARD_HIGHT * 6; } } // 控制添加后的层次关系和坐标 int x = 0; int y = 0; switch (wViewChairID) { case 0: // 出牌数量不过半, 第一排 x = m_ptOutCard[0].x - NCMJ_OUT_CARD_WIDHT * (cbOutCardCount % wOppDisCardCount)*OUT_CARD_SCALE; y = m_ptOutCard[0].y - NCMJ_OUT_CARD_HIGHT * (cbOutCardCount / wOppDisCardCount)*OUT_CARD_SCALE; break; case 3: x = m_ptOutCard[3].x + NCMJ_LROUT_CARD_WIDHT*(cbOutCardCount / wLRDisCardCount)*OUT_CARD_SCALE; y = nROutCardY - NCMJ_LROUT_CARD_HIGHT * (cbOutCardCount % wLRDisCardCount)*OUT_CARD_SCALE; break; case 2: x = nSOutCardX + NCMJ_OUT_CARD_WIDHT * (cbOutCardCount % wSelfDisCardCount)*OUT_CARD_SCALE; y = m_ptOutCard[2].y + NCMJ_OUT_CARD_HIGHT * (cbOutCardCount / wSelfDisCardCount)*OUT_CARD_SCALE; break; case 1: x = m_ptOutCard[1].x - NCMJ_LROUT_CARD_WIDHT*(cbOutCardCount / wLRDisCardCount)*OUT_CARD_SCALE; y = nLOutCardY - NCMJ_LROUT_CARD_HIGHT * (cbOutCardCount % wLRDisCardCount)*OUT_CARD_SCALE; break; default: ASSERT(false); break; } return Point(x, y); } std::list * WN_CardManager::GetCardList(WORD wChairID) { switch (wChairID) { case 0: return &m_OppHandCardList; case 1: return &m_RightHandCardList; case 2: return &m_SelfHandCardList; case 3: return &m_LeftHandCardList; default: break; } return nullptr; } void WN_CardManager::ClearCardList(WORD wChairID) { std::list* __list = GetCardList(wChairID); if (__list == nullptr) return; for (std::list::iterator it = __list->begin(); it != __list->end(); it++) { WN_SparrowCard* card = *it; if (card) { card->removeFromParentAndCleanup(true); card = nullptr; } } __list->clear(); }