Hi,以前有同窗說要我把源碼發出來,那我就把半成品源碼的連接放在每篇文件的最後,有興趣的話能夠查閱參考,有問題能夠跟我私信,也能夠關注個人我的公衆號,互相交流嘛。固然,代碼也是在不斷的持續改進中~git
上期咱們實現了叫地主功能,不過遺留了一個小功能:叫地主完成之後,要顯示地主的3張牌,這期首先彌補這塊的功能;github
接着咱們要進入開發出牌邏輯的開發階段,好了,廢話很少說,繼續咱們鬥地主開發之旅~dom
咱們在玩家界面的頂部中間位置,放置一個新的GameObject,命名爲BidCards,用來記錄3張地主牌的顯示位置。ide
因此咱們重構了CardManager中的發牌方法,在給地主發牌同時,生成地主牌的實例,放在BidCards相應位置:測試
/// <summary> /// 發牌堆上的牌(若是如今不是搶地主階段,發普通牌,若是是,發地主牌) /// </summary> /// <returns></returns> private IEnumerator DealHeapCards(bool ifForBid) { //顯示牌堆 heapPos.gameObject.SetActive(true); playerHeapPos.ToList().ForEach(s => { s.gameObject.SetActive(true); }); var cardNamesNeeded = ifForBid ? cardNames.Skip(cardNames.Length - 3).Take(3) //若是是搶地主牌,取最後3張 : cardNames.Take(cardNames.Length - 3); //若是首次發牌 //計算每張地主牌的位置 int cardIndex = 0; var width = (bidCards.GetComponent<RectTransform>().sizeDelta.x - 20) / 3; var centerBidPos = Vector3.zero; var leftBidPos = centerBidPos - Vector3.left * width; var rightBidPos = centerBidPos + Vector3.left * width; List<Vector3> bidPoss = new List<Vector3> { leftBidPos, centerBidPos, rightBidPos }; foreach (var cardName in cardNamesNeeded) { //給當前玩家發一張牌 Players[termCurrentIndex].AddCard(cardName); var cover = Instantiate(coverPrefab, heapPos.position, Quaternion.identity, heapPos.transform); cover.GetComponent<RectTransform>().localScale = Vector3.one; //移動動畫,動畫結束後自動銷燬 var tween = cover.transform.DOMove(playerHeapPos[termCurrentIndex].position, 0.3f); tween.OnComplete(() => Destroy(cover)); yield return new WaitForSeconds(1 / dealCardSpeed); //若是給地主發牌 if (ifForBid) { //顯示地主牌 var bidcard = Instantiate(cardPrefab, bidCards.transform.TransformPoint(bidPoss[cardIndex]), Quaternion.identity, bidCards.transform); bidcard.GetComponent<Card>().InitImage(new CardInfo(cardName)); bidcard.GetComponent<RectTransform>().localScale = Vector3.one * 0.3f; } else { //下一個須要發牌者 SetNextPlayer(); } cardIndex++; } //隱藏牌堆 heapPos.gameObject.SetActive(false); playerHeapPos[0].gameObject.SetActive(false); //發普通牌 if (!ifForBid) { //顯示玩家手牌 ShowPlayerSelfCards(); StartBiding(); } //發地主牌 else { if (Players[bankerIndex] is PlayerSelf) { //顯示玩家手牌 ShowPlayerSelfCards(); } StartFollowing(); } }
好的,咱們地主牌顯示已經沒有問題了,接下來,咱們要實現出牌回合邏輯動畫
出牌回合其實跟叫地主回合相似,也是能夠抽象出3種方法:進入出牌階段、出牌、不出(比較進入叫地主階段、叫地主、不叫地主);spa
所以,咱們參照叫地主的邏輯,再實現出牌邏輯:3d
添加開始出牌ToFollowing、出牌ForFollow、不出NotFollow:code
/// <summary> /// 開始出牌 /// </summary> public virtual void ToFollowing() { isMyTerm = true; //關閉倒計時 StopCountDown(CountDownTypes.Follow); //開始倒計時 StartCountDown(CountDownTypes.Follow); } /// <summary> /// 出牌 /// </summary> public void ForFollow() { //關閉倒計時 StopCountDown(CountDownTypes.Follow); //選擇的牌,添加到出牌區域 var selectedCards = cardInfos.Where(s => s.isSelected).ToList(); var offset = 5; for (int i = 0; i < selectedCards.Count(); i++) { var card = Instantiate(prefabSmall, smallCardPos.position + Vector3.right * offset * i, Quaternion.identity, smallCardPos.transform); card.GetComponent<RectTransform>().localScale = Vector3.one * 0.3f; card.GetComponent<Image>().sprite = Resources.Load("Images/Cards/" + selectedCards[i].cardName, typeof(Sprite)) as Sprite; card.transform.SetAsLastSibling(); smallCards.Add(card); } cardInfos = cardInfos.Where(s => !s.isSelected).ToList(); CardManager._instance.ForFollow(); isMyTerm = false; } /// <summary> /// 不出 /// </summary> public void NotFollow() { //關閉倒計時 StopCountDown(CountDownTypes.Follow); CardManager._instance.NotFollow(); isMyTerm = false; } /// <summary> /// 銷燬出牌對象 /// </summary> public void DropAllSmallCards() { smallCards.ForEach(Destroy); smallCards.Clear(); }
實現ToFollowing:orm
調用基類的ToFollowing,並顯示出牌按鈕以供玩家選擇
/// <summary> /// 開始出牌 /// </summary> public override void ToFollowing() { base.ToFollowing(); CardManager._instance.SetFollowButtonActive(true); }
模擬出牌,隨機選擇除手牌中的一張
void Update() { //若是當前是本身回合,模擬對手叫牌 if (isMyTerm) { if (CardManager._instance.cardManagerState == CardManagerStates.Bid) { if (Input.GetKeyDown(KeyCode.Q)) //叫牌 { ForBid(); } if (Input.GetKeyDown(KeyCode.W)) //不叫 { NotBid(); } } if (CardManager._instance.cardManagerState == CardManagerStates.Playing) { if (Input.GetKeyDown(KeyCode.Q)) //出牌 { var rd1 = Random.Range(0, cardInfos.Count); cardInfos[rd1].isSelected = true; ForFollow(); } if (Input.GetKeyDown(KeyCode.W)) //不出 { NotFollow(); } } } }
實現卡牌管理對玩家出牌的控制:
/// <summary> /// 開始出牌階段 /// </summary> private void StartFollowing() { cardManagerState = CardManagerStates.Playing; //地主先出牌 Players[bankerIndex].ToFollowing(); } /// <summary> /// 玩家出牌 /// </summary> public void ForFollow() { SetFollowButtonActive(false); //上輪玩家出牌清空 Players[(termCurrentIndex + Players.Length - 1) % 3].DropAllSmallCards(); if (Players[termCurrentIndex] is PlayerSelf) ShowPlayerSelfCards(); SetNextPlayer(); Players[termCurrentIndex].ToFollowing(); } /// <summary> /// 玩家不出 /// </summary> public void NotFollow() { SetFollowButtonActive(false); //上輪玩家出牌清空 Players[(termCurrentIndex + Players.Length - 1) % 3].DropAllSmallCards(); SetNextPlayer(); Players[termCurrentIndex].ToFollowing(); }
如今咱們的代碼具備必定的規模了,爲了方便更好的管理,把現有的代碼從新整理一下,並進行功能分類,好比:
嗯,今天到此爲止,咱們再來測試驗證下,固然,目前只是實現了出牌的功能,沒有對牌力進行校驗和出牌的控制,對手玩家隨機模擬出牌,還沒有加入AI。咱們之後逐步去實現~來看看這期的效果吧~