小实习生一枚,利用一周的时间做了个单机简单的二人小麻将
先上成品图
因为公司都用比较稳定的版本,所以我是从比较老的版本unity 4.7上手学习的
刚开始学什么都不懂,参考了一个别人写的斗地主demo,所以代码比较累赘…你们可以改良一下
二人麻将介绍
牌型分为:条,筒,万(没有东西南北发) 共108张
玩家: 二人
吃,碰,杠,胡均为简单算法,没有分种类和牌型(因为我不会打牌所以写的时候没有考虑暗杠)
功能实现
1:发牌
2:桌面摆牌
3:AI实现吃,碰,杠,胡功能
4:自己的牌实现智能提示吃,碰,杠,胡
步骤
首先导入ngui,导入ngui还是非常简单的,百度上面教程贼多,我就不写了
新建一个GameObject,改名为GameControll
绑上我们新建的C#脚本,这个脚本就是我们整个项目核心的控制点了
我在这里简单设置了一下参数,比如底分和全场倍数 ,接下来就可以开始往里面填东西la
public class GameController : MonoBehaviour{
public int basePointPerMatch;//底分
private int multiples;//全场倍数
// Use this for initialization
void Start()
{
multiples = 1;
basePointPerMatch = 100;
InitStar();//初始化场景
}
}
可以看到我这里写了一个初始化场景的方法InitStar() 使用代码动态生成页面
动态生成页面要准备好预制体,也就是画UI, 可以看到这里我将主要的场景分为两个预制体,一个是专门放player的,一个是专门放置按钮的
这是我的StartPanel预制体做好的样子
这是我的buttonPanel预制体
这里还有一个重要的预制体需要画好,即卡牌的预制体,要绑定一个类,我这里取名为CardSprite,进行卡牌精灵的处理
注意,所有调用的预制体必须放置在Resources文件夹下!我调用预制体的方法为Resources.Load(“XXX”)
做好这些准备,可以开始在GameControll类里面写初始化代码了
/// <summary>
/// 初始化面板
/// </summary>
public void InitStar()
{
GameObject buttonpanel = NGUITools.AddChild(UICamera.mainCamera.gameObject, (GameObject)Resources.Load("ButtonPanel"));
buttonpanel.AddComponent<buttonControl>();
buttonpanel.name = buttonpanel.name.Replace("(Clone)", "");//可以替换掉后缀(Clone)
GameObject mainpanel = NGUITools.AddChild(UICamera.mainCamera.gameObject, (GameObject)Resources.Load("StartPanel"));//加载StartPanel第一个场景
mainpanel.name = mainpanel.name.Replace("(Clone)", "");//可以替换掉后缀(Clone)
GameObject AI= mainpanel.transform.Find("AI").gameObject;
HandCards AI1Cards = AI.AddComponent<HandCards>();//处理手牌的类
AI1Cards.cType = CharacterType.AI;//设定角色的类型
AI.AddComponent<SimpleSmartCard>();//ai自动出牌的类
AI.transform.Find("playpoint").gameObject.SetActive(false);//隐藏AI放手牌的点
AI.transform.Find("showType").gameObject.SetActive(false);//这里可以处理图片
GameObject Player = mainpanel.transform.Find("Player").gameObject;
HandCards playerCards = Player.AddComponent<HandCards>();
Player.AddComponent<PlayCard>();//玩家出牌调用的类
playerCards.cType = CharacterType.Player;
Player.transform.Find("playpoint").gameObject.SetActive(false);
print("初始化" + "toStar()");
}
写完上面的代码,运行你会发现你写好的预制体被动态加载出来了
可以看到这里我给预制体绑定了很多处理的辅助类,我将这几个类直接贴出来吧,相信很容易看得懂
// 用于规定枚举类型
using UnityEngine;
using System.Collections;
/// <summary>
/// 角色类型
/// </summary>
public enum CharacterType
{
Library = 0,
Player,
AI,
Desk
}
/// <summary>
/// 牌类
/// </summary>
public enum Suits
{
Tiao,
Tong,
Wan,
}
/// <summary>
/// 卡牌权值
/// </summary>
public enum Weight
{
_1 = 0,
_2,
_3,
_4,
_5,
_6,
_7,
_8,
_9,
}
/// <summary>
/// 身份
/// </summary>
public enum Identity
{
loser,
fightui_host,
none
}
/// <summary>
/// 出牌类型
/// </summary>
public enum CardsType //enum 枚举关键字
{
//未知类型
None=0,
fightui_chi ,
fightui_peng,
fightui_gang,
fightui_angang,
fightui_hu,
}
/// <summary>
/// 牌的元素
/// </summary>
public enum Cardselement //enum 枚举关键字
{
//未知类型
None = 0,
Double,//一堆将
ThereCount,//三顺
ThereSame,//三连
Gang
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
//封装卡牌
public class Card
{
private readonly string cardName;//牌名
private readonly Weight weight;//权重
private readonly Suits suits; //种类
private CharacterType belongTo;//牌的归属
private bool makedSprite;
public string CardName
{
get
{
return cardName;
}
}
public Weight Weight
{
get
{
return weight;
}
}
public Suits Suits
{
get
{
return suits;
}
}
public CharacterType BelongTo
{
get
{
return belongTo;
}
set
{
belongTo = value;
}
}
public bool MakedSprite
{
get
{
return makedSprite;
}
set
{
makedSprite = value;
}
}
public Card(string name, Weight weight, Suits suits, CharacterType belongTo)
{
MakedSprite = false;
cardName = name;
this.weight = weight;
this.suits = suits;
this.BelongTo = belongTo;
}
}
using System.Collections.Generic;
using UnityEngine;
//生成手牌的类
public class HandCards : MonoBehaviour
{
public CharacterType cType;
private List<Card> library;
private Identity identity;
private Card newCard=null;
private int multiples;//玩家倍数
private int integration=1000;//积分
private bool Once = true;
void Start()
{
multiples = 1;
identity = Identity.loser;
library = new List<Card>();
}
/// <summary>
/// 积分
/// </summary>
public int Integration
{
set { integration = value; }
get { return integration; }
}
/// <summary>
/// 玩家倍数
/// </summary>
public int Multiples
{
set { multiples *= value; }
get { return multiples; }
}
/// <summary>
/// 手牌数
/// </summary>
public int CardsCount
{
get { return library.Count; }
}
/// <summary>
/// 访问身份
/// </summary>
public Identity AccessIdentity
{
set
{
identity = value;
}
get { return identity; }
}
public Card NewCard
{
get
{
return newCard;
}
}
public bool theOnce
{
get
{
return Once;
}
set
{
Once = value;
}
}
/// <summary>
/// 获取手牌
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public Card this[int index]
{
get { return library[index]; }
}
/// <summary>
/// 获取值的索引 索引器.
/// </summary>
/// <param name="card"></param>
/// <returns></returns>
public int this[Card card]
{
get { return library.IndexOf(card); }
}
/// <summary>
/// 添加手牌
/// </summary>
/// <param name="card"></param>
public void AddCard(Card card)
{
card.BelongTo = cType;
library.Add(card);
newCard = card;
}
/// <summary>
/// 出牌
/// </summary>
/// <returns></returns>
public void PopCard(Card card)
{
//从手牌移除
if (card!=null) {
library.Remove(card);
}
}
/// <summary>
/// 手牌排序
/// </summary>
public void Sort()
{
CardRules.SortCards(library, false);//CardRules类用于处理手牌,排序,判断胡,碰,杠等
}
}
一定要绑到牌的预制体上哟!
//给卡牌预制体绑定的处理精灵的方法
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class CardSprite : MonoBehaviour
{
private Card card;
public UISprite sprite;
private bool isSelected=false;
private bool canSeeCard;
public Card Poker
{
set
{
card = value;
card.MakedSprite = true;
SetSprite(canSeeCard);//显示ui
}
get { return card; }
}
/// <summary>
/// 是否被点击中
/// </summary>
public bool Select
{
set { isSelected = value; }
get { return isSelected; }
}
public bool CanSeeCard
{
get
{
return canSeeCard;
}
set
{
canSeeCard = value;
}
}
private void Start()
{
isSelected = false;
}
/// <summary>
/// 设置UISprite的显示
/// </summary>
void SetSprite(bool canSeeCard )
{
if (canSeeCard)
{
//明牌
sprite.transform.FindChild("mypointS").GetComponent<UISprite>().spriteName = card.CardName;
}
else {
if (card.BelongTo == CharacterType.Player || card.BelongTo == CharacterType.Desk)
{
sprite.transform.FindChild("mypointS").GetComponent<UISprite>().spriteName = card.CardName;
}
else
{
sprite.spriteName = "Top_Back";
}
}
}
/// <summary>
/// 销毁精灵
/// </summary>
public void Destroy()
{
if (card!=null) {
if (card.MakedSprite) {
//精灵化false
card.MakedSprite = false;
//销毁对象
Destroy(this.gameObject);
}
}
}
/// <summary>
/// 调整位置
/// </summary>
public void GoToPosition(CharacterType who, int index,int cardmargin)
{
if (sprite != null)
{
GameObject parent = GameObject.Find(who.ToString());
if (card.BelongTo == CharacterType.Player)//如果牌是player的,那么把牌放在player的点
{
GameObject mycon = parent.transform.FindChild("cardpengpoint").gameObject;
CardSprite[] myconsp = mycon.GetComponentsInChildren<CardSprite>();
transform.localPosition = new Vector3(0, 0, 0);
CardSprite[] mypoint = parent.GetComponentsInChildren<CardSprite>();
int margin = 0;
switch (myconsp.Length)
{
case 4:
margin = 180;
break;
case 8:
margin = 200 * 2;
break;
case 12:
margin = 200 * 3;
break;
case 16:
margin =210 * 4;
break;
default:
break;
};
sprite.width = 78;
sprite.height = 115;
if (Select)
{
sprite.spriteName = "Bottom_Stand_Front_Light";
}
else {
sprite.spriteName = "Bottom_Stand_Front";
}
sprite.transform.FindChild("mypointS").GetComponent<UISprite>().spriteName = card.CardName;
sprite.transform.FindChild("mypointS").GetComponent<UISprite>().depth =2;
sprite.transform.localScale = new Vector3((float)1.2, (float)1.2, 1);
transform.localPosition = new Vector3(-550+cardmargin*index+margin, -80, 0);
}
else if (card.BelongTo == CharacterType.AI)
{
if (c