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 子弹

 

posted @ 2018-10-24 01:31  Cynical丶Gary  阅读(2863)  评论(0编辑  收藏  举报