local MJDefine = MJFramework.MJImport("mj.luaScript.MJDefine") local MJMessage = MJFramework.MJImport("mj.luaScript.Protocol.MJMessage") local MJSound = MJFramework.MJImport("mj.luaScript.MJSound") local CommonHandCard = class("CommonHandCard", cc.UIView) function CommonHandCard:ctor(viewId) CommonHandCard.super.ctor(self) self._viewId = viewId self._handCards = {} self._groupNodes = {} self._handCardNodes = {} self:initHandCardConfig() end function CommonHandCard:initHandCardConfig() --[[ if not self._viewId then return end if not MJDefine.MJConfig then return end self._startPos = self:getHandCardStartPos(viewId) self._offsetPos = MJDefine.MJConfig_2d.HandCardOffsetPos[self._viewId] ]] end function CommonHandCard:onEnter() CommonHandCard.super.onEnter(self) --绑定事件 self:bindEvent(app.room , MJDefine.MJEvent.BaiOverOutCards , handler(self , self.baiOverOutCards)) end function CommonHandCard:createHandCards(cards, isGetCard) logD("CommonHandCard:createHandCards", table.tostring(cards)) if self._viewId ~= MJDefine.MyViewId and self._isReplay then logD("CommonHandCard:createHandCards", "回放状态,摊开手牌") self:createOpenHandCards(cards) return end if not cards then return end if isGetCard then self.touchMJ = nil end -- 先整理手牌,再抓牌,避免手牌出现空牌位置 logD("CommonHandCard:createHandCards", "创建手牌前,先整理一下手牌") self:resetHandCards() if type(cards) == "number" then cards = { {card = cards}} end local startIndex = table.nums(self._handCardNodes) + table.nums(self._groupNodes) * 3 for mahjongIndex, v in ipairs(cards) do local card = self:createCard(v.card, self._viewId, startIndex + mahjongIndex) self:addChild(card) table.insert(self._handCardNodes, card) end self:initTouchEvent() self:onAfterCreateHandcards() self:refreshHandCardZOrder() -- 创建完手牌之后,清除所有手牌的选中状态 self:resetHandCardStatus() end --- CommonHandCard:onAfterCreateHandcards 创建手牌之后的处理 function CommonHandCard:onAfterCreateHandcards() -- logD("CommonHandCard:onAfterCreateHandcards") end function CommonHandCard:createCard(value, viewId, mjIndex) local mjType = MJDefine.MJConfig_2d.MJType.Stand local CardClass = require(MJDefine.MJConfig_2d.MAHJONG_CARD) local mjCard = CardClass:new(value, viewId, mjType, mjIndex) local x, y = self:getCardPosition(mjCard, viewId, mjIndex) mjCard:setPosition(cc.p(x, y)) return mjCard end function CommonHandCard:getCardPosition(mjCard, viewId, mjIndex) local x = 0 local y = 0 local cardSize = mjCard:getContentSize() local offset = self:getHandCardOffestPos(viewId) local startPos = self:getHandCardStartPos(viewId) local groupCount = table.nums(self._groupNodes) local dealCardNum = self:getDealHandCardNum() if viewId == MJDefine.PlayerViewType.My then x = startPos.x + (mjIndex - 1) * (cardSize.width + offset.x) y = startPos.y + offset.y x = mjIndex == (dealCardNum + 1) and (x + 10) or x if groupCount > 0 then x = x - 180 + (4 - groupCount) * 50 end elseif viewId == MJDefine.PlayerViewType.Right then x = startPos.x + offset.x y = startPos.y + (mjIndex - 1) * (cardSize.height + offset.y) y = mjIndex == (dealCardNum + 1) and (y + 10) or y if groupCount == 4 then y = y + 100 elseif groupCount == 3 then y = y + 70 elseif groupCount == 2 then y = y + 45 elseif groupCount == 1 then y = y + 15 end elseif viewId == MJDefine.PlayerViewType.Top then x = startPos.x + (1 - mjIndex) * (cardSize.width + offset.x) y = startPos.y + offset.y x = mjIndex == (dealCardNum + 1) and (x - 10) or x if groupCount == 4 then x = x - 45 elseif groupCount == 3 then x = x - 35 elseif groupCount == 2 then x = x - 25 elseif groupCount == 1 then x = x - 15 end elseif viewId == MJDefine.PlayerViewType.Left then x = startPos.x y = startPos.y + (1 - mjIndex) * (cardSize.height + offset.y) y = mjIndex == (dealCardNum + 1) and (y - 10) or y if groupCount == 4 then y = y - 75 elseif groupCount == 3 then y = y - 55 elseif groupCount == 2 then y = y - 30 elseif groupCount == 1 then y = y - 10 end end return x, y end function CommonHandCard:createMahongOpenCard() end function CommonHandCard:clearHandCardNodes() self:removeAllChildren() end function CommonHandCard:sortHandCards() table.sort( self._handCardNodes, function(c1, c2) return c1:getValue() < c2:getValue() end ) end function CommonHandCard:getGroups() end function CommonHandCard:getGroupsLength() return table.nums(self._groupNodes) end function CommonHandCard:getHandCardsLength() return table.nums(self._handCardNodes) end function CommonHandCard:getHandCardNodes() return self._handCardNodes end function CommonHandCard:getViewId() return self._viewId end function CommonHandCard:isHandCardValid() local groupLength = self:getGroupsLength() local handCardLength = self:getHandCardsLength() local dealCardNum = self:getDealHandCardNum() local isValid = (groupLength * 3 + handCardLength) == (dealCardNum + 1) return isValid end function CommonHandCard:initTouchEvent() if self._isReplay then--回放不需要触摸事件 self:getEventDispatcher():removeEventListenersForTarget(self) return end if self._viewId ~= 4 then return end self:getEventDispatcher():removeEventListenersForTarget(self) self:registerTouch( handler(self, self.onTouchBegan), handler(self, self.onTouchMove), handler(self, self.onTouchEnd), handler(self, self.onTouchCancel)) end function CommonHandCard:onTouchBegan(touch) logD("CommonHandCard:onTouchBegan") if self.isTangCard and self.isTangCard == true then--躺牌状态,自动出牌,屏蔽触摸时间 return false end local viewId = self:getViewId() local startPos = self:getHandCardStartPos(viewId) local offsetPos = self:getHandCardOffestPos(viewId) if self.touchMJ and self.isTouchMove then logD("onTouchBegan : ------------2") self:touchOutCard() return false end logD("onTouchBegan : ------------3") local lastMj = self.touchMJ self.touchMJ = nil self.isTouchMove = false --[[ -- if self.touchMJ then -- self.touchMJ:setPositionY(self.initY) -- self.touchMJ:setStatus(MJDefine.MJStatus.Normal) -- self.touchMJ=nil -- end ]] local dealCardNum = self:getDealHandCardNum() local touchPos = self:convertToNodeSpace(touch:getLocation()) for k, v in pairs(self._handCardNodes) do local width = v:getContentSize().width local height = v:getContentSize().height local x = v:getPosition().x - width / 2 local y = v:getPosition().y - height / 2 local rect = cc.Rectangle:new(x, y, width, height) if rect:contains(touchPos.x, touchPos.y) then-- 抓牌状态 if v:getStatus() == MJDefine.MJStatus.Disable then self.touchMJ = lastMj--防止选牌出牌时,点击了一下diaable状态的麻将,再选牌的时候,之前选的那张牌下不来 return end if #self._handCardNodes + #self._groupNodes * 3 ~= (dealCardNum + 1) then -- 非抓牌状态 self.touchMJ = nil; break else -- 抓牌状态 if self._isLock and k ~= #self._handCardNodes then self.touchMJ = nil; break end end if self.baiOutCard and self.baiOutCard == true and v:getSelected()==MJDefine.MJStatus.Select then self.touchMJ = lastMj return--摆牌准备出牌阶段,被选做为摆的牌,不可以被选来打牌 end self.touchMJ = v logD("CommonHandCard:onTouchBegan touchMJ", self.touchMJ:getValue()) if self.touchMJ.status == MJDefine.MJStatus.Select then --双击出牌 if self.isTangOp and self.isTangOp == true then--如果正在躺牌 return false else self:sendOutCard() return false end else if self.isTangOp and self.isTangOp == true then--如果正在躺牌 for _,mjNode in pairs(self._handCardNodes) do if mjNode:getStatus() == MJDefine.MJStatus.Select then mjNode:runDeSelectAnimation(true) mjNode:setStatus(MJDefine.MJStatus.Normal) end end self.touchMJ:recordPostion(cc.p(self.touchMJ:getPositionX(), startPos.y)) self.touchMJ:runSelectAnimation() self.touchMJ:setStatus(MJDefine.MJStatus.Select) app.room:dispatchEvent({name = MJDefine.MJEvent.ShowTangView, card = self.touchMJ:getValue()}) return false else self.touchMJ:recordPostion(cc.p(self.touchMJ:getPositionX(), startPos.y)) self.touchMJ:runSelectAnimation() self.touchMJ:setStatus(MJDefine.MJStatus.Select) app.room:dispatchEvent({name = MJDefine.MJEvent.ShowTing, card = self.touchMJ:getValue()}) end end break end end if self.isTangOp and self.isTangOp == true then--如果正在躺牌 self.touchMJ = lastMj return false end --lastMj 有可能被移除 必须 tolua.isnull 判断一次 if lastMj and not tolua.isnull(lastMj) and lastMj ~= self.touchMJ then lastMj:runDeSelectAnimation(true) lastMj:setStatus(MJDefine.MJStatus.Normal) end if self.baiOutCard and self.baiOutCard == true then --app.room:dispatchEvent({name = MJDefine.MJEvent.ClearBaiView, showValue = 2}) else if self.touchMJ then app.room:dispatchEvent({name = MJDefine.MJEvent.ClearBaiView,value = self.touchMJ:getValue(),showValue = 0}) else app.room:dispatchEvent({name = MJDefine.MJEvent.ClearBaiView}) end end if self.touchMJ then app.room:dispatchEvent({name = MJDefine.MJEvent.SelectCard, value = self.touchMJ:getValue()}) else app.room:dispatchEvent({name = MJDefine.MJEvent.SelectCard}) app.room:dispatchEvent({name = MJDefine.MJEvent.ShowTing}) return false end return true end function CommonHandCard:onTouchMove(touch) logD("CommonHandCard:onTouchMove") local touchPos = self:convertToNodeSpace(touch:getLocation()) local prePos = self:convertToNodeSpace(touch:getPreviousLocation()) local x = math.abs(prePos.x - touchPos.x) local y = math.abs(prePos.y - touchPos.y) if x > 5 or y > 5 then logD("onTouchMove : ------------2") self.isTouchMove = true end if not tolua.isnull(self.touchMJ) and self.isTouchMove == true then self.touchMJ:setPosition(touchPos) self.touchMJ:setLocalZOrder(1) end end function CommonHandCard:onTouchEnd(touch) logD("CommonHandCard:onTouchEnd") self:touchOutCard() end function CommonHandCard:onTouchCancel(touch) logD("onTouchCancel : ------------1") self:touchOutCard() end function CommonHandCard:touchOutCard() logD("touchOutCard : ------------1") if not tolua.isnull(self.touchMJ) and self.isTouchMove then logD("touchOutCard : ------------2") if self.touchMJ:getPositionY() > MJDefine.MJ_TOUCH_OUT_CARD_Y and self.isOutCard then logD("touchOutCard : ------------3") self:sendOutCard() else logD("touchOutCard : ------------4") self.touchMJ:restorePostion() self.touchMJ:setStatus(MJDefine.MJStatus.Normal) app.room:dispatchEvent({name = MJDefine.MJEvent.SelectCard}) app.room:dispatchEvent({name = MJDefine.MJEvent.ShowTing}) self.touchMJ = nil end end logD("touchOutCard : ------------5") self.isTouchMove = false end --发送出牌消息 function CommonHandCard:sendOutCard() logD("CommonHandCard:sendOutCard") if not (self.isOutCard and self.touchMJ) then logD("CommonHandCard:sendOutCard", "不是本家出牌") return end if self.touchMJ:getIsPaoPai() and (not self:getHandCardsIsAllPaoCard()) then self.touchMJ:restorePostion() self.touchMJ:setStatus(MJDefine.MJStatus.Normal) showTooltip("不能打出别人要胡的牌!"); return end if self.baiOutCard and self.baiOutCard == true then --请求亮牌 self.baiOutCard = nil app.room:requestTangCards(self._selectCards,self.touchMJ:getValue()) return end logD("CommonHandCard:sendOutCard", "touchMJ", self.touchMJ:getValue()) local request = MJMessage.Card:new() request.card = self.touchMJ:getValue() -- logE("LHQRecordView:setOutCardVisible"..table.tostring(request)) self:sendMsg( app.room, MJDefine.MJEvent.OutCard, request, function(status, response) logE("CommonHandCard:sendOutCard", "response = ", table.tostring(response)) end ) --音效 local userInfo = app.room:getUserInfoByViewId(self._viewId) local sex = 1 if userInfo then sex = userInfo.sex else logD("CommonHandCard:sendOutCard", "userInfo为空,使用默认性别") end MJSound.PlayMJSound(sex, request.card) self:runOutCardAction(self.touchMJ:getValue()) app.room:dispatchEvent({name = MJDefine.MJEvent.LOCAL_OUT_CARD, card = self.touchMJ:getValue()}) -- app.room:dispatchEvent({name = MJDefine.MJEvent.OutHuCardFalg, card = self.touchMJ:getValue()}) app.room:dispatchEvent({name = MJDefine.MJEvent.OutCardFalg, value = self.touchMJ:getValue(), viewId = self._viewId}) self:setOutCardEnable(false) --插牌 if self.touchMJ == self._handCardNodes[#self._handCardNodes] then table.removeItem(self._handCardNodes, self.touchMJ) else table.removeItem(self._handCardNodes, self.touchMJ) self:runInsertCardAction() end self.touchMJ:removeFromParent() self.touchMJ = nil app.room:dispatchEvent({name = MJDefine.MJEvent.SelectCard}) app.room:dispatchEvent({name = MJDefine.MJEvent.ShowTing}) app.room:dispatchEvent({name = MJDefine.MJEvent.ClearBaiView,showValue = 0}) self:setTing(false) app.room:resetTings() app.room.roomInfo.lastOutViewId = MJDefine.MyViewId self:checkQueAndDisableOtherCard() self:checkBaoAndDisableCard() end function CommonHandCard:getInsertIndex(mjCard) local targetIndex = -1 for k, v in ipairs(self._handCardNodes or {}) do if v == mjCard then targetIndex = mjCard:getMJIndex() break end end return targetIndex end function CommonHandCard:resetHandCards() logD("CommonHandCard:resetHandCards", "重置手牌") if self.isHu and self.isHu == 1 then --todo lwq return end self:sortHandCards() local startIndex = table.nums(self._groupNodes) * 3 for cardIndex, card in ipairs(self._handCardNodes) do local newCardIndex = startIndex + cardIndex local x, y = self:getCardPosition(card, self._viewId, newCardIndex) if (self._viewId ~= MJDefine.MyViewId and self._isReplay) or card:getMJType() == MJDefine.MJConfig_2d.MJType.Open or card:getMJType() == MJDefine.MJConfig_3d.MJType.Open then x, y = self:getOpenCardPosition(card, self._viewId, newCardIndex) end card:setPosition(cc.p(x, y)) card:setMJIndex(newCardIndex) if self._viewId ~= 4 then -- 重新排序,手牌可能乱了,需要重新设置一下手牌的背景 card:initBackImage() end end self:refreshHandCardZOrder() end function CommonHandCard:runOutCardAction(card, callback) if callback then callback() end end function CommonHandCard:isCanOutCard() return self.isOutCard end function CommonHandCard:setOutCardEnable(b) logD("CommonHandCard:setOutCardEnable", "是否可以出牌", b) self.isOutCard = b if b then self:moveLastCard() end -- if self._viewId==MJDefine.MyViewId and self.ui.Items.Button_Sure then -- -- self.ui.Items.Button_Sure:setVisible(b) -- end end function CommonHandCard:moveLastCard(b) end function CommonHandCard:pushTing() self:clearAllTing() local tings = app.room.roomInfo.tings if tings then for _, v in pairs(tings) do for _, mj in pairs(self._handCardNodes) do if mj:getValue() == v.outCard then mj:setTing(true) end end end end end --最后一张牌显示箭头 function CommonHandCard:pushLastCardTing() --爆牌状态只给最后一张牌加听标志 self:clearAllTing() local mj = self._handCardNodes[#self._handCardNodes] mj:setTing(true) end --- -- 清除所有听牌标识 -- @return -- function CommonHandCard:clearAllTing() for _, mj in pairs(self._handCardNodes) do mj:setTing(false) end end function CommonHandCard:setTing(isTing) local handCarsNum = self:getHandCardsLength() if not (handCarsNum%3 == 2) then--如果不是出牌阶段,不显示箭头 isTing = false end for _, mjCard in pairs(self._handCardNodes or {}) do mjCard:setTing(isTing) end end function CommonHandCard:removeHandCard(arg) if type(arg) == "number" then arg = { {card = arg}} end logD("CommonHandCard:removeHandCard", "arg=", table.tostring(arg)) if self._viewId == MJDefine.MyViewId or self._isReplay then for k, v in pairs(arg) do local mj = self:getMjByValue(v.card) if mj then table.removeItem(self._handCardNodes, mj) mj:removeFromParent() end end else -- local num=#self._handCardNodes-#arg -- print(num) for i = #self._handCardNodes, #self._handCardNodes - #arg + 1, -1 do if self._handCardNodes[i] then self._handCardNodes[i]:removeFromParent() table.remove(self._handCardNodes, i) end end end end function CommonHandCard:getMjByValue(card) local mj = nil for k = #self._handCardNodes, 1, -1 do local v = self._handCardNodes[k] if v:getValue() == card then mj = v break end end return mj end --玩家出牌 function CommonHandCard:onOutCard(card) logD("CommonHandCard:onOutCard", "card=", card) -- self:runOutCardAction(card) if self._viewId ~= MJDefine.MyViewId then --其他玩家删除最后一个牌 local mj = self:getMjByValue(card) if mj then self:removeHandCard(card) self:resetHandCards() else local last = #self._handCardNodes if last and self._handCardNodes[last] then self._handCardNodes[last]:removeFromParent() table.remove(self._handCardNodes, last) end end else self:setOutCardEnable(false) local mj = self:getMjByValue(card) --插牌 if mj == self._handCardNodes[#self._handCardNodes] then table.removeItem(self._handCardNodes, mj) self:resetHandCards() else table.removeItem(self._handCardNodes, mj) self:runInsertCardAction() end if mj then mj:removeFromParent() mj = nil end end -- local memberInfo=app.room.roomInfo.memberList[data.response.nUserId] local userInfo = app.room:getUserInfoByViewId(self._viewId) local sex = 1 if userInfo then sex = userInfo.sex else logD("CommonHandCard:sendOutCard", "userInfo为空,使用默认性别") end MJSound.PlayMJSound(sex, card) end --- -- 插牌动画 -- function CommonHandCard:runInsertCardAction() logD("CommonHandCard:runInsertCardAction") self:getEventDispatcher():removeEventListenersForTarget(self) local insertMj = self._handCardNodes[#self._handCardNodes] self:resetHandCards() local x, y = self:getCardPosition(insertMj, self._viewId, 14) insertMj:setPosition(x, y) local targetIndex = insertMj:getMJIndex() local height = insertMj:getContentSize().height local x, y = self:getCardPosition(insertMj, self._viewId, targetIndex) local actions = { cc.MoveTo:create(0, cc.p(insertMj:getPositionX(), insertMj:getPositionY())), cc.MoveTo:create(0.1, cc.p(insertMj:getPositionX(), insertMj:getPositionY() + height)), cc.MoveTo:create(0.1, cc.p(x, insertMj:getPositionY() + height)), cc.MoveTo:create(0.1, cc.p(x, y)), cc.CallFunc:create(function() self:initTouchEvent() --if self.touchMJ and not tolua.isnull(self.touchMJ) then self:resetHandCards() --end end) } insertMj:runAction(cc.Sequence:create(actions)) end function CommonHandCard:removeHandCardByNum(value, num) logD("CommonHandCard:removeHandCardByNum", "value=", value, "num=", num) if self._viewId == MJDefine.MyViewId or self._isReplay then for i = 1, num do local mj = self:getMjByValue(value) if mj then table.removeItem(self._handCardNodes, mj) mj:removeFromParent() end end else for i = #self._handCardNodes, #self._handCardNodes - num + 1, -1 do self._handCardNodes[i]:removeFromParent() table.remove(self._handCardNodes, i) end end end function CommonHandCard:createOpenHandCards(cards) if not cards then return end if self._viewId == MJDefine.MyViewId and not self._isReplay then logD("CommonHandCard:createHandCards", "非回放状态,创建正常手牌") self:createHandCards(cards) return end if type(cards) == "number" then cards = { {card = cards}} end local startIndex = table.nums(self._handCardNodes) + table.nums(self._groupNodes) * 3 for index, v in ipairs(cards) do local mjIndex = startIndex + index local card = self:createOpenCard(v.card, self._viewId, mjIndex) local x, y = self:getOpenCardPosition(card, self._viewId, mjIndex) card:setPosition(cc.p(x, y)) self:addChild(card) table.insert(self._handCardNodes, card) end self:onAfterCreateOpenHandcards() self:refreshHandCardZOrder() end function CommonHandCard:onAfterCreateOpenHandcards() end function CommonHandCard:createOpenCard(value, viewId, mjIndex) local mjType = MJDefine.MJConfig_2d.MJType.Open local CardClass = require(MJDefine.MJConfig_2d.MAHJONG_CARD) local mjCard = CardClass:new(value, viewId, mjType, mjIndex) local x, y = self:getOpenCardPosition(mjCard, viewId, mjIndex) mjCard:setPosition(cc.p(x, y)) return mjCard end function CommonHandCard:getOpenCardPosition(mjCard, viewId, mjIndex) local x = 0 local y = 0 local viewId = self:getViewId() local cardSize = mjCard:getContentSize() local groupCount = table.nums(self._groupNodes) local startPos = self:getHandCardStartPos(viewId) local offset = MJDefine.MJConfig_2d.OpenCardOffsetConfig[viewId] if viewId == MJDefine.PlayerViewType.My then -- 本家不用摊牌 elseif viewId == MJDefine.PlayerViewType.Right then x = startPos.x + offset.x y = startPos.y + (mjIndex - 1) * (cardSize.height + offset.y) y = mjIndex == 14 and (y + 7) or y if groupCount == 4 then y = y + 22 elseif groupCount == 3 then y = y + 18 elseif groupCount == 2 then y = y + 13 elseif groupCount == 1 then y = y + 7 end elseif viewId == MJDefine.PlayerViewType.Top then x = startPos.x + (1 - mjIndex) * (cardSize.width + offset.x) y = startPos.y + offset.y x = mjIndex == 14 and (x - 10) or x if groupCount == 4 then x = x - 45 elseif groupCount == 3 then x = x - 35 elseif groupCount == 2 then x = x - 25 elseif groupCount == 1 then x = x - 15 end elseif viewId == MJDefine.PlayerViewType.Left then x = startPos.x y = startPos.y + (1 - mjIndex) * (cardSize.height + offset.y) y = mjIndex == 14 and (y - 7) or y if groupCount == 4 then y = y - 22 elseif groupCount == 3 then y = y - 20 elseif groupCount == 2 then y = y - 13 elseif groupCount == 1 then y = y - 7 end end return x, y end function CommonHandCard:createGroupCards(arg, fromViewId) local viewId = self:getViewId() for _, v in pairs(arg) do if not fromViewId then fromViewId = v.fromViewId end local groupIndex = table.nums(self._groupNodes) + 1 local group = self:createGroup(v.values, v.showType, viewId, groupIndex) if group then group.fromViewId = v.fromViewId ---保留触发操作的玩家位置,补杠需要 group.opType = v.opType local x, y = self:getGroupPosition(group, groupIndex) group:setPosition(cc.p(x, y)) group:customRefresh(v) self:addChild(group) table.insert(self._groupNodes, group) end end self:resetHandCards() self:refreshGroupZOrder() end function CommonHandCard:getGroupPosition(group, groupIndex) local x = 0 local y = 0 local viewId = self:getViewId() local startPos = self:getHandCardStartPos(viewId) local offset = self:getGroupOffsetConfig(viewId) if viewId == MJDefine.PlayerViewType.My then x = startPos.x + (groupIndex - 1) * offset.x y = startPos.y + offset.y elseif viewId == MJDefine.PlayerViewType.Right then x = startPos.x + offset.x y = startPos.y + (groupIndex - 1) * offset.y elseif viewId == MJDefine.PlayerViewType.Top then x = startPos.x + (1 - groupIndex) * offset.x y = startPos.y + offset.y elseif viewId == MJDefine.PlayerViewType.Left then x = startPos.x + offset.x y = startPos.y + (1 - groupIndex) * offset.y end return x, y end function CommonHandCard:createGroup(values, showType, viewId, groupIndex) local group = nil if showType == MJDefine.MJGroupType.Chi then group = require(MJDefine.MJConfig_2d.GROUP_CHI):new(values, viewId, groupIndex) elseif showType == MJDefine.MJGroupType.Peng then group = require(MJDefine.MJConfig_2d.GROUP_PENG):new(values, viewId, groupIndex) elseif showType == MJDefine.MJGroupType.Gang then group = require(MJDefine.MJConfig_2d.GROUP_GANG):new(values, viewId, groupIndex) elseif showType == MJDefine.MJGroupType.AnGang then group = require(MJDefine.MJConfig_2d.GROUP_ANGANG):new(values, viewId, groupIndex) elseif showType == MJDefine.MJGroupType.BaGang then group = require(MJDefine.MJConfig_2d.GROUP_BAGANG):new(values, viewId, groupIndex) end return group end function CommonHandCard:refreshHandCardZOrder() logD("CommonHandCard:refreshHandCardZOrder", "调整手牌层级") local viewId = self:getViewId() local groupCount = table.nums(self._groupNodes) local handCardNodes = self:getHandCardNodes() or {} for mahjongIndex, card in ipairs(handCardNodes) do local zorder = mahjongIndex if viewId == 1 then zorder = -mahjongIndex elseif viewId == 2 then elseif viewId == MJDefine.PlayerViewType.Left then zorder = zorder + groupCount else end card:setLocalZOrder(zorder) end end function CommonHandCard:resetHandCardStatus() logD("CommonHandCard:resetHandCardStatus", "清除手牌的状态") local handCardNodes = self:getHandCardNodes() or {} for k, v in ipairs(handCardNodes) do if v then local status = v:getStatus() if status == MJDefine.MJStatus.Select then v:setStatus() end end end end function CommonHandCard:lockHandCard(isForbidTouch) logD("CommonHandCard:lockHandCard") self._isLock = true for k, v in pairs(self._handCardNodes or {}) do v:setStatus(MJDefine.MJStatus.Disable) end if isForbidTouch then self:getEventDispatcher():removeEventListenersForTarget(self) end end function CommonHandCard:lockHongZhong(lock) local disableCardNum = 0 for k,v in pairs(self._handCardNodes or {}) do if v.status == MJDefine.MJStatus.Disable then disableCardNum = disableCardNum + 1 end end if disableCardNum == self:getHandCardsLength() then--锁牌了,返回 return end for k,mj in pairs(self._handCardNodes or {}) do if mj:getValue() == 0x41 then if lock then mj:setStatus(MJDefine.MJStatus.Disable) else mj:setStatus(MJDefine.MJStatus.Normal) end end end end function CommonHandCard:isLock() return self._isLock end --- CommonHandCard:getGroup 获取已经存在的组合牌 -- @param mjValue int 麻将牌的值 -- @param opTypes table 麻将牌的类型 function CommonHandCard:getGroup(mjValue, opTypes) if type(opTypes) ~= "table" then opTypes = {opTypes} end for _, vv in pairs(opTypes) do opType = vv for _, v in pairs(self._groupNodes) do if v.opType == opType then local mjCards = v:getCards() if v.opType == MJDefine.MJOperateType.OPREATE_ANGANG then if (mjCards[1]:getValue() == mjValue or mjCards[2]:getValue() == mjValue or mjCards[3]:getValue() == mjValue or mjCards[4]:getValue() == mjValue) then return v end else if (mjCards[1]:getValue() == mjValue or mjCards[2]:getValue() == mjValue or mjCards[3]:getValue() == mjValue) then return v end end end end end end --- CommonHandCard:buGang 补杠 function CommonHandCard:buGang(card) local oldGroup = self:getGroup(card, {MJDefine.MJOperateType.OPREATE_PENG}) if not oldGroup then return end local fromViewId = oldGroup.fromViewId -- 杠牌对家,换成第四张 if app.room:getMaxPlayerCount() == 2 and fromViewId ~= 0 then fromViewId = 4 end if app.room:getMaxPlayerCount() == 4 and fromViewId == 2 then fromViewId = 4 end local index = table.indexOf(self._groupNodes, oldGroup) table.remove(self._groupNodes, index) oldGroup:removeFromParent() local newGroup = self:createGroup({card, card, card, card}, MJDefine.MJGroupType.BaGang, self._viewId, index, cardNum) if not newGroup then return end newGroup.fromViewId = fromViewId newGroup.opType = MJDefine.MJOperateType.OPREATE_BAGANG table.insert(self._groupNodes, index, newGroup) local startPos = self:getHandCardStartPos(self._viewId) local groupOffset = self:getGroupOffsetConfig(self._viewId) local x = startPos.x + groupOffset[index].x local y = startPos.y + groupOffset[index].y newGroup:setPosition(cc.p(x, y)) newGroup:customRefresh(newGroup) self:addChild(newGroup) self:refreshGroupZOrder() end --- CommonHandCard:retoreBuGang 还原补杠 -- @param card 牌值 -- @param cardNum 牌张数 function CommonHandCard:restoreBuGang(card) local oldGroup = self:getGroup( card, { MJDefine.MJOperateType.OPREATE_BAGANG, MJDefine.MJOperateType.OPREATE_ANGANG, MJDefine.MJOperateType.OPREATE_ZHIGANG }) if not oldGroup then return end local fromViewId = oldGroup.fromViewId -- 杠牌对家,换成第四张 if app.room:getMaxPlayerCount() == 2 and fromViewId ~= 0 then fromViewId = 4 end if app.room:getMaxPlayerCount() == 4 and fromViewId == 2 then fromViewId = 4 end local index = table.indexOf(self._groupNodes, oldGroup) table.remove(self._groupNodes, index) oldGroup:removeFromParent() local newGroup = self:createGroup({card, card, card}, MJDefine.MJGroupType.Peng, self._viewId, index) if not newGroup then return end newGroup.fromViewId = fromViewId newGroup.opType = MJDefine.MJOperateType.OPREATE_PENG table.insert(self._groupNodes, index, newGroup) local startPos = self:getHandCardStartPos(viewId) local groupOffset = self:getGroupOffsetConfig(viewId) local x = startPos.x + groupOffset[index].x local y = startPos.y + groupOffset[index].y newGroup:setPosition(cc.p(x, y)) self:addChild(newGroup) self:refreshGroupZOrder() end --- CommonHandCard:removeLastHandCard 移除最后一张手牌 function CommonHandCard:removeLastHandCard() if #self._handCardNodes + #self._groupNodes * 3 <= 13 then -- 手牌数量不足14张,不能移除,否则会少牌 return false end local lastIndex = #self._handCardNodes self._handCardNodes[lastIndex]:removeFromParent() table.remove(self._handCardNodes, lastIndex) return true end function CommonHandCard:getLastCard() return self._handCardNodes[#self._handCardNodes] end function CommonHandCard:removeAllHandCards() for k, v in ipairs(self._handCardNodes or {}) do v:removeFromParent() end self._handCardNodes = {} end function CommonHandCard:setReplay(b) self._isReplay = b end function CommonHandCard:refreshGroupZOrder() for k, v in ipairs(self._groupNodes) do if self:getViewId() == MJDefine.PlayerViewType.Right then v:setLocalZOrder(table.nums(self._groupNodes) - k) else v:setLocalZOrder(k) end end end --- -- 获取手牌起始位置,3d必须重写 -- @param viewId 玩家本地座位 -- function CommonHandCard:getHandCardStartPos(viewId) local pos = MJDefine.MJConfig_2d.HandCardStartPos[viewId] if MJDefine.MJConfig_2d.HandCardStartPosOfCardNum then local cardNum = self:getDealHandCardNum() pos = MJDefine.MJConfig_2d.HandCardStartPosOfCardNum[cardNum][viewId] end return pos end --- -- 获取手牌偏移位置,3d必须重写 -- @param viewId 玩家本地座位 -- function CommonHandCard:getHandCardOffestPos(viewId) return MJDefine.MJConfig_2d.HandCardOffsetPos[viewId] end --- -- 获取组合牌偏移位置,3d必须重写 -- @param viewId 玩家本地座位 -- function CommonHandCard:getGroupOffsetConfig(viewId) return MJDefine.MJConfig_2d.GroupOffsetConfig[viewId] end --删除触摸事件only function CommonHandCard:removeTouchEventOnly() self:getEventDispatcher():removeEventListenersForTarget(self) end --初始化换牌触摸事件 function CommonHandCard:initSwapCardTouchEvent() if self._isReplay then--回放不需要触摸事件 self:getEventDispatcher():removeEventListenersForTarget(self) return end self._selectCards = nil self:getEventDispatcher():removeEventListenersForTarget(self) --注册交换牌时的触摸事件 self:registerTouch(handler(self,self.onSwapTouchBegan)) end --换三张时的触摸事件 function CommonHandCard:onSwapTouchBegan(touch) self._selectCards = self._selectCards or {} local viewId = self:getViewId() local startPos = self:getHandCardStartPos(viewId) local touchPos=self:convertToNodeSpace(touch:getLocation()) for k,v in pairs(self._handCardNodes) do local width = v:getContentSize().width local height = v:getContentSize().height local x = v:getPosition().x-width/2 local y = v:getPosition().y-height/2 local rect = cc.Rectangle:new(x,y,width,height) if rect:contains(touchPos.x,touchPos.y) then local t_touchMJ=v--self.touchMJ if t_touchMJ:getSelected()==MJDefine.MJStatus.Select then t_touchMJ:runDeSelectAnimationWithTime(0.1) t_touchMJ:setSelected(MJDefine.MJStatus.Normal) table.removeItem(self._selectCards,t_touchMJ) else t_touchMJ:recordPostion(cc.p(t_touchMJ:getPositionX(), startPos.y)) t_touchMJ:runSelectAnimation() t_touchMJ:setSelected(MJDefine.MJStatus.Select) table.insert(self._selectCards,t_touchMJ) end if self:checkIsInSwapRule() then app.room:dispatchEvent({name = MJDefine.MJEvent.CheckIsInSwapRule,canCommit=true}) else app.room:dispatchEvent({name = MJDefine.MJEvent.CheckIsInSwapRule,canCommit=false}) end break end end end --初始化摆牌触摸事件 function CommonHandCard:initBaiCardTouchEvent() if self._isReplay then--回放不需要触摸事件 self:getEventDispatcher():removeEventListenersForTarget(self) return end self:getEventDispatcher():removeEventListenersForTarget(self) self._selectCards = nil --注册交换牌时的触摸事件 self:registerTouch(handler(self,self.onBaiPaiTouchBegan)) end --摆牌时的触摸事件 function CommonHandCard:onBaiPaiTouchBegan(touch) self._selectCards = self._selectCards or {} local viewId = self:getViewId() local startPos = self:getHandCardStartPos(viewId) local touchPos=self:convertToNodeSpace(touch:getLocation()) for k,v in pairs(self._handCardNodes) do local width = v:getContentSize().width local height = v:getContentSize().height local x = v:getPosition().x-width/2 local y = v:getPosition().y-height/2 local rect = cc.Rectangle:new(x,y,width,height) if rect:contains(touchPos.x,touchPos.y) then local t_touchMJ=v--self.touchMJ if t_touchMJ:getSelected()==MJDefine.MJStatus.Select then --t_touchMJ:runDeSelectAnimationWithTime(0.1) t_touchMJ:setNormalColor() t_touchMJ:setSelected(MJDefine.MJStatus.Normal) table.removeItem(self._selectCards,t_touchMJ:getValue()) else --t_touchMJ:recordPostion(cc.p(t_touchMJ:getPositionX(), startPos.y)) --t_touchMJ:runSelectAnimation() local color = cc.c3b(218, 218, 128) t_touchMJ:setColor(color) t_touchMJ:setSelected(MJDefine.MJStatus.Select) table.insert(self._selectCards,t_touchMJ:getValue()) end if #self._selectCards > 0 then app.room:dispatchEvent({name = MJDefine.MJEvent.ChagneBaiCards,canCommit=true,selectCards = self._selectCards}) else app.room:dispatchEvent({name = MJDefine.MJEvent.ChagneBaiCards,canCommit=false,selectCards = {}}) end break end end end --判断是否符合换三张规则 function CommonHandCard:checkIsInSwapRule() local selectNums = #self._selectCards logD("CommonHandCard:checkIsInSwapRule1 "..selectNums) if selectNums ~= 3 then return false end local huase = self._selectCards[1]:getMJColorType() logD("CommonHandCard:checkIsInSwapRule2 "..huase) for i,v in pairs(self._selectCards) do local tHuase = v:getMJColorType() logD("CommonHandCard:checkIsInSwapRule3 "..tHuase) if tHuase ~= huase then return false end end logD("CommonHandCard:checkIsInSwapRule4 ") return true end --获取选择的牌 function CommonHandCard:getSelectedCards() local tselCards = {} for i,v in pairs(self._selectCards) do table.insert(tselCards,v:getValue()) end return tselCards end --通过传进来的参数cards来选出手牌里的cards,服务器推荐选牌用 function CommonHandCard:selectCardsByCards(cards) self._selectCards = self._selectCards or {} local viewId = self:getViewId() local startPos = self:getHandCardStartPos(viewId) for i,v in pairs(cards) do for j,k in pairs(self._handCardNodes) do if k:getValue() == v.card and (k:getSelected() ~= MJDefine.MJStatus.Select) then k:recordPostion(cc.p(k:getPositionX(),startPos.y)) k:runSelectAnimation() k:setSelected(MJDefine.MJStatus.Select) table.insert(self._selectCards,k) break end end end end --删除选中的牌 function CommonHandCard:deleteSelectedCards() if not self._selectCards or #self._selectCards == 0 then return end local tselCards = {} for i,v in pairs(self._selectCards) do table.insert(tselCards,{card = v:getValue()}) end self:removeHandCard(tselCards) self:resetHandCards() end -- todo lwq 血流专用 胡牌后,玩家的牌要躺下 function CommonHandCard:setIsHupai(hu) self.isHu = hu end function CommonHandCard:getIsHupai(hu) return self.isHu end --设置定缺类型 0万,1同,2条 function CommonHandCard:setQueType(que) logD("CommonHandCard:setQueType "..(que or "kongzhi")) self.queType = que end --检查手牌是否有定缺牌 function CommonHandCard:checkHandCardHaveQue(que) for k,v in pairs(self._handCardNodes) do if v:getMJColorType() == self.queType then return true end end return false end --检测定缺牌,屏蔽缺牌以外的牌(定缺牌打完钱不能打别的牌) function CommonHandCard:checkQueAndDisableOtherCard() logD("CommonHandCard:checkQueAndDisableOtherCard "..(self.queType or "kongzhi")) if not self.queType or self.queType > 2 or self.queType < 0 then return end local handcardNum = #self._handCardNodes local isMyGetCard = (handcardNum%3 == 2)--是否是自己摸牌阶段 logD("CommonHandCard:checkQueAndDisableOtherCard "..handcardNum) if isMyGetCard and self:checkHandCardHaveQue() then logD("CommonHandCard:checkQueAndDisableOtherCard 11111") for k,v in pairs(self._handCardNodes) do if v:getMJColorType() ~= self.queType then v:setStatus(MJDefine.MJStatus.Disable) else v:setStatus(MJDefine.MJStatus.Normal) end end else logD("CommonHandCard:checkQueAndDisableOtherCard 22222") for k,v in pairs(self._handCardNodes) do v:setStatus(MJDefine.MJStatus.Normal) end end end --检测报牌,diable手牌 function CommonHandCard:checkBaoAndDisableCard() if self.baopai and self.baopai == 1 then self:setHandCardsDidable() else self:setNotTingCardDidable(false) end end --设置所有手牌状态为Disable function CommonHandCard:setHandCardsDidable() for k,v in pairs(self._handCardNodes) do v:setStatus(MJDefine.MJStatus.Disable) end end --设置所有手牌状态为Disable function CommonHandCard:setNotTingCardDidable(is) if is then for _,mjNode in pairs(self._handCardNodes) do if not mjNode:getTing() then mjNode:setStatus(MJDefine.MJStatus.Disable) else mjNode:setStatus(MJDefine.MJStatus.Normal) end end else for _,mjNode in pairs(self._handCardNodes) do mjNode:setStatus(MJDefine.MJStatus.Normal) end end end --创建换三张的牌 function CommonHandCard:createSwapCards(cards) local index = 1 local viewId = self:getViewId() if viewId == MJDefine.PlayerViewType.My then index = 4 elseif viewId == MJDefine.PlayerViewType.Left then index = 4 elseif viewId == MJDefine.PlayerViewType.Top then index = 4 end local group = self:createGroup(cards, MJDefine.MJGroupType.Chi, self:getViewId(), index) if group then return group end return nil end -- 吃的牌不能立即打出去 function CommonHandCard:cardEnabled( cards, is ) if is then for _,card in pairs(cards) do for _,mjNode in pairs(self._handCardNodes) do if mjNode:getValue() == card then mjNode:setStatus(MJDefine.MJStatus.Disable) end end end else for _,mjNode in pairs(self._handCardNodes) do mjNode:setStatus(MJDefine.MJStatus.Normal) end end end --可以躺牌的时候,disable非听牌 function CommonHandCard:tangCardEnabled(is) self.touchMJ = nil if is then self.isTangOp = true--正在躺操作 for _,mjNode in pairs(self._handCardNodes) do local isTingCard = mjNode:getTing() local a = not mjNode:getTing() if not mjNode:getTing() then if mjNode:getStatus() == MJDefine.MJStatus.Select then mjNode:setStatus(MJDefine.MJStatus.Normal) mjNode:runDeSelectAnimation(true) end mjNode:setStatus(MJDefine.MJStatus.Disable) else if mjNode:getStatus() == MJDefine.MJStatus.Select then mjNode:runDeSelectAnimation(true) end mjNode:setStatus(MJDefine.MJStatus.Normal) end end else self.isTangOp = false--正在躺操作 for _,mjNode in pairs(self._handCardNodes) do if mjNode:getStatus() == MJDefine.MJStatus.Select then mjNode:runDeSelectAnimation(true) end mjNode:setSelected(MJDefine.MJStatus.Normal) mjNode:setStatus(MJDefine.MJStatus.Normal) end end end --设置躺状态 function CommonHandCard:setIsTanging(is) self.isTangOp = is or false end --设置躺牌 function CommonHandCard:setTangCard(is,cards) if is then for _,card in pairs(cards) do for _,mjNode in pairs(self._handCardNodes) do if mjNode:getValue() == card.card and (not mjNode.tang) then local color = cc.c3b(218, 218, 128) mjNode:setColor(color) mjNode.tang = true break end end end else for _,mjNode in pairs(self._handCardNodes) do mjNode:setNormalColor() mjNode.tang = false end end end --设置炮牌 function CommonHandCard:setPaoCard(is,cards) if is then self.paoCards = self.paoCards or {} if cards and type(cards) == 'table' and #cards > 0 then for _,card in pairs(cards) do table.insert(self.paoCards,card.card) end end for _,card in pairs(self.paoCards) do for _,mjNode in pairs(self._handCardNodes) do if mjNode:getValue() == card then mjNode:setPaoFlag(true) end end end else self.paoCards = {} for _,mjNode in pairs(self._handCardNodes) do mjNode:setPaoFlag(false) end end end --显示别人的躺牌 function CommonHandCard:showTangCard(is,cards) if is then local index = 1 for _,card in pairs(cards) do local mjNode = self._handCardNodes[index] mjNode:setValue(card.card) mjNode._newValue = string.format("%x", card.card) mjNode:setMJType(MJDefine.MJConfig_2d.MJType.Open) mjNode:initViews() local color = cc.c3b(218, 218, 128) mjNode:setColor(color) index = index + 1 end self:resetHandCards() else for _,mjNode in pairs(self._handCardNodes) do mjNode:setNormalColor() end end end --躺成功了 function CommonHandCard:setTangSuccess(is) self.isTangCard = is end function CommonHandCard:setBaoPai(flag) self.baopai = flag end -- 获取手牌是否全是炮牌,全手炮牌可以出任意牌 function CommonHandCard:getHandCardsIsAllPaoCard() --如果爆牌了,则只能出摸上来的牌 if self.baopai and self.baopai == 1 then return true end for _,mjNode in pairs(self._handCardNodes) do if mjNode:getIsPaoPai() == false then return false end end return true end --- -- 获取手牌默认发牌张数 -- 默认为13张,如果有不同,子游戏重写该方法 -- @return -- function CommonHandCard:getDealHandCardNum () return 13 end --选择完摆的牌准备出牌了 function CommonHandCard:baiOverOutCards(event) self:initTouchEvent() self.baiOutCard = true end return CommonHandCard