斗地主——牌型动画

斗地主——牌型动画

这里引用两篇文章的地址:
手牌框选功能
牌型算法

牌型动画效果在bilibili看吧

框选手牌功能

参考上面链接,我这里就补充一点,上面链接里的博主只做了功能实现,并未适配分辨率。当在你使用了UGUI CanvasScale——>ScaleWithScreenSize——>MatchWidthOrHeight 这种模式进行适配时,

RectTransformUtility.WorldToScreenPoint();
Event.current.mousePosition;

不同分辨率下就会存在误差,理解深的可以自己将转出的屏幕坐标按照Canvas和Screen大小进行适配。

我这里偷工减料了直接将 “牌” 和 “鼠标” 的屏幕坐标直接使用如下接口进行转换

RectTransformUtility.ScreenPointToLocalPointInRectangle();

这里框选代码不贴了,参考上面提供的博文进行更改就行了,实在不会可以私信我。

牌相关动画

我这里自己做的小游戏,主要是完善了下部分功能。主要分为牌型动画、牌型组合、智能提示出牌。
接下来这篇文章主要粘贴牌型动画功能代码。变量要自己去声明,需要有点lua基础,这里主要提供类似于腾讯欢乐斗地主牌型动画,代码还需要去优化。

-- 明牌动画
local LUCKYNUMBER_SHOW = 1;         -- 明牌显示类型
local LUCKYNUMBER_UPDATE = 2;       -- 明牌出牌后更新
local LUCKYNUMBER_ADD_COMCARD = 3;  -- 明牌增加公共牌(暂时没想到好的方案实现???????)

-- 手牌动画
local CardAnimType = {
    E_DeclCard = 1,                 -- 发牌手牌动画
    E_AddCommonCard = 2,            -- 增加公共牌动画
    E_PlayCard = 3,                 -- 出牌后更新手牌动画
}

local horizontalSpace = 50;
--[[
    updateHandCardsAnim         ——更新自己手牌变换动画
    updatePlayCardsAnim         ——出牌的牌型动画
    updateLuckyNumberCardsAnim  ——玩家明牌动画
--]]
function LandlordManager:updateHandCardsAnim(animType, incOrDecCards, callback)
    local operCb = function()
        if callback then
            callback();
        end
    end

    if self.animCo then
        coli.cs_coroutine.stop(self.animCo);
        self.animCo = nil;
    end

    if animType == CardAnimType.E_DeclCard then --发牌动画
        local cards = {};
        local timer = 0.12;

        self.animCo = coli.cs_coroutine.start(function()
            for i,v in ipairs(self.handCards) do
                local len = #cards + 1;
                v.card.transform.localScale = Unity.Vector3(1, 1, 1);
                v.card.transform.localPosition = Unity.Vector3(len*horizontalSpace*0.5, 0, 0);
                v.card.transform:SetSiblingIndex(i-1);

                for k,base in ipairs(cards) do
                    local offsetX = base.card.transform.localPosition.x - horizontalSpace*0.5;
                    base.card.transform:DOLocalMoveX(offsetX, timer):SetEase(Tweening.Ease.Linear);
                end

                table.insert(cards, v);
                coroutine.yield(Unity.WaitForSeconds(timer));
            end

            operCb();
        end);
    elseif animType == CardAnimType.E_AddCommonCard then --增加公共牌动画
        local timer = 0.15;
        local cards = incOrDecCards;
        cards = LandlordTools:SortCards(cards);

        local isCommonCards = function(raw)
            for i,v in ipairs(cards) do
                if v == raw then
                    return true;
                end
            end
            return false;
        end

        local halfLenth = #self.handCards*0.5;

        for i,v in ipairs(self.handCards) do
            v.card.transform.localScale = Unity.Vector3(1, 1, 1);
            v.card.transform:SetSiblingIndex(i-1);

            if isCommonCards(v.baseInfo.rawVal) then
                v.card.transform.localPosition = Unity.Vector3((i - halfLenth)*horizontalSpace, 80, 0);
                v.card.transform:DOLocalMoveY(0, 0.65):SetEase(Tweening.Ease.Linear);
            else
                v.card.transform:DOLocalMoveX((i - halfLenth)*horizontalSpace, timer):SetEase(Tweening.Ease.Linear);
            end
        end

        operCb();
    elseif animType == CardAnimType.E_PlayCard then --出牌后更新手牌动画
        local timer = 0.15;
        local halfLenth = #self.handCards*0.5;

        for i,v in ipairs(self.handCards) do
            v.card.transform:SetSiblingIndex(i-1);
            v.card.transform:DOLocalMoveX((i - halfLenth)*horizontalSpace, timer):SetEase(Tweening.Ease.Linear);
        end

        operCb();
    end
end
function LandlordManager:updatePlayCardsAnim(chair, preChair, cards, callback)
    local isPlayCard = false;
    local isPlayFx = false;

    local _completeAll = function()
        log.info("_completeAll:", isPlayCard, isPlayFx);
        if isPlayCard and isPlayFx then
            if callback then
                callback();
            end
        end
    end

	-- 打出去的牌动画,考虑到存在出牌特效展示,需要在出牌动画和特效播放后才能触发回调。
	-- 我这里用的蠢办法,你们可以自行优化
    local _playCardCompleteCb = function()
        isPlayCard = true;
        _completeAll();
    end
    local _playFxCompleteCb = function()
        isPlayFx = true;
        _completeAll();
    end

    if self.playCardCo then
        coli.cs_coroutine.stop(self.playCardCo);
        self.playCardCo = nil;
    end

    local isMe = chair:isMe();
    local timer = 0.2;
    local cycleTimer = 0.05;
    local len = #cards;
    local chairId = chair:getChairId();
    local uiTranf = CardDisplayPos[chairId].posTransf;
    local type = LandlordTools:GetCardType(self:getRawCards(cards));

    -- 根据类型, 播放出牌特效,没有的话可以注释掉
    self:playfx(chair, preChair, type, _playFxCompleteCb);

    -- 出牌动画
    -- 我这里只做顺子和非顺子两种动画
    if type == CardType.CT_SINGLE_LINE then

        if isMe then
            local scale = Unity.Vector3(0.7, 0.7, 0.7);
            local punchScale = Unity.Vector3(-0.1, -0.1, -0.1);

            self.playCardCo = coli.cs_coroutine.start(function()
                for i,v in ipairs(cards) do
                    v.card.transform:SetParent(uiTranf);
                    v.card.transform.localPosition = Unity.Vector3((i - len * 0.5)*horizontalSpace*0.7, 0, 0);
                    v.card.transform.localScale = scale;
                    v.isHandCard = false;
                    v.card:GetComponent(typeof(Runtime.LuaCardCell)):UpdateContent(v);
                    
                    v.card.transform:DOPunchScale(punchScale, timer, 12, 0.1):SetEase(Tweening.Ease.InQuart);
                    coroutine.yield(Unity.WaitForSeconds(cycleTimer));
                end

                _playCardCompleteCb();
            end);
        else
            local maxCount = 12;
            local offsetY = -50;
            local rate = 0.65;
            local scale = Unity.Vector3(0.6, 0.6, 0.6);
            local punchScale = Unity.Vector3(-0.08, -0.08, -0.08);

            if chair:isLeft() then
                self.playCardCo = coli.cs_coroutine.start(function()
                    for i,v in ipairs(cards) do
                        v.card.transform.localScale = scale;
                        v.card.transform:SetSiblingIndex(i-1);
                        if i <= maxCount then
                            v.card.transform.localPosition = Unity.Vector3((i-1)*horizontalSpace*rate, 0, 0);
                        else
                            v.card.transform.localPosition = Unity.Vector3((i-maxCount-1)*horizontalSpace*rate, offsetY, 0);
                        end

                        v.card.transform:DOPunchScale(punchScale, timer, 12, 0.1):SetEase(Tweening.Ease.InQuart);
                        coroutine.yield(Unity.WaitForSeconds(cycleTimer));
                    end

                    _playCardCompleteCb();
                end);
            else
                self.playCardCo = coli.cs_coroutine.start(function()
                    for i,v in ipairs(cards) do
                        v.card.transform.localScale = scale;
                        if i <= maxCount then
                            v.card.transform.localPosition = Unity.Vector3(-(i-1)*horizontalSpace*rate, 0, 0);
                            v.card.transform:SetSiblingIndex(len-i);
                        else
                            v.card.transform.localPosition = Unity.Vector3(-(i-maxCount-1)*horizontalSpace*rate, offsetY, 0);
                            v.card.transform:SetSiblingIndex(len+(maxCount-i));
                        end

                        v.card.transform:DOPunchScale(punchScale, timer, 12, 0.1):SetEase(Tweening.Ease.InQuart);
                        coroutine.yield(Unity.WaitForSeconds(cycleTimer));
                    end

                    _playCardCompleteCb();
                end);
            end
        end
    else
        -- update card anim
        if isMe then
            local scale = Unity.Vector3(0.7, 0.7, 0.7);

            for i,v in ipairs(cards) do
                v.card.transform:SetParent(uiTranf);
                v.card.transform.localPosition = Unity.Vector3((i - len * 0.5)*horizontalSpace*0.7, 0, 0);
                v.card.transform.localScale = scale;
                v.isHandCard = false;
                v.card:GetComponent(typeof(Runtime.LuaCardCell)):UpdateContent(v);
            end

            uiTranf:DOPunchScale(Unity.Vector3(-0.1, -0.1, -0.1), timer, 12, 0.1):SetEase(Tweening.Ease.InQuart);
        else
            local maxCount = 12;
            local offsetY = -50;
            local rate = 0.65;
            local scale = Unity.Vector3(0.6, 0.6, 0.6);
            local punchScale = Unity.Vector3(-0.08, -0.08, -0.08);

            if chair:isLeft() then
                for i,v in ipairs(cards) do
                    v.card.transform.localScale = scale;
                    v.card.transform:SetSiblingIndex(i-1);
                    if i <= maxCount then
                        v.card.transform.localPosition = Unity.Vector3((i-1)*horizontalSpace*rate, 0, 0);
                    else
                        v.card.transform.localPosition = Unity.Vector3((i-maxCount-1)*horizontalSpace*rate, offsetY, 0);
                    end
                end

                uiTranf:DOPunchScale(punchScale, timer, 12, 0.1):SetEase(Tweening.Ease.InQuart);
            else
                for i,v in ipairs(cards) do
                    v.card.transform.localScale = scale;
                    if i <= maxCount then
                        v.card.transform.localPosition = Unity.Vector3(-(i-1)*horizontalSpace*rate, 0, 0);
                        v.card.transform:SetSiblingIndex(len-i);
                    else
                        v.card.transform.localPosition = Unity.Vector3(-(i-maxCount-1)*horizontalSpace*rate, offsetY, 0);
                        v.card.transform:SetSiblingIndex(len+(maxCount-i));
                    end
                end

                uiTranf:DOPunchScale(punchScale, timer, 12, 0.1):SetEase(Tweening.Ease.InQuart);
            end
        end

        _playCardCompleteCb();
    end
end
function LandlordManager:updateLuckyNumberCardsAnim(chair, luckyType)
    local cards = self.otherHandCards[chair:getChairId()];
    local len = #cards;
    local rate = 0.5;
    local maxCount = 13;
    local offsetY = -40;
    local scale = Unity.Vector3(0.5, 0.5, 0.5);

    if luckyType == LUCKYNUMBER_SHOW then -- 其他玩家点击明牌展示动画
        local punchScale = Unity.Vector3(-0.05, -0.05, -0.05);
        local timer = 0.1;
        local cycleTimer = 0.02;

        if chair:isLeft() then
            if self.leftLuckyAnimCo then
                coli.cs_coroutine.stop(self.leftLuckyAnimCo);
                self.leftLuckyAnimCo = nil;
            end

            self.leftLuckyAnimCo = coli.cs_coroutine.start(function()
                for i,v in ipairs(cards) do
                    v.card.transform.localScale = scale;
                    v.card.transform:SetSiblingIndex(i-1);
                    if i <= maxCount then
                        
                        v.card.transform.localPosition = Unity.Vector3(i*horizontalSpace*rate, 0, 0);
                    else
                        v.card.transform.localPosition = Unity.Vector3((i-maxCount)*horizontalSpace*rate, offsetY, 0);
                    end
                    
                    v.card.transform:DOPunchScale(punchScale, timer, 12, 0.1):SetEase(Tweening.Ease.InQuart);
                    coroutine.yield(Unity.WaitForSeconds(cycleTimer));
                end
            end);
        else
            if self.rightLuckyAnimCo then
                coli.cs_coroutine.stop(self.rightLuckyAnimCo);
                self.rightLuckyAnimCo = nil;
            end

            self.rightLuckyAnimCo = coli.cs_coroutine.start(function()
                for i,v in ipairs(cards) do
                    v.card.transform.localScale = scale;
                    if i <= maxCount then
                        v.card.transform.localPosition = Unity.Vector3(-i*horizontalSpace*rate, 0, 0);
                        v.card.transform:SetSiblingIndex(len-i);
                    else
                        v.card.transform.localPosition = Unity.Vector3(-(i-maxCount)*horizontalSpace*rate, offsetY, 0);
                        v.card.transform:SetSiblingIndex(len+(maxCount-i));
                    end

                    v.card.transform:DOPunchScale(punchScale, timer, 12, 0.1):SetEase(Tweening.Ease.InQuart);
                    coroutine.yield(Unity.WaitForSeconds(cycleTimer));
                end
            end);
        end
    elseif luckyType == LUCKYNUMBER_UPDATE then --其他玩家出牌后,更新明牌
        if chair:isLeft() then
            for i,v in ipairs(cards) do
                v.card.transform.localScale = scale;
                v.card.transform:SetSiblingIndex(i-1);
                if i <= maxCount then
                    v.card.transform.localPosition = Unity.Vector3(i*horizontalSpace*rate, 0, 0);
                else
                    v.card.transform.localPosition = Unity.Vector3((i-maxCount)*horizontalSpace*rate, offsetY, 0);
                end
            end
        else
            for i,v in ipairs(cards) do
                v.card.transform.localScale = scale;
                if i <= maxCount then
                    v.card.transform.localPosition = Unity.Vector3(-i*horizontalSpace*rate, 0, 0);
                    v.card.transform:SetSiblingIndex(len-i);
                else
                    v.card.transform.localPosition = Unity.Vector3(-(i-maxCount)*horizontalSpace*rate, offsetY, 0);
                    v.card.transform:SetSiblingIndex(len+(maxCount-i));
                end
            end
        end
    end
end

结束语

有什么问题欢迎及时指正,万分感谢。有什么想法也可以提出来,咋们共同学习。

异步多任务完成后回调,如何设计?像我上面那样用两个bool值处理肯定是最low的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值