• 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 initialization
        void Start () {
            
        }
        
        // Update is called once per frame
        void Update () {
            //监听玩家水平轴输入
            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);
        }
    }
    Player.cs

    控制图片的移动和切换

      制作坦克渲染

      添加精灵数组的引用

        private SpriteRenderer sr;
        public Sprite[] tankSprite;

    (上 右 下 左)

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

    //监听玩家水平轴输入
            float h = Input.GetAxisRaw("Horizontal");    //返回-1 0 1
            transform.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 initialization
        void Start () {
            sr = GetComponent<SpriteRenderer>();
        }
        
        // Update is called once per frame
        void Update () {
            //监听玩家水平轴输入
            float h = Input.GetAxisRaw("Horizontal");    //返回-1 0 1
            transform.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 1
            transform.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 initialization
        void Start () {
            sr = GetComponent<SpriteRenderer>();
        }
        
        // Update is called once per frame
        void Update () {
            //监听玩家水平轴输入
            float h = Input.GetAxisRaw("Horizontal");    //返回-1 0 1
            transform.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 1
            transform.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 initialization
        void Start () {
            sr = GetComponent<SpriteRenderer>();
        }
        
        // Update is called once per frame
        void 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 1
            transform.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 initialization
        void Start () {
            sr = GetComponent<SpriteRenderer>();
        }
        
        // Update is called once per frame
        void 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 1
            transform.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 initialization
        void Start () {
            
        }
        
        // Update is called once per frame
        void Update () {
            //监听玩家水平轴输入
            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);
        }
    }
    Player.cs

    控制图片的移动和切换

      制作坦克渲染

      添加精灵数组的引用

        private SpriteRenderer sr;
        public Sprite[] tankSprite;

    (上 右 下 左)

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

    //监听玩家水平轴输入
            float h = Input.GetAxisRaw("Horizontal");    //返回-1 0 1
            transform.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 initialization
        void Start () {
            sr = GetComponent<SpriteRenderer>();
        }
        
        // Update is called once per frame
        void Update () {
            //监听玩家水平轴输入
            float h = Input.GetAxisRaw("Horizontal");    //返回-1 0 1
            transform.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 1
            transform.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 initialization
        void Start () {
            sr = GetComponent<SpriteRenderer>();
        }
        
        // Update is called once per frame
        void Update () {
            //监听玩家水平轴输入
            float h = Input.GetAxisRaw("Horizontal");    //返回-1 0 1
            transform.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 1
            transform.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 initialization
        void Start () {
            sr = GetComponent<SpriteRenderer>();
        }
        
        // Update is called once per frame
        void 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 1
            transform.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 initialization
        void Start () {
            sr = GetComponent<SpriteRenderer>();
        }
        
        // Update is called once per frame
        void 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 1
            transform.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 initialization
        void Start () {
            sr = GetComponent<SpriteRenderer>();
        }

      添加Heart.cs心脏死亡时方法

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

      添加Explosion.cs脚本

      当坦克销毁时触发脚本

    public class Explosion : MonoBehaviour {
    
        // Use this for initialization
        void Start () {
            //坦克销毁后0.167秒销毁爆炸特效
            Destroy(gameObject,0.167f);
        }
        
        // Update is called once per frame
        void 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 initialization
        void Start () {
            sr = GetComponent<SpriteRenderer>();
        }
        
        // Update is called once per frame
        void Update () {
            //保护是否处于无敌状态
            if(isDefended)
            {
                defendEffectPrefab.SetActive(true);
                defendTimeVal -= Time.deltaTime;
                if (defendTimeVal<=0)
                {
                    isDefended = false;
                    defendEffectPrefab.SetActive(false);
                }
            }
    
            //攻击的CD
            if (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 1
            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()
        {
            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 initialization
        void Start () {
            //坦克销毁后0.167秒销毁爆炸特效
            Destroy(gameObject,0.167f);
        }
        
        // Update is called once per frame
        void 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 initialization
        void 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 initialization
        void Start () {
            
        }
        
        // Update is called once per frame
        void 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 initialization
        void Start()
        {
            sr = GetComponent<SpriteRenderer>();
        }
    
        // Update is called once per frame
        void Update()
        {
            //保护是否处于无敌状态
            if (isDefended)
            {
                defendEffectPrefab.SetActive(true);
                defendTimeVal -= Time.deltaTime;
                if (defendTimeVal <= 0)
                {
                    isDefended = false;
                    defendEffectPrefab.SetActive(false);
                }
            }
    
            //攻击的CD
            if (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 1
            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()
        {
            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 initialization
        void 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 initialization
        void Start () {
            Invoke("BornTank",0.8f);
            Destroy(gameObject,0.8f);
        }
        
        // Update is called once per frame
        void 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 initialization
        void 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 initialization
        void Start()
        {
            sr = GetComponent<SpriteRenderer>();
        }
    
        // Update is called once per frame
        void 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 initialization
        void Start () {
            
        }
        
        // Update is called once per frame
        void 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 initialization
        void Start () {
            
        }
        
        // Update is called once per frame
        void 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 initialization
        void Start () {
            sr = GetComponent<SpriteRenderer>();
        }
        
        // Update is called once per frame
        void Update () {
            //保护是否处于无敌状态
            if(isDefended)
            {
                defendEffectPrefab.SetActive(true);
                defendTimeVal -= Time.deltaTime;
                if (defendTimeVal<=0)
                {
                    isDefended = false;
                    defendEffectPrefab.SetActive(false);
                }
            }
    
            //攻击的CD
            if (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 1
            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()
        {
            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 initialization
        void 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 initialization
        void Start()
        {
            sr = GetComponent<SpriteRenderer>();
        }
    
        // Update is called once per frame
        void 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);
        }
    
        //优化敌人AI
        private 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 initialization
        void Start () {
            //坦克销毁后0.167秒销毁爆炸特效
            Destroy(gameObject,0.167f);
        }
        
        // Update is called once per frame
        void 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 initialization
        void 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 initialization
        void Start () {
            
        }
        
        // Update is called once per frame
        void 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 initialization
        void Start () {
            sr = GetComponent<SpriteRenderer>();
        }
        
        // Update is called once per frame
        void 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();
            //攻击的CD
            if (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 1
            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()
        {
            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 initialization
        void Start () {
            
        }
        
        // Update is called once per frame
        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;
            }
        }
    }
    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 initialization
        void 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 initialization
        void Start()
        {
            sr = GetComponent<SpriteRenderer>();
        }
    
        // Update is called once per frame
        void 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);
        }
    
        //优化敌人AI
        private 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 initialization
        void Start () {
            //坦克销毁后0.167秒销毁爆炸特效
            Destroy(gameObject,0.167f);
        }
        
        // Update is called once per frame
        void 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 initialization
        void 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 initialization
        void Start () {
            
        }
        
        // Update is called once per frame
        void 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 子弹
    (如需转载学习,请标明出处)
  • 相关阅读:
    websocket+nodejs+redis实现消息订阅和发布系统
    nodejs下载图片到本地,根据百度图片查找相应的图片,通过nodejs保存到本地文件夹
    基于vue 2.X和高德地图的vue-amap组件获取经纬度
    获取Class对象的三种方式
    java中的回调机制的理解(小例子)
    URL和URI的区别
    java web开发中各类地址的写法
    ListView性能
    Android中的Handler, Looper, MessageQueue和Thread对应关系
    java几种常用的算法
  • 原文地址:https://www.cnblogs.com/1138720556Gary/p/9795316.html
Copyright © 2020-2023  润新知