100个 Unity小游戏系列六 -Unity 抽奖游戏专题四 翻卡游戏

一、演示效果

二、知识点讲解

2.1 布局

cs 复制代码
  void CreateItems()
        {
            reward_data_list = reward_data_list ?? new List<RewardData>();
            reward_data_list.Clear();


            for (int i = 0; i < ItemCount; i++)
            {

                GameObject item;
                if (i + 1 <= itemParent.childCount)
                {
                    item = itemParent.GetChild(i).gameObject;
                }
                else
                {
                    item = Instantiate(itemParent.GetChild(0).gameObject, itemParent);
                }

                item.transform.localPosition = initPosArr[i];
                item.transform.localScale = Vector3.one;
                var cardGraphics = item.transform.Find("Graphics").GetComponent<RectTransform>();

                RefreshCardData(cardGraphics, false, rewardDatas[i]);
                SetCardOpen(false, item.GetComponent<Button>(), true, rewardDatas[i]);
            }

            StartAnim(rewardDatas);
        }

/// <summary>
        /// 明牌,洗牌动画
        /// </summary>
        private void StartAnim(RewardData[] rewardsArr)
        {
            CardSelectable = false;

            if (rewardsArr.Length != itemParent.childCount)
            {
                Debug.LogErrorFormat("rewards length is not equals cards count:{0}", itemParent.childCount);
                return;
            }

            isSwapCard = true;
            var seqAnim = DOTween.Sequence();
            seqAnim.AppendInterval(2f);
            seqAnim.AppendCallback(() =>
            {
                int overCount = itemParent.childCount;
                for (int i = 0; i < itemParent.childCount; i++)
                {
                    SetCardOpen(false, itemParent.GetChild(i).GetComponent<Button>(), false, null, 0.2f, () =>
                    {
                        //所有卡片翻回去之后开始洗牌
                        if (--overCount <= 0)
                        {
                            List<int> cardsList = new List<int>();

                            for (int childIndex = 0; childIndex < itemParent.childCount; childIndex++)
                            {
                                cardsList.Add(childIndex);
                            }


                            SwapCards(cardsList, 10, () =>
                            {
                                RefreshCardADState(false);
                                CardSelectable = true;
                            });
                        }
                    });
                }
            });
        }

2.2 转动逻辑

cs 复制代码
 private void SwapCards(List<int> cardsList, int swapCount, Action onComplete)
        {
            if (swapCount <= 0)
            {
                onComplete?.Invoke();
                return;
            }

            SwapCardAnim(cardsList, () =>
            {
                ListRandom(cardsList);
                SwapCards(cardsList, --swapCount, onComplete);
            });
        }

        public static void ListRandom<T>(List<T> sources)
        {
            int index;
            T temp;
            for (int i = 0; i < sources.Count; i++)
            {
                index = UnityEngine.Random.Range(0, sources.Count);
                if (index != i)
                {
                    temp = sources[i];
                    sources[i] = sources[index];
                    sources[index] = temp;
                }
            }
        }
        /// <summary>
        /// 洗牌动画
        /// </summary>
        /// <param name="onSwapOver"></param>
        private void SwapCardAnim(List<int> cardsindexList, Action onSwapOver)
        {
            if (itemParent.childCount % 2 != 0)
            {
                Debug.LogError("cardsRoot 卡片个数不能为奇数");
                return;
            }

            int moveMission = itemParent.childCount;
            TweenCallback onMoveOver = () =>
            {
                if (--moveMission <= 0)
                {
                    onSwapOver?.Invoke();
                }
            };
            for (int i = 0; i < cardsindexList.Count; i += 2)
            {
                var indexA = cardsindexList[i];
                var indexB = cardsindexList[i + 1];
                var cardA = itemParent.GetChild(indexA);
                var cardB = itemParent.GetChild(indexB);
                float moveDuration = Vector2.Distance(initPosArr[indexA], initPosArr[indexB]) / 1500;
                moveDuration = Mathf.Clamp(moveDuration, 0, 0.18f);

                cardA.DOLocalMove(initPosArr[indexB], moveDuration).onComplete = onMoveOver;
                cardB.DOLocalMove(initPosArr[indexA], moveDuration).onComplete = onMoveOver;
            }
        }

        private void SetCardOpen(bool isUser, Button cardBt, bool isOpen, RewardData reward = null, float duration = 0.2f, Action onCardAnimOver = null)
        {
            if (isOpen && reward == null)
            {
                Debug.LogError("翻卡传入奖励数据为null");
                return;
            }
            if (isUser && !CardSelectable)
            {
                return;
            }
            CardSelectable = false;
            int texIndex = 0;
            int colorIndex = 0;
            string tmStr = string.Empty;
            Vector3 halfRotate = new Vector3(0, 90, 0);
            if (isOpen)
            {
                texIndex = reward.type;
                colorIndex = reward.type - 1;
                tmStr = reward.amount.ToString();
                halfRotate.y = 270;
            }

            cardBt.interactable = !isOpen;

            var card = cardBt.transform;
            var cardGraphics = card.Find("Graphics").GetComponent<RectTransform>();

            var seqAnim = DOTween.Sequence();
            seqAnim.Append(cardGraphics.DOLocalRotate(halfRotate, duration).SetEase(Ease.Linear));
            seqAnim.AppendCallback(() =>
            {
                RefreshCardData(cardGraphics, isOpen, reward);
            });
            seqAnim.Append(cardGraphics.DOLocalRotate(halfRotate + Vector3.up * 90, duration).SetEase(Ease.Linear));
            seqAnim.onComplete = () =>
            {
                if (!isUser)
                {
                    //CardSelectable = true;
                    onCardAnimOver?.Invoke();
                }
            };
            if (isUser)
            {
                card.SetSiblingIndex(itemParent.childCount);
                //float moveDuration = Vector2.Distance(card.transform.localPosition, Vector3.zero) / 400;
                //moveDuration = Mathf.Clamp(moveDuration, 0, 0.4f);
                //card.DOMove(Vector3.zero, moveDuration);
                //card.DOScale(1.4f, moveDuration).onComplete = () =>
                //{
                //    var moveSeq = DOTween.Sequence();
                //    moveSeq.AppendInterval(1.0f);
                //    moveSeq.AppendCallback(() =>
                //    {
                //        var smallCard = smallCardsRoot.GetChild(CurClaimIndex);
                //        moveDuration = Mathf.Clamp(Vector2.Distance(card.position, smallCard.position) / 10, 0, 0.4f);
                //        card.DOScale(smallCard.GetComponent<RectTransform>().sizeDelta.x / card.GetComponent<RectTransform>().sizeDelta.x, moveDuration);
                //        card.DOMove(smallCard.position, moveDuration).onComplete = () =>
                //        {
                //            CardSelectable = true;
                //            GF.Sound.PlaySound("poker_end.wav", false);

                //            //加奖励
                //            GF.UserData.ClaimReward(UserDataType.LuckpokerRedpacket, reward, GF.UserData.GameUIForm.gameMainView.levelSocreTxt.transform);
                //            onCardAnimOver?.Invoke();
                //        };
                //    });
                //};


                CardSelectable = true;
                onCardAnimOver?.Invoke();
            }
        }

三 、完整代码逻辑

https://github.com/lixianjun0903/luckydraw-master.git

相关推荐
ZBzibing39 分钟前
[游戏技术]L4D服务器报错解决
服务器·游戏
琪智科技5 小时前
秦时明月6.2魔改版+GM工具+虚拟机一键端
游戏
dangoxiba6 小时前
【Unity学习心得】如何使用Unity制作“饥荒”风格的俯视角2.5D游戏
游戏·unity·c#·游戏引擎
qq 1778036228 小时前
智能新时代,游戏盾守护顺畅体验
运维·服务器·网络·游戏·云计算·ddos·ip
cyr___8 小时前
Unity教程(十六)敌人攻击状态的实现
学习·游戏·unity·游戏引擎
nbsaas-boot9 小时前
架构卡牌游戏:通过互动与挑战学习系统设计的创新玩法
学习·游戏·架构
FairGuard手游加固9 小时前
游戏如何应对云手机刷量问题
游戏
哆木9 小时前
部署在线GBA游戏,并通过docker安装启动
游戏·html·gba
优梦创客16 小时前
《黑神话悟空》开发框架与战斗系统解析
unity·游戏开发·黑神话悟空·战斗系统·解包
仙魁XAN1 天前
Unity 设计模式 之 创造型模式-【工厂方法模式】【抽象工厂模式】
unity·设计模式·工厂方法模式·抽象工厂模式