日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Unity3D_(游戏)2D坦克大战 像素版

發布時間:2023/12/1 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Unity3D_(游戏)2D坦克大战 像素版 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

  2D坦克大戰? ? 像素版

 

游戲規則: 

  玩家通過上、下、左、右移動坦克,空格鍵發射子彈

  敵人AI出身時朝向己方大本營(未防止游戲快速結束,心臟上方三個單位障礙物設為剛體)   

  當玩家被擊殺次數>=3  或  心臟被子彈擊穿  重新加載游戲場景

  控制游戲每4秒發射一顆子彈(可自己做修改)  

?

  游戲項目已托管到Github上  傳送門?

?

  (文章最下邊有游戲腳本)

?

場景搭建

?

  設置Main Camera攝像頭參數

?

?

游戲中制作預制體與動畫

?

  創建一個Cube作為參照,Cube長寬高都為1m

  創建一個Player1_0作為玩家

? ? ?將Player1_0制作成預制體

?

  制作游戲磚塊、鋼鐵、草叢、基地預制體

?

  創建游戲物體出生動畫Animation

  快速創建動畫:點擊第一張圖片->按住Shift->點擊最后一張圖片

  保存好后場景出現Born_0動畫,修改scale大小為3 3 3

?

?

  制作坦克出生無敵、坦克爆炸、河流特效

  動畫大小與預制體適配

?

?

控制玩家的移動

?

  添加Player.cs腳本,綁定到Player玩家坦克上

?

  默認移動速度

public float moveSpeed = 3;

?

  監聽玩家水平軸輸入

float h = Input.GetAxisRaw("Horizontal"); //返回-1 0 1 transform.Translate(Vector3.right*h*moveSpeed*Time.deltaTime,Space.World);

?

  監聽玩家垂直軸輸入

  float v = Input.GetAxisRaw("Vertical");transform.Translate(Vector3.up * v * moveSpeed * Time.deltaTime, Space.World);

?

?

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Player : MonoBehaviour {public float moveSpeed = 3;// Use this for initializationvoid Start () {}// Update is called once per framevoid Update () {//監聽玩家水平軸輸入float h = Input.GetAxisRaw("Horizontal"); //返回-1 0 1transform.Translate(Vector3.right*h*moveSpeed*Time.deltaTime,Space.World);//監聽玩家垂直軸輸入float v = Input.GetAxisRaw("Vertical");transform.Translate(Vector3.up * v * moveSpeed * Time.deltaTime, Space.World);} } Player.cs

?

?

控制圖片的移動和切換

?

  制作坦克渲染

  添加精靈數組的引用

private SpriteRenderer sr;public Sprite[] tankSprite;

?

(上 右 下 左)

?

  玩家按上下左右控制坦克方向的移動

//監聽玩家水平軸輸入float h = Input.GetAxisRaw("Horizontal"); //返回-1 0 1transform.Translate(Vector3.right*h*moveSpeed*Time.deltaTime,Space.World);if (h < 0){sr.sprite = tankSprite[3];}else if (h>0){sr.sprite = tankSprite[1];}//監聽玩家垂直軸輸入float v = Input.GetAxisRaw("Vertical");transform.Translate(Vector3.up * v * moveSpeed * Time.deltaTime, Space.World);if (v < 0){sr.sprite = tankSprite[2];}else if (v > 0){sr.sprite = tankSprite[0];}

?

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Player : MonoBehaviour {public float moveSpeed = 3;private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左// Use this for initializationvoid Start () {sr = GetComponent<SpriteRenderer>();}// Update is called once per framevoid Update () {//監聽玩家水平軸輸入float h = Input.GetAxisRaw("Horizontal"); //返回-1 0 1transform.Translate(Vector3.right*h*moveSpeed*Time.deltaTime,Space.World);if (h < 0){sr.sprite = tankSprite[3];}else if (h>0){sr.sprite = tankSprite[1];}//監聽玩家垂直軸輸入float v = Input.GetAxisRaw("Vertical");transform.Translate(Vector3.up * v * moveSpeed * Time.deltaTime, Space.World);if (v < 0){sr.sprite = tankSprite[2];}else if (v > 0){sr.sprite = tankSprite[0];}} } Player.cs

?

?

碰撞器的添加

?

  碰撞檢測

    兩個物體都有碰撞器

    一個物體上掛載剛體組件

?

  給玩家Player添加2D剛體和2D碰撞器

  剛體的Gravity Scale設置為0,取消重力因素的影響

?

?  給Barriar、Wall、River、Heart添加Box Collider 2D碰撞器

?

?

  發現坦克方向坐標軸會改變,在Rigidbody 2D中Constraints下的Freeze Rotation Z 進行綁定,當它碰撞到物體時坐標不發生偏移

?

  

?

  解決抖動問題

?

  使用private void FixedUpdate()

FixedUpdate () 和 Update () 同:當MonoBehaviour啟用時,其在每一幀被調用。都是用來更新的異:Update()每一幀的時間不固定,即第一幀與第二幀的時間t1和第三幀與第四幀的時間t2不一定相同。FixedUpdate()每幀與每幀之間相差的時間是固定的.Update受當前渲染的物體影響,這與當前場景中正在被渲染的物體有關(比如人物的面數,個數等),有時快有時慢,幀率會變化,Update被調用的時間間隔就會發生變化。但是FixedUpdate則不受幀率的變化影響,它是以固定的時間間隔來被調用。所以一些物理屬性的更新操作應該放在FxiedUpdate中操作,比如Force,Collider,Rigidbody等。外設的操作也是,比如說鍵盤或者鼠標的輸入輸出Input,因為這樣GameObject的物理表現的更平滑,更接近現實。FixedUpdate的時間間隔可以在項目設置中更改,Edit->Project Setting->time 找到Fixed timestep。就可以修改了 FixedUpdate () 和 Update ()

?

//監聽玩家水平軸輸入float h = Input.GetAxisRaw("Horizontal"); //返回-1 0 1transform.Translate(Vector3.right*h*moveSpeed*Time.fixedDeltaTime,Space.World);//監聽玩家垂直軸輸入float v = Input.GetAxisRaw("Vertical");transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);

?

  FixedUpdate()方法留空就行

private void FixedUpdate(){}

?

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Player : MonoBehaviour {public float moveSpeed = 3;private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左// Use this for initializationvoid Start () {sr = GetComponent<SpriteRenderer>();}// Update is called once per framevoid Update () {//監聽玩家水平軸輸入float h = Input.GetAxisRaw("Horizontal"); //返回-1 0 1transform.Translate(Vector3.right*h*moveSpeed*Time.fixedDeltaTime,Space.World);if (h < 0){sr.sprite = tankSprite[3];}else if (h>0){sr.sprite = tankSprite[1];}//監聽玩家垂直軸輸入float v = Input.GetAxisRaw("Vertical");transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v < 0){sr.sprite = tankSprite[2];}else if (v > 0){sr.sprite = tankSprite[0];}}// private void FixedUpdate(){} } Player.cs

?

  解決玩家按方向鍵左右的同時按上下

  在監聽玩家垂直軸輸入后對v方向按鍵進行判斷,如果為0則在Update()中直接返回

float v = Input.GetAxisRaw("Vertical");transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v < 0){sr.sprite = tankSprite[2];}else if (v > 0){sr.sprite = tankSprite[0];}if(v!=0){return;}//監聽玩家水平軸輸入float h = Input.GetAxisRaw("Horizontal"); //返回-1 0 1transform.Translate(Vector3.right*h*moveSpeed*Time.fixedDeltaTime,Space.World);if (h < 0){sr.sprite = tankSprite[3];}else if (h>0){sr.sprite = tankSprite[1];}

?

  整理一下Player.cs腳本

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Player : MonoBehaviour {//屬性值public float moveSpeed = 3;//引用private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左// Use this for initializationvoid Start () {sr = GetComponent<SpriteRenderer>();}// Update is called once per framevoid Update () {}private void FixedUpdate(){Move();}//坦克的移動方法private void Move(){//監聽玩家垂直軸輸入float v = Input.GetAxisRaw("Vertical");transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v < 0){sr.sprite = tankSprite[2];}else if (v > 0){sr.sprite = tankSprite[0];}if (v != 0){return;}//監聽玩家水平軸輸入float h = Input.GetAxisRaw("Horizontal"); //返回-1 0 1transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World);if (h < 0){sr.sprite = tankSprite[3];}else if (h > 0){sr.sprite = tankSprite[1];}} } Player.cs

?

?

2D渲染層級

?

  設置游戲物體的層級

      

?

      

?

?

?

坦克的攻擊

?

  坦克的攻擊方法

private void Attack(){if(Input.GetKeyDown(KeyCode.Space)){Instantiate(bullectPrefab,transform.position,transform.rotation);}}

?

private void FixedUpdate(){Move();Attack();}

?

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Player : MonoBehaviour {//屬性值public float moveSpeed = 3;//引用private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左public GameObject bullectPrefab;// Use this for initializationvoid Start () {sr = GetComponent<SpriteRenderer>();}// Update is called once per framevoid Update () {}private void FixedUpdate(){Move();Attack();}//坦克的攻擊方法private void Attack(){if(Input.GetKeyDown(KeyCode.Space)){Instantiate(bullectPrefab,transform.position,transform.rotation);}}//坦克的移動方法private void Move(){//監聽玩家垂直軸輸入float v = Input.GetAxisRaw("Vertical");transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v < 0){sr.sprite = tankSprite[2];}else if (v > 0){sr.sprite = tankSprite[0];}if (v != 0){return;}//監聽玩家水平軸輸入float h = Input.GetAxisRaw("Horizontal"); //返回-1 0 1transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World);if (h < 0){sr.sprite = tankSprite[3];}else if (h > 0){sr.sprite = tankSprite[1];}} } player.cs

?

  子彈的朝向和移動

  通過按鍵V和H來判斷子彈旋轉的角度

?

  定義子彈旋轉的角度

private Vector3 bullectEulerAugles;

?

  子彈參數的角度:當前坦克的角度+子彈應該旋轉的角度

Instantiate(bullectPrefab,transform.position,Quaternion.Euler(transform.eulerAngles+bullectEulerAugles));

?

---恢復內容結束---

?

?

未完~

?

完成時會有完整項目展示

?

?

場景搭建

?

  設置Main Camera攝像頭參數

?

?

游戲中制作預制體與動畫

?

  創建一個Cube作為參照,Cube長寬高都為1m

  創建一個Player1_0作為玩家

? ? ?將Player1_0制作成預制體

?

  制作游戲磚塊、鋼鐵、草叢、基地預制體

?

  創建游戲物體出生動畫Animation

  快速創建動畫:點擊第一張圖片->按住Shift->點擊最后一張圖片

  保存好后場景出現Born_0動畫,修改scale大小為3 3 3

?

?

  制作坦克出生無敵、坦克爆炸、河流特效

  動畫大小與預制體適配

?

?

控制玩家的移動

?

  添加Player.cs腳本,綁定到Player玩家坦克上

?

  默認移動速度

public float moveSpeed = 3;

?

  監聽玩家水平軸輸入

float h = Input.GetAxisRaw("Horizontal"); //返回-1 0 1 transform.Translate(Vector3.right*h*moveSpeed*Time.deltaTime,Space.World);

?

  監聽玩家垂直軸輸入

  float v = Input.GetAxisRaw("Vertical");transform.Translate(Vector3.up * v * moveSpeed * Time.deltaTime, Space.World);

?

?

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Player : MonoBehaviour {public float moveSpeed = 3;// Use this for initializationvoid Start () {}// Update is called once per framevoid Update () {//監聽玩家水平軸輸入float h = Input.GetAxisRaw("Horizontal"); //返回-1 0 1transform.Translate(Vector3.right*h*moveSpeed*Time.deltaTime,Space.World);//監聽玩家垂直軸輸入float v = Input.GetAxisRaw("Vertical");transform.Translate(Vector3.up * v * moveSpeed * Time.deltaTime, Space.World);} } Player.cs

?

?

控制圖片的移動和切換

?

  制作坦克渲染

  添加精靈數組的引用

private SpriteRenderer sr;public Sprite[] tankSprite;

?

(上 右 下 左)

?

  玩家按上下左右控制坦克方向的移動

//監聽玩家水平軸輸入float h = Input.GetAxisRaw("Horizontal"); //返回-1 0 1transform.Translate(Vector3.right*h*moveSpeed*Time.deltaTime,Space.World);if (h < 0){sr.sprite = tankSprite[3];}else if (h>0){sr.sprite = tankSprite[1];}//監聽玩家垂直軸輸入float v = Input.GetAxisRaw("Vertical");transform.Translate(Vector3.up * v * moveSpeed * Time.deltaTime, Space.World);if (v < 0){sr.sprite = tankSprite[2];}else if (v > 0){sr.sprite = tankSprite[0];}

?

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Player : MonoBehaviour {public float moveSpeed = 3;private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左// Use this for initializationvoid Start () {sr = GetComponent<SpriteRenderer>();}// Update is called once per framevoid Update () {//監聽玩家水平軸輸入float h = Input.GetAxisRaw("Horizontal"); //返回-1 0 1transform.Translate(Vector3.right*h*moveSpeed*Time.deltaTime,Space.World);if (h < 0){sr.sprite = tankSprite[3];}else if (h>0){sr.sprite = tankSprite[1];}//監聽玩家垂直軸輸入float v = Input.GetAxisRaw("Vertical");transform.Translate(Vector3.up * v * moveSpeed * Time.deltaTime, Space.World);if (v < 0){sr.sprite = tankSprite[2];}else if (v > 0){sr.sprite = tankSprite[0];}} } Player.cs

?

?

碰撞器的添加

?

  碰撞檢測

    兩個物體都有碰撞器

    一個物體上掛載剛體組件

?

  給玩家Player添加2D剛體和2D碰撞器

  剛體的Gravity Scale設置為0,取消重力因素的影響

?

?  給Barriar、Wall、River、Heart添加Box Collider 2D碰撞器

?

?

  發現坦克方向坐標軸會改變,在Rigidbody 2D中Constraints下的Freeze Rotation Z 進行綁定,當它碰撞到物體時坐標不發生偏移

?

  

?

  解決抖動問題

?

  使用private void FixedUpdate()

FixedUpdate () 和 Update () 同:當MonoBehaviour啟用時,其在每一幀被調用。都是用來更新的異:Update()每一幀的時間不固定,即第一幀與第二幀的時間t1和第三幀與第四幀的時間t2不一定相同。FixedUpdate()每幀與每幀之間相差的時間是固定的.Update受當前渲染的物體影響,這與當前場景中正在被渲染的物體有關(比如人物的面數,個數等),有時快有時慢,幀率會變化,Update被調用的時間間隔就會發生變化。但是FixedUpdate則不受幀率的變化影響,它是以固定的時間間隔來被調用。所以一些物理屬性的更新操作應該放在FxiedUpdate中操作,比如Force,Collider,Rigidbody等。外設的操作也是,比如說鍵盤或者鼠標的輸入輸出Input,因為這樣GameObject的物理表現的更平滑,更接近現實。FixedUpdate的時間間隔可以在項目設置中更改,Edit->Project Setting->time 找到Fixed timestep。就可以修改了 FixedUpdate () 和 Update ()

?

//監聽玩家水平軸輸入float h = Input.GetAxisRaw("Horizontal"); //返回-1 0 1transform.Translate(Vector3.right*h*moveSpeed*Time.fixedDeltaTime,Space.World);//監聽玩家垂直軸輸入float v = Input.GetAxisRaw("Vertical");transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);

?

  FixedUpdate()方法留空就行

private void FixedUpdate(){}

?

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Player : MonoBehaviour {public float moveSpeed = 3;private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左// Use this for initializationvoid Start () {sr = GetComponent<SpriteRenderer>();}// Update is called once per framevoid Update () {//監聽玩家水平軸輸入float h = Input.GetAxisRaw("Horizontal"); //返回-1 0 1transform.Translate(Vector3.right*h*moveSpeed*Time.fixedDeltaTime,Space.World);if (h < 0){sr.sprite = tankSprite[3];}else if (h>0){sr.sprite = tankSprite[1];}//監聽玩家垂直軸輸入float v = Input.GetAxisRaw("Vertical");transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v < 0){sr.sprite = tankSprite[2];}else if (v > 0){sr.sprite = tankSprite[0];}}// private void FixedUpdate(){} } Player.cs

?

  解決玩家按方向鍵左右的同時按上下

  在監聽玩家垂直軸輸入后對v方向按鍵進行判斷,如果為0則在Update()中直接返回

float v = Input.GetAxisRaw("Vertical");transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v < 0){sr.sprite = tankSprite[2];}else if (v > 0){sr.sprite = tankSprite[0];}if(v!=0){return;}//監聽玩家水平軸輸入float h = Input.GetAxisRaw("Horizontal"); //返回-1 0 1transform.Translate(Vector3.right*h*moveSpeed*Time.fixedDeltaTime,Space.World);if (h < 0){sr.sprite = tankSprite[3];}else if (h>0){sr.sprite = tankSprite[1];}

?

  整理一下Player.cs腳本

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Player : MonoBehaviour {//屬性值public float moveSpeed = 3;//引用private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左// Use this for initializationvoid Start () {sr = GetComponent<SpriteRenderer>();}// Update is called once per framevoid Update () {}private void FixedUpdate(){Move();}//坦克的移動方法private void Move(){//監聽玩家垂直軸輸入float v = Input.GetAxisRaw("Vertical");transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v < 0){sr.sprite = tankSprite[2];}else if (v > 0){sr.sprite = tankSprite[0];}if (v != 0){return;}//監聽玩家水平軸輸入float h = Input.GetAxisRaw("Horizontal"); //返回-1 0 1transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World);if (h < 0){sr.sprite = tankSprite[3];}else if (h > 0){sr.sprite = tankSprite[1];}} } Player.cs

?

?

2D渲染層級

?

  設置游戲物體的層級

      

?

      

?

?

?

坦克的攻擊

?

  坦克的攻擊方法

private void Attack(){if(Input.GetKeyDown(KeyCode.Space)){Instantiate(bullectPrefab,transform.position,transform.rotation);}}

?

private void FixedUpdate(){Move();Attack();}

?

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Player : MonoBehaviour {//屬性值public float moveSpeed = 3;//引用private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左public GameObject bullectPrefab;// Use this for initializationvoid Start () {sr = GetComponent<SpriteRenderer>();}// Update is called once per framevoid Update () {}private void FixedUpdate(){Move();Attack();}//坦克的攻擊方法private void Attack(){if(Input.GetKeyDown(KeyCode.Space)){Instantiate(bullectPrefab,transform.position,transform.rotation);}}//坦克的移動方法private void Move(){//監聽玩家垂直軸輸入float v = Input.GetAxisRaw("Vertical");transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v < 0){sr.sprite = tankSprite[2];}else if (v > 0){sr.sprite = tankSprite[0];}if (v != 0){return;}//監聽玩家水平軸輸入float h = Input.GetAxisRaw("Horizontal"); //返回-1 0 1transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World);if (h < 0){sr.sprite = tankSprite[3];}else if (h > 0){sr.sprite = tankSprite[1];}} } player.cs

?

  子彈的朝向和移動

  通過按鍵V和H來判斷子彈旋轉的角度

?

  定義子彈旋轉的角度

private Vector3 bullectEulerAugles;

?

  子彈參數的角度:當前坦克的角度+子彈應該旋轉的角度

Instantiate(bullectPrefab,transform.position,Quaternion.Euler(transform.eulerAngles+bullectEulerAugles));

?

private void Attack(){if(Input.GetKeyDown(KeyCode.Space)){//子彈參數的角度:當前坦克的角度+子彈應該旋轉的角度Instantiate(bullectPrefab,transform.position,Quaternion.Euler(transform.eulerAngles+bullectEulerAugles));timeVal = 0;}}

?

  給子彈添加方向速度

public float moveSpeed = 10;

?

  給子彈添加判斷是否是友軍

public bool isPlayerBullect;

?

void Update () {transform.Translate(transform.up*moveSpeed*Time.deltaTime,Space.World);}

?

  添加子彈攻擊CD間隔

if (timeVal>=0.4f){//間隔大于0.4的時候才有攻擊效果 Attack();}else{timeVal += Time.deltaTime;}

?

?

?

?

  給組件添加標簽

  

?

  給子彈添加碰撞體和觸發器

?

  添加Heart.cs腳本,當Heart心臟被子彈攻擊時,切換死亡圖片

private SpriteRenderer sr;public Sprite BrokenSprite; // Use this for initializationvoid Start () {sr = GetComponent<SpriteRenderer>();}

?

  添加Heart.cs心臟死亡時方法

private void Die(){sr.sprite = BrokenSprite; }

?

  添加Explosion.cs腳本

  當坦克銷毀時觸發腳本

public class Explosion : MonoBehaviour {// Use this for initializationvoid Start () {//坦克銷毀后0.167秒銷毀爆炸特效Destroy(gameObject,0.167f);}// Update is called once per framevoid Update () {} }

?

  子彈觸發碰撞檢測

  當子彈碰撞到物體時觸發OnTriggerEnter2D(Collider2D collision)方法

  子彈碰到“Tank”判斷是否是友軍,不是的話擊毀自己

  子彈碰到"Wall"時,銷毀子彈自身

  子彈碰到"Heart"時,觸發基地死亡方法

  子彈碰到"Barrier"剛體時,銷毀子彈

?

private void OnTriggerEnter2D(Collider2D collision){switch(collision.tag){case "Tank":if(!isPlayerBullect){collision.SendMessage("Die");}break;case "Heart":collision.SendMessage("Die");Destroy(gameObject);break;case "Enemy":break;case "Wall"://銷毀自身和墻 Destroy(collision.gameObject);Destroy(gameObject);break;case "Barrier":Destroy(gameObject);break;default:break;}}

?

  

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Player : MonoBehaviour {//屬性值public float moveSpeed = 3;private Vector3 bullectEulerAugles;public float timeVal;private float defendTimeVal=1;private bool isDefended=true;//引用private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左public GameObject bullectPrefab;public GameObject explosionPrefab;public GameObject defendEffectPrefab;// Use this for initializationvoid Start () {sr = GetComponent<SpriteRenderer>();}// Update is called once per framevoid Update () {//保護是否處于無敵狀態if(isDefended){defendEffectPrefab.SetActive(true);defendTimeVal -= Time.deltaTime;if (defendTimeVal<=0){isDefended = false;defendEffectPrefab.SetActive(false);}}//攻擊的CDif (timeVal>=0.4f){//間隔大于0.4的時候才有攻擊效果 Attack();}else{timeVal += Time.deltaTime;}}private void FixedUpdate(){Move();}//坦克的攻擊方法private void Attack(){if(Input.GetKeyDown(KeyCode.Space)){//子彈參數的角度:當前坦克的角度+子彈應該旋轉的角度Instantiate(bullectPrefab,transform.position,Quaternion.Euler(transform.eulerAngles+bullectEulerAugles));timeVal = 0;}}//坦克的移動方法private void Move(){//監聽玩家垂直軸輸入float v = Input.GetAxisRaw("Vertical");transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v < 0){sr.sprite = tankSprite[2];bullectEulerAugles = new Vector3(0, 0, -180);}else if (v > 0){sr.sprite = tankSprite[0];bullectEulerAugles = new Vector3(0, 0, 0);}if (v != 0){return;}//監聽玩家水平軸輸入float h = Input.GetAxisRaw("Horizontal"); //返回-1 0 1transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World);if (h < 0){sr.sprite = tankSprite[3];bullectEulerAugles = new Vector3(0, 0, 90);}else if (h > 0){sr.sprite = tankSprite[1];bullectEulerAugles = new Vector3(0, 0, -90);}}//坦克的死亡方法private void Die(){if(isDefended){return;}//產生爆炸特效 Instantiate(explosionPrefab, transform.position, transform.rotation);//死亡 Destroy(gameObject);} } Player.cs

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Explosion : MonoBehaviour {// Use this for initializationvoid Start () {//坦克銷毀后0.167秒銷毀爆炸特效Destroy(gameObject,0.167f);}// Update is called once per framevoid Update () {} } Explosion.cs

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Heart : MonoBehaviour {private SpriteRenderer sr;public Sprite BrokenSprite; // Use this for initializationvoid Start () {sr = GetComponent<SpriteRenderer>();}private void Die(){sr.sprite = BrokenSprite; } } Heart

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Bullect : MonoBehaviour {public float moveSpeed = 10;public bool isPlayerBullect;// Use this for initializationvoid Start () {}// Update is called once per framevoid Update () {transform.Translate(transform.up*moveSpeed*Time.deltaTime,Space.World);}//子彈觸發碰撞檢測private void OnTriggerEnter2D(Collider2D collision){switch(collision.tag){case "Tank":if(!isPlayerBullect){collision.SendMessage("Die");}break;case "Heart":collision.SendMessage("Die");Destroy(gameObject);break;case "Enemy":break;case "Wall"://銷毀自身和墻 Destroy(collision.gameObject);Destroy(gameObject);break;case "Barrier":Destroy(gameObject);break;default:break;}}} Bullect.cs

?

?

敵人的制作

?

  Ctrl+D一份玩家,修改圖片渲染,制作敵人

?

  添加敵人腳本Enemy.cs

  玩家的移動和敵人的移動差不多,把Player.cs腳本中內容復制到Enemy.cs當中

  

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Enemy : MonoBehaviour {//屬性值public float moveSpeed = 3;private Vector3 bullectEulerAugles;public float timeVal;private float defendTimeVal = 1;private bool isDefended = true;//引用private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左public GameObject bullectPrefab;public GameObject explosionPrefab;public GameObject defendEffectPrefab;// Use this for initializationvoid Start(){sr = GetComponent<SpriteRenderer>();}// Update is called once per framevoid Update(){//保護是否處于無敵狀態if (isDefended){defendEffectPrefab.SetActive(true);defendTimeVal -= Time.deltaTime;if (defendTimeVal <= 0){isDefended = false;defendEffectPrefab.SetActive(false);}}//攻擊的CDif (timeVal >= 0.4f){//間隔大于0.4的時候才有攻擊效果 Attack();}else{timeVal += Time.deltaTime;}}private void FixedUpdate(){Move();}//坦克的攻擊方法private void Attack(){if (Input.GetKeyDown(KeyCode.Space)){//子彈參數的角度:當前坦克的角度+子彈應該旋轉的角度Instantiate(bullectPrefab, transform.position, Quaternion.Euler(transform.eulerAngles + bullectEulerAugles));timeVal = 0;}}//坦克的移動方法private void Move(){//監聽玩家垂直軸輸入float v = Input.GetAxisRaw("Vertical");transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v < 0){sr.sprite = tankSprite[2];bullectEulerAugles = new Vector3(0, 0, -180);}else if (v > 0){sr.sprite = tankSprite[0];bullectEulerAugles = new Vector3(0, 0, 0);}if (v != 0){return;}//監聽玩家水平軸輸入float h = Input.GetAxisRaw("Horizontal"); //返回-1 0 1transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World);if (h < 0){sr.sprite = tankSprite[3];bullectEulerAugles = new Vector3(0, 0, 90);}else if (h > 0){sr.sprite = tankSprite[1];bullectEulerAugles = new Vector3(0, 0, -90);}}//坦克的死亡方法private void Die(){if (isDefended){return;}//產生爆炸特效 Instantiate(explosionPrefab, transform.position, transform.rotation);//死亡 Destroy(gameObject);} } Enemy.cs

(因為敵人沒有出生無敵3s,運行時無敵預制體defendEffectPrefab會出現報空)

?

  添加基地死亡時動畫

public GameObject explosionPrefab;

?

private void Die(){sr.sprite = BrokenSprite;Instantiate(explosionPrefab,transform.position,transform.rotation);}

?

  (關閉項目后爆炸腳本失活了,最后的時候再做一個補上)

?

  添加一個玩家出生時腳本Born.cs

  延時玩家出生和死亡動畫

public GameObject playerPrefab;// Use this for initializationvoid Start () {Invoke("BornTank",1f);Destroy(gameObject,1f);}private void BornTank(){Instantiate(playerPrefab,transform.position,Quaternion.identity);}

?

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Born : MonoBehaviour {public GameObject playerPrefab;// Use this for initializationvoid Start () {Invoke("BornTank",0.8f);Destroy(gameObject,0.8f);}// Update is called once per framevoid Update () {}private void BornTank(){Instantiate(playerPrefab,transform.position,Quaternion.identity);} } Born.cs

?

  制作大坦克和小坦克,添加坦克方向變化時改變坦克方向圖片

  坦克改變方向順序按上、右、下、左進行添加

?

  小敵人同打敵人設置當坦克方向改變時切換自身圖片

  將大敵人和小敵人設置成預制體

  小敵人速度調大一些,改為5

?

  編寫Born.cs腳本判斷是否產生敵人

public bool createPlay;

?

private void BornTank(){if (createPlay){Instantiate(playerPrefab, transform.position, Quaternion.identity);}else{int num = Random.Range(0, 2);Instantiate(enemyPrefabList[num], transform.position, Quaternion.identity);}}

?

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Born : MonoBehaviour {public GameObject playerPrefab;public GameObject[] enemyPrefabList;//判斷是否產生敵人public bool createPlay;// Use this for initializationvoid Start () {Invoke("BornTank",1f);Destroy(gameObject,1f);}private void Update(){}private void BornTank(){if (createPlay){Instantiate(playerPrefab, transform.position, Quaternion.identity);}else{int num = Random.Range(0, 2);Instantiate(enemyPrefabList[num], transform.position, Quaternion.identity);}} } Born.cs

?

?

編寫敵人AI

?

  子彈間3s攻擊一次

void Update(){//攻擊的時間間隔if (timeVal >= 0.3f){//間隔大于0.4的時候才有攻擊效果 Attack();}else{timeVal += Time.deltaTime;}}

?

//坦克的攻擊方法private void Attack(){//子彈參數的角度:當前坦克的角度+子彈應該旋轉的角度Instantiate(bullectPrefab, transform.position, Quaternion.Euler(transform.eulerAngles + bullectEulerAugles));timeVal = 0;}

?

  坦克的移動不需要按下上下左右鍵盤,只需要管理V和H的值對敵人AI進行方向的控制

  定義兩個計時器

public float timeVal;public float timeValChangeDirection;

?

  修改敵人移動的方法

  

private void Move(){if(timeValChangeDirection>=4){int num = Random.Range(0,8);if(num>5){v = -1;h = 0;}else if (num == 0){v = 1;h = 0;}else if (num > 0 && num <= 2){h = -1;v = 0;}else if (num > 2 && num <= 4){h = 1;v = 0;}timeValChangeDirection = 0;}else{timeValChangeDirection += Time.fixedDeltaTime;}//監聽玩家垂直軸輸入 transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v < 0){sr.sprite = tankSprite[2];bullectEulerAugles = new Vector3(0, 0, -180);}else if (v > 0){sr.sprite = tankSprite[0];bullectEulerAugles = new Vector3(0, 0, 0);}if (v != 0){return;}//監聽玩家水平軸輸入 transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World);if (h < 0){sr.sprite = tankSprite[3];bullectEulerAugles = new Vector3(0, 0, 90);}else if (h > 0){sr.sprite = tankSprite[1];bullectEulerAugles = new Vector3(0, 0, -90);}}

?

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Enemy : MonoBehaviour {//屬性值public float moveSpeed = 3;private Vector3 bullectEulerAugles;private float v;private float h;//引用private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左public GameObject bullectPrefab;public GameObject explosionPrefab;//計時器public float timeVal;public float timeValChangeDirection=4;// Use this for initializationvoid Start(){sr = GetComponent<SpriteRenderer>();}// Update is called once per framevoid Update(){//攻擊的時間間隔if (timeVal >= 0.3f){//間隔大于0.4的時候才有攻擊效果 Attack();}else{timeVal += Time.deltaTime;}}private void FixedUpdate(){Move();}//坦克的攻擊方法private void Attack(){//子彈參數的角度:當前坦克的角度+子彈應該旋轉的角度Instantiate(bullectPrefab, transform.position, Quaternion.Euler(transform.eulerAngles + bullectEulerAugles));timeVal = 0;}//坦克的移動方法private void Move(){if(timeValChangeDirection>=4){int num = Random.Range(0,8);if(num>5){v = -1;h = 0;}else if (num == 0){v = 1;h = 0;}else if (num > 0 && num <= 2){h = -1;v = 0;}else if (num > 2 && num <= 4){h = 1;v = 0;}timeValChangeDirection = 0;}else{timeValChangeDirection += Time.fixedDeltaTime;}//監聽玩家垂直軸輸入 transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v < 0){sr.sprite = tankSprite[2];bullectEulerAugles = new Vector3(0, 0, -180);}else if (v > 0){sr.sprite = tankSprite[0];bullectEulerAugles = new Vector3(0, 0, 0);}if (v != 0){return;}//監聽玩家水平軸輸入 transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World);if (h < 0){sr.sprite = tankSprite[3];bullectEulerAugles = new Vector3(0, 0, 90);}else if (h > 0){sr.sprite = tankSprite[1];bullectEulerAugles = new Vector3(0, 0, -90);}}//坦克的死亡方法private void Die(){//產生爆炸特效 Instantiate(explosionPrefab, transform.position, transform.rotation);//死亡 Destroy(gameObject);} } Enemy.cs

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Bullect : MonoBehaviour {public float moveSpeed = 10;public bool isPlayerBullect;// Use this for initializationvoid Start () {}// Update is called once per framevoid Update () {transform.Translate(transform.up*moveSpeed*Time.deltaTime,Space.World);}//子彈觸發碰撞檢測private void OnTriggerEnter2D(Collider2D collision){switch(collision.tag){case "Tank":if(!isPlayerBullect){collision.SendMessage("Die");}Destroy(gameObject);break;case "Heart":collision.SendMessage("Die");Destroy(gameObject);break;case "Enemy":if(isPlayerBullect){collision.SendMessage("Die");}Destroy(gameObject);break;case "Wall"://銷毀自身和墻 Destroy(collision.gameObject);Destroy(gameObject);break;case "Barrier":Destroy(gameObject);break;default:break;}}} Bullect.cs

?

?

初始化地圖工具

?

  判斷地圖長度

?

  地圖大小:長20  寬16

?

  添加MapCreation.cs地圖管理器來控制草和地圖等建筑物

public class MapCreation : MonoBehaviour {//用來裝飾初始化地圖所需物體的數組//0.老家 1.墻 2.障礙 3.出生效果 4.河流 5.草 6.空氣墻public GameObject[] item;}

?

?

  制作老家心臟和心臟周圍的圍墻

private void Awake(){//實例化老家Instantiate(item[0], new Vector3(0, -8, -0), Quaternion.identity);//用墻把老家圍起來Instantiate(item[1], new Vector3(-1, -8, -0), Quaternion.identity);Instantiate(item[1], new Vector3(1, -8, -0), Quaternion.identity);for(int i=-1;i<2;i++){Instantiate(item[1],new Vector3(i,-7,0),Quaternion.identity);}}

?

?

  對同一個位置上進行判斷,判斷是否有障礙物在上面,如果在上面那不再額外生成其它建筑物

  已經有東西位置的列表

private List<Vector3> itemPositionList = new List<Vector3>();

?

private void CreateItem(GameObject createGameObject,Vector3 createPosition,Quaternion createRotate){GameObject itemGo = Instantiate(createGameObject, createPosition, createRotate);itemGo.transform.SetParent(gameObject.transform);itemPositionList.Add(createPosition);}

?

  制作外圍墻,也就是游戲邊界

for(int i=-11;i<12;i++){CreateItem(item[6], new Vector3(i, 9, 0), Quaternion.identity);}for(int i=-11;i<12;i++){CreateItem(item[6], new Vector3(i, -9, 0), Quaternion.identity);}for(int i=-8;i<9;i++){CreateItem(item[6], new Vector3(-11, i, 0), Quaternion.identity);}for(int i=-8;i<9;i++){CreateItem(item[6], new Vector3(-11, i, 0), Quaternion.identity);}

?

  產生隨機位置的方法

private Vector3 CreateRamdomPosition(){//不生成x=-10,10的兩列,y=-8和8這兩行的位置while(true){Vector3 createPosition = new Vector3(Random.Range(-9, 10), Random.Range(-7, 8),0);if(!HasThePosition(createPosition)){return createPosition;}}}

?

  用來判斷位置列表中是否有這個位置

private bool HasThePosition(Vector3 createPos){for(int i=0;i<itemPositionList.Count;i++){if(createPos==itemPositionList[i]){return true;}}return false;}

?

?

  修復子彈觸發碰撞檢測

private void OnTriggerEnter2D(Collider2D collision){switch(collision.tag){case "Tank":if(!isPlayerBullect){collision.SendMessage("Die");Destroy(gameObject);}break;case "Heart":collision.SendMessage("Die");Destroy(gameObject);break;case "Enemy":if(isPlayerBullect){collision.SendMessage("Die");Destroy(gameObject);}break;case "Wall"://銷毀自身和墻 Destroy(collision.gameObject);Destroy(gameObject);break;case "Barrier":Destroy(gameObject);break;default:break;}}

?

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Bullect : MonoBehaviour {public float moveSpeed = 10;public bool isPlayerBullect;// Use this for initializationvoid Start () {}// Update is called once per framevoid Update () {transform.Translate(transform.up*moveSpeed*Time.deltaTime,Space.World);}//子彈觸發碰撞檢測private void OnTriggerEnter2D(Collider2D collision){switch(collision.tag){case "Tank":if(!isPlayerBullect){collision.SendMessage("Die");Destroy(gameObject);}break;case "Heart":collision.SendMessage("Die");Destroy(gameObject);break;case "Enemy":if(isPlayerBullect){collision.SendMessage("Die");Destroy(gameObject);}break;case "Wall"://銷毀自身和墻 Destroy(collision.gameObject);Destroy(gameObject);break;case "Barrier":Destroy(gameObject);break;default:break;}}} Bullect.cs

?

  實例化地圖

for(int i=0;i<20;i++){CreateItem(item[1], CreateRamdomPosition(), Quaternion.identity);}for(int i=0;i<20;i++){CreateItem(item[2], CreateRamdomPosition(), Quaternion.identity);}for (int i = 0; i < 20; i++){CreateItem(item[4], CreateRamdomPosition(), Quaternion.identity);}for (int i = 0; i < 20; i++){CreateItem(item[5], CreateRamdomPosition(), Quaternion.identity);}

?

  

?

  初始化玩家

GameObject go = Instantiate(item[3], new Vector3(-2, -8, 0), Quaternion.identity); go.GetComponent<Born>().createPlay = true;

?

  產生敵人

CreateItem(item[3], new Vector3(-10,8,0),Quaternion.identity); CreateItem(item[3], new Vector3(0, 8, 0), Quaternion.identity); CreateItem(item[3], new Vector3(10, 8, 0), Quaternion.identity);

?

  實例化地圖并且讓圍墻的數量盡可能的多

for (int i=0;i<60;i++){CreateItem(item[1], CreateRamdomPosition(), Quaternion.identity);}for(int i=0;i<20;i++){CreateItem(item[2], CreateRamdomPosition(), Quaternion.identity);}for (int i = 0; i < 20; i++){CreateItem(item[4], CreateRamdomPosition(), Quaternion.identity);}for (int i = 0; i < 20; i++){CreateItem(item[5], CreateRamdomPosition(), Quaternion.identity);}

?

  產生敵人的方法

private void CreateEnemy(){int num = Random.Range(0, 3);Vector3 EnemyPos = new Vector3();if(num==0){EnemyPos = new Vector3(-10, 8, 0);}else if(num==1){EnemyPos = new Vector3(0, 8, 0);}else{EnemyPos = new Vector3(10, 8, 0);}CreateItem(item[3],EnemyPos,Quaternion.identity);}

?

  每隔5s產生一波敵人

InvokeRepeating("CreateEnemy",4,5);

?

  優化一下敵人AI

  敵人AI碰到一起時切換一次方向

private void OnCollisionEnter2D(Collision2D collision){if(collision.gameObject.tag=="Enemy"){timeValChangeDirection = 4;}}

?

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Player : MonoBehaviour {//屬性值public float moveSpeed = 3;private Vector3 bullectEulerAugles;public float timeVal;private float defendTimeVal=3;private bool isDefended=true;//引用private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左public GameObject bullectPrefab;public GameObject explosionPrefab;public GameObject defendEffectPrefab;// Use this for initializationvoid Start () {sr = GetComponent<SpriteRenderer>();}// Update is called once per framevoid Update () {//保護是否處于無敵狀態if(isDefended){defendEffectPrefab.SetActive(true);defendTimeVal -= Time.deltaTime;if (defendTimeVal<=0){isDefended = false;defendEffectPrefab.SetActive(false);}}//攻擊的CDif (timeVal>=0.4f){//間隔大于0.4的時候才有攻擊效果 Attack();}else{timeVal += Time.deltaTime;}}private void FixedUpdate(){Move();}//坦克的攻擊方法private void Attack(){if(Input.GetKeyDown(KeyCode.Space)){//子彈參數的角度:當前坦克的角度+子彈應該旋轉的角度Instantiate(bullectPrefab,transform.position,Quaternion.Euler(transform.eulerAngles+bullectEulerAugles));timeVal = 0;}}//坦克的移動方法private void Move(){//監聽玩家垂直軸輸入float v = Input.GetAxisRaw("Vertical");transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v < 0){sr.sprite = tankSprite[2];bullectEulerAugles = new Vector3(0, 0, -180);}else if (v > 0){sr.sprite = tankSprite[0];bullectEulerAugles = new Vector3(0, 0, 0);}if (v != 0){return;}//監聽玩家水平軸輸入float h = Input.GetAxisRaw("Horizontal"); //返回-1 0 1transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World);if (h < 0){sr.sprite = tankSprite[3];bullectEulerAugles = new Vector3(0, 0, 90);}else if (h > 0){sr.sprite = tankSprite[1];bullectEulerAugles = new Vector3(0, 0, -90);}}//坦克的死亡方法private void Die(){if(isDefended){return;}//產生爆炸特效 Instantiate(explosionPrefab, transform.position, transform.rotation);//死亡 Destroy(gameObject);} } Player.cs

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class MapCreation : MonoBehaviour {//用來裝飾初始化地圖所需物體的數組//0.老家 1.墻 2.障礙 3.出生效果 4.河流 5.草 6.空氣墻public GameObject[] item;//已經有東西位置的列表private List<Vector3> itemPositionList = new List<Vector3>();private void Awake(){//實例化老家CreateItem(item[0], new Vector3(0, -8, -0), Quaternion.identity);//用墻把老家圍起來CreateItem(item[1], new Vector3(-1, -8, -0), Quaternion.identity);CreateItem(item[1], new Vector3(1, -8, -0), Quaternion.identity);for(int i=-1;i<2;i++){Instantiate(item[1],new Vector3(i,-7,0),Quaternion.identity);}//實例化外圍墻for(int i=-11;i<12;i++){CreateItem(item[6], new Vector3(i, 9, 0), Quaternion.identity);}for(int i=-11;i<12;i++){CreateItem(item[6], new Vector3(i, -9, 0), Quaternion.identity);}for(int i=-8;i<9;i++){CreateItem(item[6], new Vector3(-11, i, 0), Quaternion.identity);}for(int i=-8;i<9;i++){CreateItem(item[6], new Vector3(11, i, 0), Quaternion.identity);}//初始化玩家GameObject go = Instantiate(item[3], new Vector3(-2, -8, 0), Quaternion.identity);go.GetComponent<Born>().createPlay = true;//產生敵人CreateItem(item[3], new Vector3(-10,8,0),Quaternion.identity);CreateItem(item[3], new Vector3(0, 8, 0), Quaternion.identity);CreateItem(item[3], new Vector3(10, 8, 0), Quaternion.identity);//第一次調用CreateEnemy用4s,每隔5s開調用InvokeRepeating("CreateEnemy",4,5);//實例化地圖for (int i=0;i<60;i++){CreateItem(item[1], CreateRamdomPosition(), Quaternion.identity);}for(int i=0;i<20;i++){CreateItem(item[2], CreateRamdomPosition(), Quaternion.identity);}for (int i = 0; i < 20; i++){CreateItem(item[4], CreateRamdomPosition(), Quaternion.identity);}for (int i = 0; i < 20; i++){CreateItem(item[5], CreateRamdomPosition(), Quaternion.identity);}}private void CreateItem(GameObject createGameObject,Vector3 createPosition,Quaternion createRotate){GameObject itemGo = Instantiate(createGameObject, createPosition, createRotate);itemGo.transform.SetParent(gameObject.transform);itemPositionList.Add(createPosition);}//產生隨機位置的方法private Vector3 CreateRamdomPosition(){//不生成x=-10,10的兩列,y=-8和8這兩行的位置while(true){Vector3 createPosition = new Vector3(Random.Range(-9, 10), Random.Range(-7, 8),0);if(!HasThePosition(createPosition)){return createPosition;}}}//用來判斷位置列表中是否有這個位置private bool HasThePosition(Vector3 createPos){for(int i=0;i<itemPositionList.Count;i++){if(createPos==itemPositionList[i]){return true;}}return false;}//產生敵人的方法private void CreateEnemy(){int num = Random.Range(0, 3);Vector3 EnemyPos = new Vector3();if(num==0){EnemyPos = new Vector3(-10, 8, 0);}else if(num==1){EnemyPos = new Vector3(0, 8, 0);}else{EnemyPos = new Vector3(10, 8, 0);}CreateItem(item[3],EnemyPos,Quaternion.identity);}} MapCreation.cs

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Born : MonoBehaviour {public GameObject playerPrefab;public GameObject[] enemyPrefabList;//判斷是否產生敵人public bool createPlay;// Use this for initializationvoid Start () {Invoke("BornTank",1f);Destroy(gameObject,1f);}private void Update(){}private void BornTank(){if (createPlay){Instantiate(playerPrefab, transform.position, Quaternion.identity);}else{int num = Random.Range(0, 2);Instantiate(enemyPrefabList[num], transform.position, Quaternion.identity);}} } Born.cs

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Enemy : MonoBehaviour {//屬性值public float moveSpeed = 3;private Vector3 bullectEulerAugles;private float v;private float h;//引用private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左public GameObject bullectPrefab;public GameObject explosionPrefab;//計時器public float timeVal;public float timeValChangeDirection=4;// Use this for initializationvoid Start(){sr = GetComponent<SpriteRenderer>();}// Update is called once per framevoid Update(){//攻擊的時間間隔if (timeVal >= 0.3f){//間隔大于0.4的時候才有攻擊效果 Attack();}else{timeVal += Time.deltaTime;}}private void FixedUpdate(){Move();}//坦克的攻擊方法private void Attack(){//子彈參數的角度:當前坦克的角度+子彈應該旋轉的角度Instantiate(bullectPrefab, transform.position, Quaternion.Euler(transform.eulerAngles + bullectEulerAugles));timeVal = 0;}//坦克的移動方法private void Move(){if(timeValChangeDirection>=4){int num = Random.Range(0,8);if(num>5){v = -1;h = 0;}else if (num == 0){v = 1;h = 0;}else if (num > 0 && num <= 2){h = -1;v = 0;}else if (num > 2 && num <= 4){h = 1;v = 0;}timeValChangeDirection = 0;}else{timeValChangeDirection += Time.fixedDeltaTime;}//監聽玩家垂直軸輸入 transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v < 0){sr.sprite = tankSprite[2];bullectEulerAugles = new Vector3(0, 0, -180);}else if (v > 0){sr.sprite = tankSprite[0];bullectEulerAugles = new Vector3(0, 0, 0);}if (v != 0){return;}//監聽玩家水平軸輸入 transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World);if (h < 0){sr.sprite = tankSprite[3];bullectEulerAugles = new Vector3(0, 0, 90);}else if (h > 0){sr.sprite = tankSprite[1];bullectEulerAugles = new Vector3(0, 0, -90);}}//坦克的死亡方法private void Die(){//產生爆炸特效 Instantiate(explosionPrefab, transform.position, transform.rotation);//死亡 Destroy(gameObject);}//優化敵人AIprivate void OnCollisionEnter2D(Collision2D collision){if(collision.gameObject.tag=="Enemy"){timeValChangeDirection = 4;}}} Enemy.cs

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Explosion : MonoBehaviour {// Use this for initializationvoid Start () {//坦克銷毀后0.167秒銷毀爆炸特效Destroy(gameObject,0.167f);}// Update is called once per framevoid Update () {} } Explosion

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Heart : MonoBehaviour {private SpriteRenderer sr;public GameObject explosionPrefab;public Sprite BrokenSprite; // Use this for initializationvoid Start () {sr = GetComponent<SpriteRenderer>();}private void Die(){sr.sprite = BrokenSprite;Instantiate(explosionPrefab,transform.position,transform.rotation);} } Heart.cs

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Bullect : MonoBehaviour {public float moveSpeed = 10;public bool isPlayerBullect;// Use this for initializationvoid Start () {}// Update is called once per framevoid Update () {transform.Translate(transform.up*moveSpeed*Time.deltaTime,Space.World);}//子彈觸發碰撞檢測private void OnTriggerEnter2D(Collider2D collision){switch(collision.tag){case "Tank":if(!isPlayerBullect){collision.SendMessage("Die");Destroy(gameObject);}break;case "Heart":collision.SendMessage("Die");Destroy(gameObject);break;case "Enemy":if(isPlayerBullect){collision.SendMessage("Die");Destroy(gameObject);}break;case "Wall"://銷毀自身和墻 Destroy(collision.gameObject);Destroy(gameObject);break;case "Barrier":Destroy(gameObject);break;default:break;}}} Bullect.cs

?

?

玩家狀態管理

?

  游戲中添加空物體PlayerManager對象

  添加游戲的屬性值

public int lifeVale = 3;public int playerScore = 0;public bool isDead;

?

  坦克的死亡方法

private void Die(){if(isDefended){return;}PlayerManager.Instance.isDead = true;//產生爆炸特效 Instantiate(explosionPrefab, transform.position, transform.rotation);//死亡 Destroy(gameObject);}

?

  玩家狀態管理類監聽玩家狀態,當玩家被子彈擊中時,生命值開始降低

void Update () {if(isDead){Recover();}}private void Recover(){if (lifeVale < 0){//游戲失敗,返回主界面 SceneManager.LoadScene("Game");}else{lifeVale--;GameObject go = Instantiate(born,new Vector3(-2,-8,0),Quaternion.identity);go.GetComponent<Born>().createPlay = true;isDead = false;}}

?

?

?

游戲源代碼

?

  

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Player : MonoBehaviour {//屬性值public float moveSpeed = 3;private Vector3 bullectEulerAugles;public float timeVal;private float defendTimeVal=3;private bool isDefended=true;//引用private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左public GameObject bullectPrefab;public GameObject explosionPrefab;public GameObject defendEffectPrefab;// Use this for initializationvoid Start () {sr = GetComponent<SpriteRenderer>();}// Update is called once per framevoid Update () {//保護是否處于無敵狀態if(isDefended){defendEffectPrefab.SetActive(true);defendTimeVal -= Time.deltaTime;if (defendTimeVal<=0){isDefended = false;defendEffectPrefab.SetActive(false);}}}private void FixedUpdate(){if(PlayerManager.Instance.isDefeat){return;}Move();//攻擊的CDif (timeVal >= 0.4f){//間隔大于0.4的時候才有攻擊效果 Attack();}else{timeVal += Time.fixedDeltaTime;}}//坦克的攻擊方法private void Attack(){if(Input.GetKeyDown(KeyCode.Space)){//子彈參數的角度:當前坦克的角度+子彈應該旋轉的角度Instantiate(bullectPrefab,transform.position,Quaternion.Euler(transform.eulerAngles+bullectEulerAugles));timeVal = 0;}}//坦克的移動方法private void Move(){//監聽玩家垂直軸輸入float v = Input.GetAxisRaw("Vertical");transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v < 0){sr.sprite = tankSprite[2];bullectEulerAugles = new Vector3(0, 0, -180);}else if (v > 0){sr.sprite = tankSprite[0];bullectEulerAugles = new Vector3(0, 0, 0);}if (v != 0){return;}//監聽玩家水平軸輸入float h = Input.GetAxisRaw("Horizontal"); //返回-1 0 1transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World);if (h < 0){sr.sprite = tankSprite[3];bullectEulerAugles = new Vector3(0, 0, 90);}else if (h > 0){sr.sprite = tankSprite[1];bullectEulerAugles = new Vector3(0, 0, -90);}}//坦克的死亡方法private void Die(){if(isDefended){return;}PlayerManager.Instance.isDead = true;//產生爆炸特效 Instantiate(explosionPrefab, transform.position, transform.rotation);//死亡 Destroy(gameObject);} } Player.cs 游戲玩家

?

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement;public class PlayerManager : MonoBehaviour {//屬性值public int lifeVale = 3;public int playerScore = 0;public bool isDead=false;public bool isDefeat;//引用public GameObject born;//單例private static PlayerManager instance;public static PlayerManager Instance{get{return instance;}set{instance = value;}}public void Awake(){Instance = this;}// Use this for initializationvoid Start () {}// Update is called once per framevoid Update () {if(isDead){Recover();}}private void Recover(){if (lifeVale < 0){//游戲失敗,返回主界面 SceneManager.LoadScene("Game");}else{lifeVale--;GameObject go = Instantiate(born,new Vector3(-2,-8,0),Quaternion.identity);go.GetComponent<Born>().createPlay = true;isDead = false;}} } PlayerManager.cs 游戲玩家狀態管理

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class MapCreation : MonoBehaviour {//用來裝飾初始化地圖所需物體的數組//0.老家 1.墻 2.障礙 3.出生效果 4.河流 5.草 6.空氣墻public GameObject[] item;//已經有東西位置的列表private List<Vector3> itemPositionList = new List<Vector3>();private void Awake(){//實例化老家CreateItem(item[0], new Vector3(0, -8, -0), Quaternion.identity);//用墻把老家圍起來CreateItem(item[1], new Vector3(-1, -8, -0), Quaternion.identity);CreateItem(item[1], new Vector3(1, -8, -0), Quaternion.identity);for(int i=-1;i<2;i++){Instantiate(item[1],new Vector3(i,-7,0),Quaternion.identity);}//坦克一開始就向下太難了,就直接給老家前面加了一頂墻CreateItem(item[2], new Vector3(0, -4, -0), Quaternion.identity);//實例化外圍墻for (int i=-11;i<12;i++){CreateItem(item[6], new Vector3(i, 9, 0), Quaternion.identity);}for(int i=-11;i<12;i++){CreateItem(item[6], new Vector3(i, -9, 0), Quaternion.identity);}for(int i=-8;i<9;i++){CreateItem(item[6], new Vector3(-11, i, 0), Quaternion.identity);}for(int i=-8;i<9;i++){CreateItem(item[6], new Vector3(11, i, 0), Quaternion.identity);}//初始化玩家GameObject go = Instantiate(item[3], new Vector3(-2, -8, 0), Quaternion.identity);go.GetComponent<Born>().createPlay = true;//產生敵人CreateItem(item[3], new Vector3(-10,8,0),Quaternion.identity);CreateItem(item[3], new Vector3(0, 8, 0), Quaternion.identity);CreateItem(item[3], new Vector3(10, 8, 0), Quaternion.identity);//第一次調用CreateEnemy用4s,每隔5s開調用InvokeRepeating("CreateEnemy",4,5);//實例化地圖for (int i=0;i<60;i++){CreateItem(item[1], CreateRamdomPosition(), Quaternion.identity);}for(int i=0;i<20;i++){CreateItem(item[2], CreateRamdomPosition(), Quaternion.identity);}for (int i = 0; i < 20; i++){CreateItem(item[4], CreateRamdomPosition(), Quaternion.identity);}for (int i = 0; i < 20; i++){CreateItem(item[5], CreateRamdomPosition(), Quaternion.identity);}}private void CreateItem(GameObject createGameObject,Vector3 createPosition,Quaternion createRotate){GameObject itemGo = Instantiate(createGameObject, createPosition, createRotate);itemGo.transform.SetParent(gameObject.transform);itemPositionList.Add(createPosition);}//產生隨機位置的方法private Vector3 CreateRamdomPosition(){//不生成x=-10,10的兩列,y=-8和8這兩行的位置while(true){Vector3 createPosition = new Vector3(Random.Range(-9, 10), Random.Range(-7, 8),0);if(!HasThePosition(createPosition)){return createPosition;}}}//用來判斷位置列表中是否有這個位置private bool HasThePosition(Vector3 createPos){for(int i=0;i<itemPositionList.Count;i++){if(createPos==itemPositionList[i]){return true;}}return false;}//產生敵人的方法private void CreateEnemy(){int num = Random.Range(0, 3);Vector3 EnemyPos = new Vector3();if(num==0){EnemyPos = new Vector3(-10, 8, 0);}else if(num==1){EnemyPos = new Vector3(0, 8, 0);}else{EnemyPos = new Vector3(10, 8, 0);}CreateItem(item[3],EnemyPos,Quaternion.identity);}} MapCreation.cs 初始化地圖

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Born : MonoBehaviour {public GameObject playerPrefab;public GameObject[] enemyPrefabList;//判斷是否產生敵人public bool createPlay;// Use this for initializationvoid Start () {Invoke("BornTank",1f);Destroy(gameObject,1f);}private void Update(){}private void BornTank(){if (createPlay){Instantiate(playerPrefab, transform.position, Quaternion.identity);}else{int num = Random.Range(0, 2);Instantiate(enemyPrefabList[num], transform.position, Quaternion.identity);}} } Born.cs 玩家敵人坦克出生

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Enemy : MonoBehaviour {//屬性值public float moveSpeed = 3;private Vector3 bullectEulerAugles;private float v=-1;private float h;//引用private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左public GameObject bullectPrefab;public GameObject explosionPrefab;//計時器public float timeVal;public float timeValChangeDirection=0;// Use this for initializationvoid Start(){sr = GetComponent<SpriteRenderer>();}// Update is called once per framevoid Update(){//攻擊的時間間隔if (timeVal >= 0.3f){//間隔大于0.4的時候才有攻擊效果 Attack();}else{timeVal += Time.deltaTime;}}private void FixedUpdate(){Move();}//坦克的攻擊方法private void Attack(){//子彈參數的角度:當前坦克的角度+子彈應該旋轉的角度Instantiate(bullectPrefab, transform.position, Quaternion.Euler(transform.eulerAngles + bullectEulerAugles));timeVal = 0;}//坦克的移動方法private void Move(){if(timeValChangeDirection>=4){int num = Random.Range(0,8);if(num>5){v = -1;h = 0;}else if (num == 0){v = 1;h = 0;}else if (num > 0 && num <= 2){h = -1;v = 0;}else if (num > 2 && num <= 4){h = 1;v = 0;}timeValChangeDirection = 0;}else{timeValChangeDirection += Time.fixedDeltaTime;}//監聽玩家垂直軸輸入 transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v < 0){sr.sprite = tankSprite[2];bullectEulerAugles = new Vector3(0, 0, -180);}else if (v > 0){sr.sprite = tankSprite[0];bullectEulerAugles = new Vector3(0, 0, 0);}if (v != 0){return;}//監聽玩家水平軸輸入 transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World);if (h < 0){sr.sprite = tankSprite[3];bullectEulerAugles = new Vector3(0, 0, 90);}else if (h > 0){sr.sprite = tankSprite[1];bullectEulerAugles = new Vector3(0, 0, -90);}}//坦克的死亡方法private void Die(){PlayerManager.Instance.playerScore++;//產生爆炸特效 Instantiate(explosionPrefab, transform.position, transform.rotation);//死亡 Destroy(gameObject);}//優化敵人AIprivate void OnCollisionEnter2D(Collision2D collision){if(collision.gameObject.tag=="Enemy"){timeValChangeDirection = 4;}}} Enemy.cs 敵人坦克

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Explosion : MonoBehaviour {// Use this for initializationvoid Start () {//坦克銷毀后0.167秒銷毀爆炸特效Destroy(gameObject,0.167f);}// Update is called once per framevoid Update () {} } Explosion.cs 游戲銷毀特效

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Heart : MonoBehaviour {private SpriteRenderer sr;public GameObject explosionPrefab;public Sprite BrokenSprite; // Use this for initializationvoid Start () {sr = GetComponent<SpriteRenderer>();}private void Die(){sr.sprite = BrokenSprite;Instantiate(explosionPrefab,transform.position,transform.rotation);PlayerManager.Instance.isDefeat = true;} } Heart.cs 心臟

?

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement;public class Bullect : MonoBehaviour {public float moveSpeed = 10;public bool isPlayerBullect;// Use this for initializationvoid Start () {}// Update is called once per framevoid Update () {transform.Translate(transform.up*moveSpeed*Time.deltaTime,Space.World);}//子彈觸發碰撞檢測private void OnTriggerEnter2D(Collider2D collision){switch(collision.tag){case "Tank":if(!isPlayerBullect){collision.SendMessage("Die");Destroy(gameObject);}break;case "Heart":collision.SendMessage("Die");Destroy(gameObject);SceneManager.LoadScene("Game");break;case "Enemy":if(isPlayerBullect){collision.SendMessage("Die");Destroy(gameObject);}break;case "Wall"://銷毀自身和墻 Destroy(collision.gameObject);Destroy(gameObject);break;case "Barrier":Destroy(gameObject);break;default:break;}}} Bullect.cs 子彈

?

轉載于:https://www.cnblogs.com/1138720556Gary/p/9795316.html

總結

以上是生活随笔為你收集整理的Unity3D_(游戏)2D坦克大战 像素版的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。