五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

Unity中實(shí)現(xiàn)坦克大戰(zhàn)——90版經(jīng)典游戲復(fù)刻

2018-10-18 17:05 作者:皮皮關(guān)做游戲  | 我要投稿

作者:呆呆的碼農(nóng)


工程難度:??


作為紅白機(jī)時(shí)代的經(jīng)典游戲,90坦克絕對(duì)算是年代表作品之一,今天我想用讀取配置表的方式復(fù)刻一下這兒時(shí)的經(jīng)典。

1.場(chǎng)景建設(shè)

首先將準(zhǔn)備好的場(chǎng)景素材導(dǎo)入工程,將其中的磚墻的Tag設(shè)置為Wall,草地Tag設(shè)置為Wall1,水墻設(shè)置為Wall2,鐵墻Wall3,并在每個(gè)物體身上添加Box Collider2D組件,設(shè)置三個(gè)空節(jié)點(diǎn),用來掛載敵人和玩家和子彈。

上圖中白色圖片為敵人生成點(diǎn)。

2.數(shù)據(jù)配置表

作為可拓展、可配置的坦克大戰(zhàn)當(dāng)然離不開配置表的設(shè)置,你可以在配置表里面添加一切你想擁有的角色屬性或道具屬性等等。

玩家表分析設(shè)計(jì):

1.需要一個(gè)唯一ID來區(qū)別表中的數(shù)據(jù),方便索引;

2.需要等級(jí)來綁定顯示和子彈類型;

3.需要圖片名稱,用來加載圖片用;

4.需要子彈類型,用來顯示不同的子彈效果,及能打穿鐵墻和不能;

敵人表分析設(shè)計(jì):

1.需要一個(gè)唯一ID來區(qū)別表中的數(shù)據(jù),方便索引;

2.需要等級(jí)來綁定顯示和子彈類型;

3.需要圖片名稱,用來加載圖片;

4.需要子彈類型,用來顯示不同的子彈效果,及能打穿鐵墻和不能;

道具分析:

1.添加ID來,方便索引;

2.添加圖片名稱,用來顯示道具外形;

(勤勞的我,會(huì)告訴你就做了一個(gè)道具么?)

我的配置表如下:

1.玩家配置表

ID為1的玩家,等級(jí)為1,外觀圖片是Character1,子彈種類為1

2.敵人配置表

ID為1的敵人,等級(jí)為1,外觀圖片是Monster1,子彈種類為1

3.道具配置表

ID為1的道具,外觀圖片是Star

做好表格之后需要將表格放入U(xiǎn)nity中讀取,這中間我用了一個(gè)小工具將.xlsx格式的文件轉(zhuǎn)化為TXT文本,并放在了Assets根目下,然后用Json插件讀取表格信息并寫入字典,當(dāng)游戲中需要對(duì)應(yīng)數(shù)據(jù)時(shí)new一個(gè)新的物體出來附上對(duì)應(yīng)的值,從而獲取動(dòng)態(tài)數(shù)據(jù)。代碼方式如下:

//構(gòu)造靜態(tài)數(shù)據(jù)類,他們的組成與表格對(duì)應(yīng)

public? class StaticMonsterData

{

??? public readonly string id;

??? public readonly string level;

??? public readonly string pictrue;

??? public readonly string buttle;

??? public float Value(string m)

??? {

??????? float? intA;

???? ???float .TryParse(m, out intA);

??????? return intA;

??? }

}

public class StaticPropData

{

??? public readonly string ID;

??? public readonly string Pictrue;

}

public class StaticCharacterData

{

??? public readonly string id;

??? public readonly string level;

??? public readonly string pictrue;

??? public readonly string buttle;

??? public float Value(string m)

??? {

??????? float intA;

??????? float .TryParse(m, out intA);

??????? return intA;

??? }

}

?

public class StaticData : MonoBehaviour {

??? public static StaticData Instance;

??? public Dictionary<string, StaticMonsterData> monsterDictionary;

??? public Dictionary<string, StaticCharacterData> characterDictionary;

??? public Dictionary<string, StaticPropData> propdictionary;

?

??? void Awake()

??? {

??????? Instance = this;

??????? Init();

??????? LoadSence();

??? }

??? // 初始化,將表格數(shù)據(jù)寫如字典

??? void Init()

??? {

??????? monsterDictionary = Load<Dictionary<string, StaticMonsterData>>("Monster");

??????? characterDictionary = Load<Dictionary<string, StaticCharacterData>>("Character");

??????? propdictionary = Load<Dictionary<string, StaticPropData>>("Prop");

??? }

?

??? // 載入場(chǎng)景,并掛載GameMode腳本

??? void LoadSence()

??? {

??????? var temp = Resources.Load<GameObject>("Sence").gameObject;

??????? var sence = Instantiate(temp);

??????? sence.name = temp.name;

??????? sence.AddComponent<GameMode>();

??? }

??? //獲取TXT文本并賦值給對(duì)應(yīng)的類,并返回T的類型值;

??? public static T Load<T>(string name)

??? {

??????? string rName = name;

??????? string readFilePath=? "Assets/" + rName + ".txt";

??????? string str;

??????? T data = default(T);

??????? if (File.Exists(readFilePath))

??????? {

??????????? StreamReader textData = File.OpenText(readFilePath);

??????????? str = textData.ReadLine();

??????????? textData.Close();

??????????? textData.Dispose();

??????????? data = JsonMapper.ToObject<T>(str);

??????? }

??????? return data;

??? }

?

}

?

?

動(dòng)態(tài)數(shù)據(jù)的獲取:

?

//建立角色類

public class RoleData

{

??? public string id;

??? public float? level;

??? public string picture;

??? public float? speed;

??? public float? bullet;

}

//玩家類繼承角色類

public class CharacterData : RoleData

{

??? ///建立構(gòu)造函數(shù),獲取靜態(tài)數(shù)據(jù)

??? public static CharacterData GetCharacterData(StaticCharacterData data)

??? {

??????? CharacterData characterData = new CharacterData();

??????? characterData.id = data.id;

??????? characterData.level = data.Value(data.level);

??????? characterData.picture = data.pictrue;

??????? characterData.bullet = data.Value(data.buttle);

??????? return characterData;

??? }

}

?

public class MonsterData : RoleData

{

??? public static MonsterData GetMonsterData(StaticMonsterData data)

??? {

??????? MonsterData monsterData =new MonsterData();

??????? monsterData.id = data.id;

??????? monsterData.level = data.Value(data.level);

??????? monsterData.picture = data.pictrue;

??????? monsterData.bullet = data.Value(data.buttle);

??????? return monsterData;

??? }

}

?

public class PropData

{

??? public string id;

??? public string pictrue;

??? public static PropData GetPubicPropData(StaticPropData data)

??? {

?????? ?PropData propData = new PropData();

??????? propData.id = data.ID;

??????? propData.pictrue = data.Pictrue;

??????? return propData;

??? }

}

?

3.GameMode

當(dāng)數(shù)據(jù)獲取完畢,場(chǎng)景載入開始時(shí),需要加載玩家角色,敵人角色,道具信息等,并將他們對(duì)應(yīng)的表信息轉(zhuǎn)換成能隨時(shí)調(diào)用的動(dòng)態(tài)信息賦值給他們。

代碼如下:

void Start()

??? {

??????? home = gameObject.transform.Find("CharacterHome").gameObject;

??????? home1 = gameObject.transform.Find("MonsterHome/Home1").gameObject;

??????? home2 =gameObject .transform .Find("MonsterHome/Home2").gameObject;

??????? home3 = gameObject.transform.Find("MonsterHome/Home3").gameObject;

??????? home4 = gameObject.transform.Find("MonsterHome/Home4").gameObject;

??????? animator1 = home1.GetComponent<Animator>();

??????? animator2 = home2.GetComponent<Animator>();

??????? animator3 = home3.GetComponent<Animator>();

??????? animator4 = home4.GetComponent<Animator>();

??????? Init();

??? }

?

???

??? void CreatMonster(string ID, GameObject Object)

??? {

??????? var Data = StaticData.Instance.monsterDictionary[ID];//獲取字典中相應(yīng)key值的靜態(tài)數(shù)據(jù)

??????? var monsterData = MonsterData.GetMonsterData(Data);//將靜態(tài)數(shù)據(jù)轉(zhuǎn)換成動(dòng)態(tài)數(shù)據(jù)

??????? var temp = Resources.Load<GameObject>("Monster");

??????? var monster = Instantiate(temp, Object.transform);

??????? monster.AddComponent<AiMonster>().data = monsterData;//將動(dòng)態(tài)數(shù)據(jù)賦值給角色。

??? }

??? //獲取KEY值為1的靜態(tài)數(shù)據(jù),轉(zhuǎn)化賦值給生成的玩家。

??? void CreatCharacter()

??? {

??????? var Data = StaticData.Instance.characterDictionary["1"];

??????? var characterData = CharacterData.GetCharacterData(Data);

??????? var temp = Resources.Load<GameObject>("Character");

??????? var character = Instantiate(temp, home.transform);

??????? character.AddComponent<Character>().data = characterData;

??? }

??? //隨機(jī)地點(diǎn)生成道具。并賦值

??? void CreatProp()

??? {

??????? var data = StaticData.Instance.propdictionary["1"];

??????? var propData = PropData.GetPubicPropData(data);

??????? var temp = Resources.Load<GameObject>("Prop");

??????? var prop = Instantiate(temp,gameObject.transform);

??????? prop.transform.position += new Vector3(Random.Range(-480, 200),Random.Range(350,-350));

??????? prop.AddComponent<Prop>().data = propData;

??? }

??? void Init()

??? {

??????? animator1.Play("Start", 0);

??????? animator2.Play("Start", 0);

??????? animator3.Play("Start", 0);

??????? animator4.Play("Start", 0);

???????? //2s后創(chuàng)建敵人

??????? StartCoroutine(OnDelay(2.0f, () =>

???????? {

???????????? CreatMonster("1", home1);

???????? ????CreatMonster("2", home2);

???????????? CreatMonster("3", home3);

???????????? CreatMonster("4", home4);

???????? }));

??????? CreatCharacter();

??? }

??? int times = 0;

??? void Update ()

??? {

??????? if (isGameover == false)

??????? {

??????????? times++;

??????????? CreatProp();

??????????? if (times == 3)

??????????? {

??????????????? isGameover = true;

??????????? }

??????? }

??? }

??? IEnumerator OnDelay(float time, UnityEngine.Events.UnityAction rFunc)

??? {

??????? yield return new WaitForSeconds(time);

??????? rFunc();

??????? yield return null;

??? }

}

?

效果顯示:

4.玩家

簡(jiǎn)單的搭建好玩家模型,設(shè)計(jì)玩家行為:

  1. 玩家可以上、下、左、右四個(gè)方向移動(dòng);

  2. 每次移動(dòng)距離為場(chǎng)景中一個(gè)墻體的1/2寬度距離;

  3. 玩家無法穿越障礙;

  4. 玩家可以發(fā)射子彈;

  5. 玩家可以獲得道具;

  6. 玩家獲取道具升級(jí)之后可以改變外形和字典效果;

  7. 玩家可以死亡;

代碼如下:

void Start()

??? {

??????? //獲取玩家模型組件

??????? muzzle = gameObject.transform.Find("MuzzlePiont").gameObject;

??????? rayPiont1 = gameObject.transform.Find("RayPiont1").gameObject;

?? ?????rayPiont2 = gameObject.transform.Find("RayPiont2").gameObject;

??????? bulletPiont = GameObject.Find("BulletPiont");

??????? animator = gameObject.GetComponent<Animator>();

??????? bron = gameObject.transform.Find("Image").GetComponent<Image>();

???? ???//調(diào)用函數(shù)

??????? Init(data);

??????? OnPlayAnimation();

??? }

??? // 播放出生光圈,并在3S后隱藏該組件

??? private void OnPlayAnimation()

??? {

??????? animator.Play("Bron", 0);

??????? StartCoroutine(OnDelay(3, () =>

??????? {

??????????? bron.gameObject.SetActive(false);

??????? }));

??? }

?

??? //初始化玩家,畫出當(dāng)前數(shù)據(jù)下玩家的外形

??? void Init(CharacterData data)

??? {

??????? draw = gameObject.transform.Find("Draw").GetComponent<Image>();

??????? var image_Show = Resources.Load<Sprite>("Image/" + data.picture);

??????? draw.sprite = image_Show;

??? }

?

??? void Update()

??? {

??????? //判斷當(dāng)前是正在移動(dòng)

??????? if (OnMove == false)

??????? {

??????????? if (Input.GetKey(KeyCode.D))

??????????? {

??????????????? OnMove = true;

??????????????? MoveVector = new Vector3(1, 0, 0);

??????????????? endPosition = transform.position + MoveVector * 25;// 設(shè)定每次移動(dòng)25為1/2墻寬

??????????? }

??????????? if (Input.GetKey(KeyCode.S))

??????????? {

??????????????? OnMove = true;

??????????????? MoveVector = new Vector3(0, -1, 0);

??????????????? endPosition = transform.position + MoveVector * 25;

??????????? }

??????????? if (Input.GetKey(KeyCode.A))

??????????? {

??????????????? OnMove = true;

??????????????? MoveVector = new Vector3(-1, 0, 0);

??????????????? endPosition = transform.position + MoveVector * 25;

??????????? }

??????????? if (Input.GetKey(KeyCode.W))

??????????? {

??????????????? OnMove = true;

??????????????? MoveVector = new Vector3(0, 1, 0);

??????????????? endPosition = transform.position + MoveVector * 25;

??????????? }

??????????

??????? }

??????? if (OnMove)

??????? {

??????????? Move();

??????? }

??????? Fire();

??? }

?

??? void Move()

??? {

??????? //當(dāng)初始位置和結(jié)束位置相等時(shí),可以接受重新輸入移動(dòng)方向。

??????? if ((endPosition - transform.position).magnitude ==0)

??????? {

??????????? OnMove = false;

??????????? return;

??????? }

??????? //轉(zhuǎn)向

??????? Trun(MoveVector);

??????? //向移動(dòng)方向打出兩條射線

??????? RaycastHit2D hit1 = Physics2D.Raycast(rayPiont1.transform.position, MoveVector, 0.1f);

??????? RaycastHit2D hit2 = Physics2D.Raycast(rayPiont2.transform.position, MoveVector, 0.1f);

??????? // 射線 碰撞判定

??????? if (hit1.collider != null || hit2.collider != null)

??????? {

??????????? if (hit1.collider == null)

??????????? {

??????????????? if (hit2.collider.tag == "Prop")

??????????????? {

??????????????????? if (data.id == "1")

??????????????????? {

??????????????????????? var Data = StaticData.Instance.characterDictionary["2"];

??????????????????????? var characterData = CharacterData.GetCharacterData(Data);

??????????????????????? data = characterData;

???????? ???????????????Init(data);

??????????????????? }

??????????????????? else if (data.id == "2")

??????????????????? {

??????????????????????? var Data = StaticData.Instance.characterDictionary["3"];

??????????????????????? var characterData = CharacterData.GetCharacterData(Data);

??????????????????????? data = characterData;

??????????????????????? Init(data);

??????????????????? }

??????????????????? else if (data.id == "3")

??????????????????? {

??????????????????????? var Data = StaticData.Instance.characterDictionary["4"];

??????????????????????? var characterData = CharacterData.GetCharacterData(Data);

??????????????????????? data = characterData;

??????????????????????? Init(data);

??????????????????? }

??????????????????? else

?????????????????? ?{

??????????????????????? return;

??????????????????? }

?

??????????????? }

??????????????? if (hit2.collider.tag == "Wall1")

??????????????? {

??????????????????? transform.position += MoveVector;

??????????????? }

??????????????? else

??????????????? {

??????????????????? OnMove = false;

??????????????? }

??????????? }

??????????? else if (hit2.collider == null)

??????????? {

??????????????? if (hit1.collider.tag == "Prop")

??????????????? {

??????????????????? Destroy(hit1.collider.gameObject);

???????? ???????????if (data.id == "1")

??????????????????? {

??????????????????????? var Data = StaticData.Instance.characterDictionary["2"];

??????????????????????? var characterData = CharacterData.GetCharacterData(Data);

??????????????????????? data = characterData;

??????????????????????? Init(data);

??????????????????? }

??????????????????? else if (data.id == "2")

??????????????????? {

??????????????????????? var Data = StaticData.Instance.characterDictionary["3"];

??????????????????????? var characterData = CharacterData.GetCharacterData(Data);

??????????????????????? data = characterData;

??????????????????????? Init(data);

??????????????????? }

??????????????????? else if (data.id == "3")

??????????????????? {

??????????????????????? var Data = StaticData.Instance.characterDictionary["4"];

??????????????????????? var characterData = CharacterData.GetCharacterData(Data);

??????????????????????? data = characterData;

??????????????????????? Init(data);

??????????????????? }

?

??????????????? }

??????????????? if (hit1.collider.tag == "Wall1")

??????????????? {

??????????????????? transform.position += MoveVector;

??????????????? }

?

??????????????? else

??????????????? {

??????????????????? OnMove = false;

??????????????? }

??????????? }

???????? ???else

??????????? {

??????????????? if (hit1.collider.tag == "Prop")

??????????????? {

??????????????????? if (data.id == "1")

??????????????????? {

??????????????????????? var Data = StaticData.Instance.characterDictionary["2"];

??????????????????????? var characterData = CharacterData.GetCharacterData(Data);

??????????????????????? data = characterData;

??????????????????????? Init(data);

??????????????????? }

??????????????????? else if (data.id == "2")

??????????????????? {

??????????????????????? var Data = StaticData.Instance.characterDictionary["3"];

??????????????????????? var characterData = CharacterData.GetCharacterData(Data);

??????????????????????? data = characterData;

??????????????????????? Init(data);

??????????????????? }

??????????????? ????else if (data.id == "3")

??????????????????? {

??????????????????????? var Data = StaticData.Instance.characterDictionary["4"];

??????????????????????? var characterData = CharacterData.GetCharacterData(Data);

??????????????????????? data = characterData;

??????????????????????? Init(data);

??????????????????? }

?

??????????????? }

??????????????? else if (hit2.collider.tag == "Prop")

??????????????? {

??????????????????? if (data.id == "1")

??????????????????? {

??????????????????????? var Data = StaticData.Instance.characterDictionary["2"];

??????????????????????? var characterData = CharacterData.GetCharacterData(Data);

??????????????????????? data = characterData;

??????????????????????? Init(data);

??????????????????? }

???????????????? ???else if (data.id == "2")

??????????????????? {

??????????????????????? var Data = StaticData.Instance.characterDictionary["3"];

??????????????????????? var characterData = CharacterData.GetCharacterData(Data);

??????????????????????? data = characterData;

??????????????????????? Init(data);

??????????????????? }

??????????????????? else if (data.id == "3")

??????????????????? {

??????????????????????? var Data = StaticData.Instance.characterDictionary["4"];

??????????????????????? var characterData = CharacterData.GetCharacterData(Data);

??????????????????????? data = characterData;

??????????????????????? Init(data);

??????????????????? }

??????????????????? else

??????????????????? {

??????????????????????? return;

??????????????????? }

?

?? ?????????????}

??????????????? if (hit1.collider.tag == "Wall1" && hit2.collider.tag == "Wall1")

??????????????? {

??????????????????? transform.position += MoveVector;

??????????????? }

??????????????? else

??????????????? {

??????????????????? OnMove = false;

??????????????? }

??????????? }

??????? }

??????? else

??????? {

??????????? transform.position += MoveVector;

??????? }

??? }

?

??? void Trun(Vector3 moveVector)

??? {

??????? var angel = Vector3.Angle(transform.right, moveVector);//計(jì)算當(dāng)前方向和下一個(gè)方向的角度

??????? var normal = Vector3.Cross(transform.right, moveVector);//計(jì)算當(dāng)前向量和下一個(gè)移動(dòng)方向的叉乘得出它們所在平面的垂直向量

??????? angel *= Mathf.Sign(Vector3.Dot(transform.forward, normal));//技算當(dāng)前向量和下個(gè)移動(dòng)方向向量的點(diǎn)積,并返回正負(fù)號(hào)賦值給角度

??????? var vector = transform.right.normalized - moveVector.normalized;//計(jì)算從下一個(gè)方向向量指向當(dāng)前向量的向量

??????? if (vector.magnitude > 0.1f)

??????? {

??????????? transform.Rotate(transform.forward, angel);

??????? }

??? }

?

??? void Fire()

??? {

??????? if (Input.GetKeyDown(KeyCode.Space))

??????? {

??????????? var bulletDemo = Resources.Load<GameObject>("Bullet");

??????????? var bullet = Instantiate(bulletDemo, muzzle.transform);

??????????? bullet.transform.SetParent(bulletPiont.transform);

??????????? bullet.transform.localScale = Vector3.one;

??????????? //如果玩家數(shù)據(jù)的等級(jí)為4則改變自己的子彈效果,并將發(fā)射子彈的母體賦值給子彈

??????????? if (data.level == 4)

??????????? {

??????????????? bullet.AddComponent<Bullet1>().motherObject = gameObject;

??????????? }

??????????? else

??????????? {

??????????????? bullet.AddComponent<Bullet>().motherObject = gameObject;

??????????? }

??????? }

??? }

??? // 死亡時(shí)將顯示晚間外形組件隱藏,播放死亡動(dòng)畫0.3S后摧毀玩家組件

??? public void Die()

??? {

??????? draw.gameObject.SetActive(false);

??????? animator.Play("Die", 0);

??????? StartCoroutine(OnDelay(0.3f, () =>

??????? {

?? ?????????Destroy(gameObject);

??????? }));

??? }

?

??? IEnumerator OnDelay(float time, UnityEngine.Events.UnityAction rFunc)

??? {

??????? yield return new WaitForSeconds(time);

??????? rFunc();

??????? yield return null;

??? }

?

}

?

效果查看:

5.敵人

搭建好敵人模型,設(shè)置敵人Ai:

  1. 敵人可以上、下、左、右四個(gè)方向移動(dòng);

  2. 每次移動(dòng)距離為場(chǎng)景中墻的1/2寬;

  3. 敵人無法穿越障礙;若沒有遇見障礙則隨機(jī)選擇是否繼續(xù)延當(dāng)前方向前進(jìn),若遇見障礙則隨機(jī)重新選擇移動(dòng)方向;

  4. 敵人可以發(fā)射子彈,頻率為1.5s一次;

  5. 敵人可以死亡;

代碼如下:

因?yàn)閿橙撕屯婕一纠淄皇前淹婕业妮斎霌Q成了隨機(jī)數(shù),所以不貼代碼了。

查看效果:

6.道具

搭建好道具模型,設(shè)置其功能

  1. 道具隨機(jī)生成在地圖上;

  2. 玩家獲取道具后,道具消失;

因?yàn)橹挥幸粋€(gè)道具,模塊小沒有單獨(dú)劃分模塊出來隨機(jī)生成的體現(xiàn)在GamaMode腳本中體現(xiàn),玩家獲取道具后消失在玩家功能中體現(xiàn)了。


嗯,90坦克的主要玩法差不多也就時(shí)這些了,而且所用的數(shù)據(jù)完全來至配置表,有興趣的朋友可以自己研拓展,可以增加一些道具啊,或者玩家屬性什么的,當(dāng)然也可以加別的那就看你的腦洞了。

相關(guān)工程和插件已經(jīng)上傳github 鏈接:https://github.com/dingchao12/Deom


想系統(tǒng)學(xué)習(xí)游戲開發(fā)的童鞋,歡迎訪問?http://levelpp.com/? ? ? ? ? ? ? ?

游戲開發(fā)攪基QQ群:869551769? ? ? ? ? ? ? ?

微信公眾號(hào):皮皮關(guān)

Unity中實(shí)現(xiàn)坦克大戰(zhàn)——90版經(jīng)典游戲復(fù)刻的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
峨边| 驻马店市| 宁都县| 社旗县| 西华县| 胶南市| 苍梧县| 循化| 广东省| 延长县| 靖边县| 普兰店市| 赤壁市| 来宾市| 榕江县| 革吉县| 扶风县| 峨山| 宜昌市| 偃师市| 汾西县| 麻江县| 邻水| 宾阳县| 惠水县| 兴业县| 塔河县| 巴彦县| 博爱县| 云梦县| 庆安县| 荃湾区| 巴里| 银川市| SHOW| 文安县| 沭阳县| 西宁市| 高青县| 榕江县| 宣城市|