Unity3D手机斗地主游戏开发实战

Unity3D手机斗地主游戏开发实战

  • 商品编号:
    #14651402_146
    • 原价:
      免费
    • 会员价:
      免费
  • 分类:
    • V1.0.0
  • 数量:
    限购1件

购物车中已存在此商品(限购一件),单击跳转购物车

  • 开发者:生活是咖啡
  • 开发语言:C#
  • 商品架构:C/S
  • 代码管理工具:github
  • 大小(M):0 M
  • 编码格式:utf-8
  • 是否开源:是
  • 开源协议:BSD

上期我们实现了叫地主功能,不过遗留了一个小功能:叫地主完成以后,要显示地主的3张牌,这期首先弥补这块的功能;

接着我们要进入开发出牌逻辑的开发阶段,好了,废话不多说,继续我们斗地主开发之旅~

地主牌的显示

我们在玩家界面的顶部中间位置,放置一个新的GameObject,命名为BidCards,用来记录3张地主牌的显示位置。

所以我们重构了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种方法:进入出牌阶段、出牌、不出(比较进入叫地主阶段、叫地主、不叫地主);

因此,我们参照叫地主的逻辑,再实现出牌逻辑:

调整Player基类,添加开始出牌ToFollowing、出牌ForFollow、不出NotFollow

ToFollowing:进入自己回合,关闭其他人的倒计时,进入自己的倒计时阶段;

ForFollow:关闭自己的倒计时,然后将选择的牌添加到出牌区域,跳出自己回合;

NotFollow:关闭自己的倒计时,跳出自己回合;

/// <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();
}

调整PlayerSelf类,实现ToFollowing

调用基类的ToFollowing,并显示出牌按钮以供玩家选择

/// <summary>
/// 开始出牌
/// </summary>
public override void ToFollowing()
{
    base.ToFollowing();
    CardManager._instance.SetFollowButtonActive(true);
}

调整PlayerOther类,模拟出牌

随机选择除手牌中的一张

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();
            }
        }
    }
}

调整CardManager,实现卡牌管理对玩家出牌的控制

发完地主牌以后,开始出牌阶段,由地主先出牌;

玩家选择出牌后,将上轮玩家的出牌堆清空,并将选择的牌添加到自己的出牌堆,轮转到下个玩家;

玩家选择不出牌,将上轮玩家的出牌堆清空,轮转到下个玩家;

/// <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();
}

代码整理

现在我们的代码具有一定的规模了,为了方便更好的管理,把现有的代码重新整理一下,并进行功能分类,比如:

208266-20171029173330133-647981926371995-20171106180036888-107418205

总结

嗯,今天到此为止,我们再来测试验证下,当然,目前只是实现了出牌的功能,没有对牌力进行校验和出牌的控制,对手玩家随机模拟出牌,尚未加入AI。我们以后逐步去实现~来看看这期的效果吧~



权利声明:本站所有商品信息、客户评价等信息是初心商城重要的数据资源,未经许可,禁止非法转载使用。 注:本站商品信息均来自初心商城,其真实性、准确性和合法性由初心商城负责。

                  初心源说明:初心商城主要为程序员提供开发基础的代码源以及成熟项目,网站中所有的商品有提供收费版本的, 也有提供免费版本的,按照大家各自不同的需求进行购买。实实在在的让程序员只用专注于自己的业务实现你的小梦想, 如果您对我们的成果表示认同并且觉得对你有所帮助我们愿意接受来自各方面的支持^_^。

                  支持:用手机扫描二维码支付

                  支付宝支持我们 微信支持我们

                  您的支持将被用于:
                  1、持续深入的上传更多更好的源代码
                  2、建立更加完善的技术社区
                  3、完善现在系统出现各种问题
                  4、购买域名和租赁服务器

                  1、交易规则

                  2、发货方式

                  1、自动:在上方保障服务中标有自动发货的商品,拍下后,将会自动收到来自卖家的商品获取(下载)链接

                  2、手动:在上方保障服务中标有手动发货的商品,拍下后,卖家会收到邮件,也可通过QQ或订单中的电话联系对方。

                  3、退款说明

                  1、描述:源码描述(含标题)与实际源码不一致的(例:描述PHP实际为ASP、描述的功能实际缺少、版本不符等)

                  2、演示:有演示站时,与实际源码小于95%一致的(但描述中有"不保证完全一样、有变化的可能性"类似显著声明的除外)

                  3、发货:手动发货源码,在卖家未发货前,已申请退款的

                  4、服务:卖家不提供安装服务或需额外收费的(但描述中有显著声明的除外)

                  5、其它:如质量方面的硬性常规问题等

                  备注:经核实符合上述任一,均支持退款,但卖家予以积极解决问题则除外。交易中的商品,卖家无法对描述进行修改!

                  4、注意事项

                  1、客户买完之后未确认收货,将不会收到下载地址和下载码,确认收货之后才能收到下载地址和下载码。

                  2、在未拍下前,双方在QQ上所商定的内容,亦可成为纠纷评判依据(商定与描述冲突时,商定为准);

                  3、在商品同时有网站演示与图片演示,且站演与图演不一致时,默认按图演作为纠纷评判依据(特别声明或有商定除外);

                  4、在没有"无任何正当退款依据"的前提下,写有"一旦售出,概不支持退款"等类似的声明,视为无效声明;

                  5、虽然交易产生纠纷的几率很小,但请尽量保留如聊天记录这样的重要信息,以防产生纠纷时出现问题不明确的情况。

                  5、交易声明

                  1、本站作为直卖平台,依据交易合同(商品描述、交易前商定的内容)来保障交易的安全及买卖双方的权益;

                  2、非平台线上交易的商品,出现任何后果均与本站无关;无论卖家以何理由要求线下交易的,请联系管理举报。

                  初心Logo

                  初心商城| 初心系列| 初心博客| 初心历史| 系统反馈

                  chuxinm.com 京ICP备16055626号 © 2016-2018 山西米立信息技术有限公司 保留所有权利
                  违法和不良信息举报电话:186-2950-9347,本网站所列数据,除特殊说明,所有数据均出自我工作室
                  本网站兼容所有主流浏览器,不支持手机自适应