河北通信建设有限公司网站,假网页生成器,网站建设是什么行业,网站开发实例2D坦克大战 像素版 游戏规则#xff1a; 玩家通过上、下、左、右移动坦克#xff0c;空格键发射子弹 敌人AI出身时朝向己方大本营(未防止游戏快速结束#xff0c;心脏上方三个单位障碍物设为刚体) 当玩家被击杀次数3 或 心脏被子弹击穿 重新加载游戏… 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 1transform.Translate(Vector3.right*h*moveSpeed*Time.deltaTime,Space.World); 监听玩家垂直轴输入 float v Input.GetAxisRaw(Vertical);transform.Translate(Vector3.up * v * moveSpeed * Time.deltaTime, Space.World); using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Player : MonoBehaviour {public float moveSpeed 3;// Use this for initializationvoid Start () {}// Update is called once per framevoid Update () {//监听玩家水平轴输入float h Input.GetAxisRaw(Horizontal); //返回-1 0 1transform.Translate(Vector3.right*h*moveSpeed*Time.deltaTime,Space.World);//监听玩家垂直轴输入float v Input.GetAxisRaw(Vertical);transform.Translate(Vector3.up * v * moveSpeed * Time.deltaTime, Space.World);}
} Player.cs 控制图片的移动和切换 制作坦克渲染 添加精灵数组的引用 private SpriteRenderer sr;public Sprite[] tankSprite; (上 右 下 左) 玩家按上下左右控制坦克方向的移动 //监听玩家水平轴输入float h Input.GetAxisRaw(Horizontal); //返回-1 0 1transform.Translate(Vector3.right*h*moveSpeed*Time.deltaTime,Space.World);if (h 0){sr.sprite tankSprite[3];}else if (h0){sr.sprite tankSprite[1];}//监听玩家垂直轴输入float v Input.GetAxisRaw(Vertical);transform.Translate(Vector3.up * v * moveSpeed * Time.deltaTime, Space.World);if (v 0){sr.sprite tankSprite[2];}else if (v 0){sr.sprite tankSprite[0];} using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Player : MonoBehaviour {public float moveSpeed 3;private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左// Use this for initializationvoid Start () {sr GetComponentSpriteRenderer();}// Update is called once per framevoid Update () {//监听玩家水平轴输入float h Input.GetAxisRaw(Horizontal); //返回-1 0 1transform.Translate(Vector3.right*h*moveSpeed*Time.deltaTime,Space.World);if (h 0){sr.sprite tankSprite[3];}else if (h0){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中操作比如ForceColliderRigidbody等。外设的操作也是比如说键盘或者鼠标的输入输出Input因为这样GameObject的物理表现的更平滑更接近现实。FixedUpdate的时间间隔可以在项目设置中更改Edit-Project Setting-time 找到Fixed timestep。就可以修改了 FixedUpdate () 和 Update () //监听玩家水平轴输入float h Input.GetAxisRaw(Horizontal); //返回-1 0 1transform.Translate(Vector3.right*h*moveSpeed*Time.fixedDeltaTime,Space.World);//监听玩家垂直轴输入float v Input.GetAxisRaw(Vertical);transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World); FixedUpdate()方法留空就行 private void FixedUpdate(){} using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Player : MonoBehaviour {public float moveSpeed 3;private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左// Use this for initializationvoid Start () {sr GetComponentSpriteRenderer();}// Update is called once per framevoid Update () {//监听玩家水平轴输入float h Input.GetAxisRaw(Horizontal); //返回-1 0 1transform.Translate(Vector3.right*h*moveSpeed*Time.fixedDeltaTime,Space.World);if (h 0){sr.sprite tankSprite[3];}else if (h0){sr.sprite tankSprite[1];}//监听玩家垂直轴输入float v Input.GetAxisRaw(Vertical);transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v 0){sr.sprite tankSprite[2];}else if (v 0){sr.sprite tankSprite[0];}}//private void FixedUpdate(){}
} Player.cs 解决玩家按方向键左右的同时按上下 在监听玩家垂直轴输入后对v方向按键进行判断如果为0则在Update()中直接返回 float v Input.GetAxisRaw(Vertical);transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v 0){sr.sprite tankSprite[2];}else if (v 0){sr.sprite tankSprite[0];}if(v!0){return;}//监听玩家水平轴输入float h Input.GetAxisRaw(Horizontal); //返回-1 0 1transform.Translate(Vector3.right*h*moveSpeed*Time.fixedDeltaTime,Space.World);if (h 0){sr.sprite tankSprite[3];}else if (h0){sr.sprite tankSprite[1];} 整理一下Player.cs脚本 using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Player : MonoBehaviour {//属性值public float moveSpeed 3;//引用private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左// Use this for initializationvoid Start () {sr GetComponentSpriteRenderer();}// Update is called once per framevoid Update () {}private void FixedUpdate(){Move();}//坦克的移动方法private void Move(){//监听玩家垂直轴输入float v Input.GetAxisRaw(Vertical);transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v 0){sr.sprite tankSprite[2];}else if (v 0){sr.sprite tankSprite[0];}if (v ! 0){return;}//监听玩家水平轴输入float h Input.GetAxisRaw(Horizontal); //返回-1 0 1transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World);if (h 0){sr.sprite tankSprite[3];}else if (h 0){sr.sprite tankSprite[1];}}
} Player.cs 2D渲染层级 设置游戏物体的层级 坦克的攻击 坦克的攻击方法 private void Attack(){if(Input.GetKeyDown(KeyCode.Space)){Instantiate(bullectPrefab,transform.position,transform.rotation);}} private void FixedUpdate(){Move();Attack();} using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Player : MonoBehaviour {//属性值public float moveSpeed 3;//引用private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左public GameObject bullectPrefab;// Use this for initializationvoid Start () {sr GetComponentSpriteRenderer();}// Update is called once per framevoid Update () {}private void FixedUpdate(){Move();Attack();}//坦克的攻击方法private void Attack(){if(Input.GetKeyDown(KeyCode.Space)){Instantiate(bullectPrefab,transform.position,transform.rotation);}}//坦克的移动方法private void Move(){//监听玩家垂直轴输入float v Input.GetAxisRaw(Vertical);transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v 0){sr.sprite tankSprite[2];}else if (v 0){sr.sprite tankSprite[0];}if (v ! 0){return;}//监听玩家水平轴输入float h Input.GetAxisRaw(Horizontal); //返回-1 0 1transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World);if (h 0){sr.sprite tankSprite[3];}else if (h 0){sr.sprite tankSprite[1];}}
} player.cs 子弹的朝向和移动 通过按键V和H来判断子弹旋转的角度 定义子弹旋转的角度 private Vector3 bullectEulerAugles; 子弹参数的角度当前坦克的角度子弹应该旋转的角度 Instantiate(bullectPrefab,transform.position,Quaternion.Euler(transform.eulerAnglesbullectEulerAugles)); ---恢复内容结束--- 未完~ 完成时会有完整项目展示 场景搭建 设置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 1transform.Translate(Vector3.right*h*moveSpeed*Time.deltaTime,Space.World); 监听玩家垂直轴输入 float v Input.GetAxisRaw(Vertical);transform.Translate(Vector3.up * v * moveSpeed * Time.deltaTime, Space.World); using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Player : MonoBehaviour {public float moveSpeed 3;// Use this for initializationvoid Start () {}// Update is called once per framevoid Update () {//监听玩家水平轴输入float h Input.GetAxisRaw(Horizontal); //返回-1 0 1transform.Translate(Vector3.right*h*moveSpeed*Time.deltaTime,Space.World);//监听玩家垂直轴输入float v Input.GetAxisRaw(Vertical);transform.Translate(Vector3.up * v * moveSpeed * Time.deltaTime, Space.World);}
} Player.cs 控制图片的移动和切换 制作坦克渲染 添加精灵数组的引用 private SpriteRenderer sr;public Sprite[] tankSprite; (上 右 下 左) 玩家按上下左右控制坦克方向的移动 //监听玩家水平轴输入float h Input.GetAxisRaw(Horizontal); //返回-1 0 1transform.Translate(Vector3.right*h*moveSpeed*Time.deltaTime,Space.World);if (h 0){sr.sprite tankSprite[3];}else if (h0){sr.sprite tankSprite[1];}//监听玩家垂直轴输入float v Input.GetAxisRaw(Vertical);transform.Translate(Vector3.up * v * moveSpeed * Time.deltaTime, Space.World);if (v 0){sr.sprite tankSprite[2];}else if (v 0){sr.sprite tankSprite[0];} using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Player : MonoBehaviour {public float moveSpeed 3;private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左// Use this for initializationvoid Start () {sr GetComponentSpriteRenderer();}// Update is called once per framevoid Update () {//监听玩家水平轴输入float h Input.GetAxisRaw(Horizontal); //返回-1 0 1transform.Translate(Vector3.right*h*moveSpeed*Time.deltaTime,Space.World);if (h 0){sr.sprite tankSprite[3];}else if (h0){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中操作比如ForceColliderRigidbody等。外设的操作也是比如说键盘或者鼠标的输入输出Input因为这样GameObject的物理表现的更平滑更接近现实。FixedUpdate的时间间隔可以在项目设置中更改Edit-Project Setting-time 找到Fixed timestep。就可以修改了 FixedUpdate () 和 Update () //监听玩家水平轴输入float h Input.GetAxisRaw(Horizontal); //返回-1 0 1transform.Translate(Vector3.right*h*moveSpeed*Time.fixedDeltaTime,Space.World);//监听玩家垂直轴输入float v Input.GetAxisRaw(Vertical);transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World); FixedUpdate()方法留空就行 private void FixedUpdate(){} using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Player : MonoBehaviour {public float moveSpeed 3;private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左// Use this for initializationvoid Start () {sr GetComponentSpriteRenderer();}// Update is called once per framevoid Update () {//监听玩家水平轴输入float h Input.GetAxisRaw(Horizontal); //返回-1 0 1transform.Translate(Vector3.right*h*moveSpeed*Time.fixedDeltaTime,Space.World);if (h 0){sr.sprite tankSprite[3];}else if (h0){sr.sprite tankSprite[1];}//监听玩家垂直轴输入float v Input.GetAxisRaw(Vertical);transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v 0){sr.sprite tankSprite[2];}else if (v 0){sr.sprite tankSprite[0];}}//private void FixedUpdate(){}
} Player.cs 解决玩家按方向键左右的同时按上下 在监听玩家垂直轴输入后对v方向按键进行判断如果为0则在Update()中直接返回 float v Input.GetAxisRaw(Vertical);transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v 0){sr.sprite tankSprite[2];}else if (v 0){sr.sprite tankSprite[0];}if(v!0){return;}//监听玩家水平轴输入float h Input.GetAxisRaw(Horizontal); //返回-1 0 1transform.Translate(Vector3.right*h*moveSpeed*Time.fixedDeltaTime,Space.World);if (h 0){sr.sprite tankSprite[3];}else if (h0){sr.sprite tankSprite[1];} 整理一下Player.cs脚本 using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Player : MonoBehaviour {//属性值public float moveSpeed 3;//引用private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左// Use this for initializationvoid Start () {sr GetComponentSpriteRenderer();}// Update is called once per framevoid Update () {}private void FixedUpdate(){Move();}//坦克的移动方法private void Move(){//监听玩家垂直轴输入float v Input.GetAxisRaw(Vertical);transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v 0){sr.sprite tankSprite[2];}else if (v 0){sr.sprite tankSprite[0];}if (v ! 0){return;}//监听玩家水平轴输入float h Input.GetAxisRaw(Horizontal); //返回-1 0 1transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World);if (h 0){sr.sprite tankSprite[3];}else if (h 0){sr.sprite tankSprite[1];}}
} Player.cs 2D渲染层级 设置游戏物体的层级 坦克的攻击 坦克的攻击方法 private void Attack(){if(Input.GetKeyDown(KeyCode.Space)){Instantiate(bullectPrefab,transform.position,transform.rotation);}} private void FixedUpdate(){Move();Attack();} using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Player : MonoBehaviour {//属性值public float moveSpeed 3;//引用private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左public GameObject bullectPrefab;// Use this for initializationvoid Start () {sr GetComponentSpriteRenderer();}// Update is called once per framevoid Update () {}private void FixedUpdate(){Move();Attack();}//坦克的攻击方法private void Attack(){if(Input.GetKeyDown(KeyCode.Space)){Instantiate(bullectPrefab,transform.position,transform.rotation);}}//坦克的移动方法private void Move(){//监听玩家垂直轴输入float v Input.GetAxisRaw(Vertical);transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v 0){sr.sprite tankSprite[2];}else if (v 0){sr.sprite tankSprite[0];}if (v ! 0){return;}//监听玩家水平轴输入float h Input.GetAxisRaw(Horizontal); //返回-1 0 1transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World);if (h 0){sr.sprite tankSprite[3];}else if (h 0){sr.sprite tankSprite[1];}}
} player.cs 子弹的朝向和移动 通过按键V和H来判断子弹旋转的角度 定义子弹旋转的角度 private Vector3 bullectEulerAugles; 子弹参数的角度当前坦克的角度子弹应该旋转的角度 Instantiate(bullectPrefab,transform.position,Quaternion.Euler(transform.eulerAnglesbullectEulerAugles)); private void Attack(){if(Input.GetKeyDown(KeyCode.Space)){//子弹参数的角度当前坦克的角度子弹应该旋转的角度Instantiate(bullectPrefab,transform.position,Quaternion.Euler(transform.eulerAnglesbullectEulerAugles));timeVal 0;}} 给子弹添加方向速度 public float moveSpeed 10; 给子弹添加判断是否是友军 public bool isPlayerBullect; void Update () {transform.Translate(transform.up*moveSpeed*Time.deltaTime,Space.World);} 添加子弹攻击CD间隔 if (timeVal0.4f){//间隔大于0.4的时候才有攻击效果Attack();}else{timeVal Time.deltaTime;} 给组件添加标签 给子弹添加碰撞体和触发器 添加Heart.cs脚本当Heart心脏被子弹攻击时切换死亡图片 private SpriteRenderer sr;public Sprite BrokenSprite; // Use this for initializationvoid Start () {sr GetComponentSpriteRenderer();} 添加Heart.cs心脏死亡时方法 private void Die(){sr.sprite BrokenSprite; } 添加Explosion.cs脚本 当坦克销毁时触发脚本 public class Explosion : MonoBehaviour {// Use this for initializationvoid Start () {//坦克销毁后0.167秒销毁爆炸特效Destroy(gameObject,0.167f);}// Update is called once per framevoid Update () {}
} 子弹触发碰撞检测 当子弹碰撞到物体时触发OnTriggerEnter2D(Collider2D collision)方法 子弹碰到“Tank”判断是否是友军不是的话击毁自己 子弹碰到Wall时销毁子弹自身 子弹碰到Heart时触发基地死亡方法 子弹碰到Barrier刚体时销毁子弹 private void OnTriggerEnter2D(Collider2D collision){switch(collision.tag){case Tank:if(!isPlayerBullect){collision.SendMessage(Die);}break;case Heart:collision.SendMessage(Die);Destroy(gameObject);break;case Enemy:break;case Wall://销毁自身和墙Destroy(collision.gameObject);Destroy(gameObject);break;case Barrier:Destroy(gameObject);break;default:break;}} using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Player : MonoBehaviour {//属性值public float moveSpeed 3;private Vector3 bullectEulerAugles;public float timeVal;private float defendTimeVal1;private bool isDefendedtrue;//引用private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左public GameObject bullectPrefab;public GameObject explosionPrefab;public GameObject defendEffectPrefab;// Use this for initializationvoid Start () {sr GetComponentSpriteRenderer();}// Update is called once per framevoid Update () {//保护是否处于无敌状态if(isDefended){defendEffectPrefab.SetActive(true);defendTimeVal - Time.deltaTime;if (defendTimeVal0){isDefended false;defendEffectPrefab.SetActive(false);}}//攻击的CDif (timeVal0.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.eulerAnglesbullectEulerAugles));timeVal 0;}}//坦克的移动方法private void Move(){//监听玩家垂直轴输入float v Input.GetAxisRaw(Vertical);transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v 0){sr.sprite tankSprite[2];bullectEulerAugles new Vector3(0, 0, -180);}else if (v 0){sr.sprite tankSprite[0];bullectEulerAugles new Vector3(0, 0, 0);}if (v ! 0){return;}//监听玩家水平轴输入float h Input.GetAxisRaw(Horizontal); //返回-1 0 1transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World);if (h 0){sr.sprite tankSprite[3];bullectEulerAugles new Vector3(0, 0, 90);}else if (h 0){sr.sprite tankSprite[1];bullectEulerAugles new Vector3(0, 0, -90);}}//坦克的死亡方法private void Die(){if(isDefended){return;}//产生爆炸特效Instantiate(explosionPrefab, transform.position, transform.rotation);//死亡Destroy(gameObject);}
} Player.cs using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Explosion : MonoBehaviour {// Use this for initializationvoid Start () {//坦克销毁后0.167秒销毁爆炸特效Destroy(gameObject,0.167f);}// Update is called once per framevoid Update () {}
} Explosion.cs using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Heart : MonoBehaviour {private SpriteRenderer sr;public Sprite BrokenSprite; // Use this for initializationvoid Start () {sr GetComponentSpriteRenderer();}private void Die(){sr.sprite BrokenSprite; }
} Heart using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Bullect : MonoBehaviour {public float moveSpeed 10;public bool isPlayerBullect;// Use this for initializationvoid Start () {}// Update is called once per framevoid Update () {transform.Translate(transform.up*moveSpeed*Time.deltaTime,Space.World);}//子弹触发碰撞检测private void OnTriggerEnter2D(Collider2D collision){switch(collision.tag){case Tank:if(!isPlayerBullect){collision.SendMessage(Die);}break;case Heart:collision.SendMessage(Die);Destroy(gameObject);break;case Enemy:break;case Wall://销毁自身和墙Destroy(collision.gameObject);Destroy(gameObject);break;case Barrier:Destroy(gameObject);break;default:break;}}} Bullect.cs 敌人的制作 CtrlD一份玩家修改图片渲染制作敌人 添加敌人脚本Enemy.cs 玩家的移动和敌人的移动差不多把Player.cs脚本中内容复制到Enemy.cs当中 using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Enemy : MonoBehaviour {//属性值public float moveSpeed 3;private Vector3 bullectEulerAugles;public float timeVal;private float defendTimeVal 1;private bool isDefended true;//引用private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左public GameObject bullectPrefab;public GameObject explosionPrefab;public GameObject defendEffectPrefab;// Use this for initializationvoid Start(){sr GetComponentSpriteRenderer();}// Update is called once per framevoid Update(){//保护是否处于无敌状态if (isDefended){defendEffectPrefab.SetActive(true);defendTimeVal - Time.deltaTime;if (defendTimeVal 0){isDefended false;defendEffectPrefab.SetActive(false);}}//攻击的CDif (timeVal 0.4f){//间隔大于0.4的时候才有攻击效果Attack();}else{timeVal Time.deltaTime;}}private void FixedUpdate(){Move();}//坦克的攻击方法private void Attack(){if (Input.GetKeyDown(KeyCode.Space)){//子弹参数的角度当前坦克的角度子弹应该旋转的角度Instantiate(bullectPrefab, transform.position, Quaternion.Euler(transform.eulerAngles bullectEulerAugles));timeVal 0;}}//坦克的移动方法private void Move(){//监听玩家垂直轴输入float v Input.GetAxisRaw(Vertical);transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v 0){sr.sprite tankSprite[2];bullectEulerAugles new Vector3(0, 0, -180);}else if (v 0){sr.sprite tankSprite[0];bullectEulerAugles new Vector3(0, 0, 0);}if (v ! 0){return;}//监听玩家水平轴输入float h Input.GetAxisRaw(Horizontal); //返回-1 0 1transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World);if (h 0){sr.sprite tankSprite[3];bullectEulerAugles new Vector3(0, 0, 90);}else if (h 0){sr.sprite tankSprite[1];bullectEulerAugles new Vector3(0, 0, -90);}}//坦克的死亡方法private void Die(){if (isDefended){return;}//产生爆炸特效Instantiate(explosionPrefab, transform.position, transform.rotation);//死亡Destroy(gameObject);}
} Enemy.cs (因为敌人没有出生无敌3s,运行时无敌预制体defendEffectPrefab会出现报空) 添加基地死亡时动画 public GameObject explosionPrefab; private void Die(){sr.sprite BrokenSprite;Instantiate(explosionPrefab,transform.position,transform.rotation);} (关闭项目后爆炸脚本失活了最后的时候再做一个补上) 添加一个玩家出生时脚本Born.cs 延时玩家出生和死亡动画 public GameObject playerPrefab;// Use this for initializationvoid Start () {Invoke(BornTank,1f);Destroy(gameObject,1f);}private void BornTank(){Instantiate(playerPrefab,transform.position,Quaternion.identity);} using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Born : MonoBehaviour {public GameObject playerPrefab;// Use this for initializationvoid Start () {Invoke(BornTank,0.8f);Destroy(gameObject,0.8f);}// Update is called once per framevoid Update () {}private void BornTank(){Instantiate(playerPrefab,transform.position,Quaternion.identity);}
} Born.cs 制作大坦克和小坦克添加坦克方向变化时改变坦克方向图片 坦克改变方向顺序按上、右、下、左进行添加 小敌人同打敌人设置当坦克方向改变时切换自身图片 将大敌人和小敌人设置成预制体 小敌人速度调大一些改为5 编写Born.cs脚本判断是否产生敌人 public bool createPlay; private void BornTank(){if (createPlay){Instantiate(playerPrefab, transform.position, Quaternion.identity);}else{int num Random.Range(0, 2);Instantiate(enemyPrefabList[num], transform.position, Quaternion.identity);}} using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Born : MonoBehaviour {public GameObject playerPrefab;public GameObject[] enemyPrefabList;//判断是否产生敌人public bool createPlay;// Use this for initializationvoid Start () {Invoke(BornTank,1f);Destroy(gameObject,1f);}private void Update(){}private void BornTank(){if (createPlay){Instantiate(playerPrefab, transform.position, Quaternion.identity);}else{int num Random.Range(0, 2);Instantiate(enemyPrefabList[num], transform.position, Quaternion.identity);}}
} Born.cs 编写敌人AI 子弹间3s攻击一次 void Update(){//攻击的时间间隔if (timeVal 0.3f){//间隔大于0.4的时候才有攻击效果Attack();}else{timeVal Time.deltaTime;}} //坦克的攻击方法private void Attack(){//子弹参数的角度当前坦克的角度子弹应该旋转的角度Instantiate(bullectPrefab, transform.position, Quaternion.Euler(transform.eulerAngles bullectEulerAugles));timeVal 0;} 坦克的移动不需要按下上下左右键盘只需要管理V和H的值对敌人AI进行方向的控制 定义两个计时器 public float timeVal;public float timeValChangeDirection; 修改敌人移动的方法 private void Move(){if(timeValChangeDirection4){int num Random.Range(0,8);if(num5){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 timeValChangeDirection4;// Use this for initializationvoid Start(){sr GetComponentSpriteRenderer();}// Update is called once per framevoid Update(){//攻击的时间间隔if (timeVal 0.3f){//间隔大于0.4的时候才有攻击效果Attack();}else{timeVal Time.deltaTime;}}private void FixedUpdate(){Move();}//坦克的攻击方法private void Attack(){//子弹参数的角度当前坦克的角度子弹应该旋转的角度Instantiate(bullectPrefab, transform.position, Quaternion.Euler(transform.eulerAngles bullectEulerAugles));timeVal 0;}//坦克的移动方法private void Move(){if(timeValChangeDirection4){int num Random.Range(0,8);if(num5){v -1;h 0;}else if (num 0){v 1;h 0;}else if (num 0 num 2){h -1;v 0;}else if (num 2 num 4){h 1;v 0;}timeValChangeDirection 0;}else{timeValChangeDirection Time.fixedDeltaTime;}//监听玩家垂直轴输入transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v 0){sr.sprite tankSprite[2];bullectEulerAugles new Vector3(0, 0, -180);}else if (v 0){sr.sprite tankSprite[0];bullectEulerAugles new Vector3(0, 0, 0);}if (v ! 0){return;}//监听玩家水平轴输入transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World);if (h 0){sr.sprite tankSprite[3];bullectEulerAugles new Vector3(0, 0, 90);}else if (h 0){sr.sprite tankSprite[1];bullectEulerAugles new Vector3(0, 0, -90);}}//坦克的死亡方法private void Die(){//产生爆炸特效Instantiate(explosionPrefab, transform.position, transform.rotation);//死亡Destroy(gameObject);}
} Enemy.cs using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Bullect : MonoBehaviour {public float moveSpeed 10;public bool isPlayerBullect;// Use this for initializationvoid Start () {}// Update is called once per framevoid Update () {transform.Translate(transform.up*moveSpeed*Time.deltaTime,Space.World);}//子弹触发碰撞检测private void OnTriggerEnter2D(Collider2D collision){switch(collision.tag){case Tank:if(!isPlayerBullect){collision.SendMessage(Die);}Destroy(gameObject);break;case Heart:collision.SendMessage(Die);Destroy(gameObject);break;case Enemy:if(isPlayerBullect){collision.SendMessage(Die);}Destroy(gameObject);break;case Wall://销毁自身和墙Destroy(collision.gameObject);Destroy(gameObject);break;case Barrier:Destroy(gameObject);break;default:break;}}} Bullect.cs 初始化地图工具 判断地图长度 地图大小长20 宽16 添加MapCreation.cs地图管理器来控制草和地图等建筑物 public class MapCreation : MonoBehaviour {//用来装饰初始化地图所需物体的数组//0.老家 1.墙 2.障碍 3.出生效果 4.河流 5.草 6.空气墙public GameObject[] item;} 制作老家心脏和心脏周围的围墙 private void Awake(){//实例化老家Instantiate(item[0], new Vector3(0, -8, -0), Quaternion.identity);//用墙把老家围起来Instantiate(item[1], new Vector3(-1, -8, -0), Quaternion.identity);Instantiate(item[1], new Vector3(1, -8, -0), Quaternion.identity);for(int i-1;i2;i){Instantiate(item[1],new Vector3(i,-7,0),Quaternion.identity);}} 对同一个位置上进行判断判断是否有障碍物在上面如果在上面那不再额外生成其它建筑物 已经有东西位置的列表 private ListVector3 itemPositionList new ListVector3(); 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;i12;i){CreateItem(item[6], new Vector3(i, 9, 0), Quaternion.identity);}for(int i-11;i12;i){CreateItem(item[6], new Vector3(i, -9, 0), Quaternion.identity);}for(int i-8;i9;i){CreateItem(item[6], new Vector3(-11, i, 0), Quaternion.identity);}for(int i-8;i9;i){CreateItem(item[6], new Vector3(-11, i, 0), Quaternion.identity);} 产生随机位置的方法 private Vector3 CreateRamdomPosition(){//不生成x-1010的两列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 i0;iitemPositionList.Count;i){if(createPositemPositionList[i]){return true;}}return false;} 修复子弹触发碰撞检测 private void OnTriggerEnter2D(Collider2D collision){switch(collision.tag){case Tank:if(!isPlayerBullect){collision.SendMessage(Die);Destroy(gameObject);}break;case Heart:collision.SendMessage(Die);Destroy(gameObject);break;case Enemy:if(isPlayerBullect){collision.SendMessage(Die);Destroy(gameObject);}break;case Wall://销毁自身和墙Destroy(collision.gameObject);Destroy(gameObject);break;case Barrier:Destroy(gameObject);break;default:break;}} using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Bullect : MonoBehaviour {public float moveSpeed 10;public bool isPlayerBullect;// Use this for initializationvoid Start () {}// Update is called once per framevoid Update () {transform.Translate(transform.up*moveSpeed*Time.deltaTime,Space.World);}//子弹触发碰撞检测private void OnTriggerEnter2D(Collider2D collision){switch(collision.tag){case Tank:if(!isPlayerBullect){collision.SendMessage(Die);Destroy(gameObject);}break;case Heart:collision.SendMessage(Die);Destroy(gameObject);break;case Enemy:if(isPlayerBullect){collision.SendMessage(Die);Destroy(gameObject);}break;case Wall://销毁自身和墙Destroy(collision.gameObject);Destroy(gameObject);break;case Barrier:Destroy(gameObject);break;default:break;}}} Bullect.cs 实例化地图 for(int i0;i20;i){CreateItem(item[1], CreateRamdomPosition(), Quaternion.identity);}for(int i0;i20;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.GetComponentBorn().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 i0;i60;i){CreateItem(item[1], CreateRamdomPosition(), Quaternion.identity);}for(int i0;i20;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(num0){EnemyPos new Vector3(-10, 8, 0);}else if(num1){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.tagEnemy){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 defendTimeVal3;private bool isDefendedtrue;//引用private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左public GameObject bullectPrefab;public GameObject explosionPrefab;public GameObject defendEffectPrefab;// Use this for initializationvoid Start () {sr GetComponentSpriteRenderer();}// Update is called once per framevoid Update () {//保护是否处于无敌状态if(isDefended){defendEffectPrefab.SetActive(true);defendTimeVal - Time.deltaTime;if (defendTimeVal0){isDefended false;defendEffectPrefab.SetActive(false);}}//攻击的CDif (timeVal0.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.eulerAnglesbullectEulerAugles));timeVal 0;}}//坦克的移动方法private void Move(){//监听玩家垂直轴输入float v Input.GetAxisRaw(Vertical);transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v 0){sr.sprite tankSprite[2];bullectEulerAugles new Vector3(0, 0, -180);}else if (v 0){sr.sprite tankSprite[0];bullectEulerAugles new Vector3(0, 0, 0);}if (v ! 0){return;}//监听玩家水平轴输入float h Input.GetAxisRaw(Horizontal); //返回-1 0 1transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World);if (h 0){sr.sprite tankSprite[3];bullectEulerAugles new Vector3(0, 0, 90);}else if (h 0){sr.sprite tankSprite[1];bullectEulerAugles new Vector3(0, 0, -90);}}//坦克的死亡方法private void Die(){if(isDefended){return;}//产生爆炸特效Instantiate(explosionPrefab, transform.position, transform.rotation);//死亡Destroy(gameObject);}
} Player.cs using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class MapCreation : MonoBehaviour {//用来装饰初始化地图所需物体的数组//0.老家 1.墙 2.障碍 3.出生效果 4.河流 5.草 6.空气墙public GameObject[] item;//已经有东西位置的列表private ListVector3 itemPositionList new ListVector3();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;i2;i){Instantiate(item[1],new Vector3(i,-7,0),Quaternion.identity);}//实例化外围墙for(int i-11;i12;i){CreateItem(item[6], new Vector3(i, 9, 0), Quaternion.identity);}for(int i-11;i12;i){CreateItem(item[6], new Vector3(i, -9, 0), Quaternion.identity);}for(int i-8;i9;i){CreateItem(item[6], new Vector3(-11, i, 0), Quaternion.identity);}for(int i-8;i9;i){CreateItem(item[6], new Vector3(11, i, 0), Quaternion.identity);}//初始化玩家GameObject go Instantiate(item[3], new Vector3(-2, -8, 0), Quaternion.identity);go.GetComponentBorn().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 i0;i60;i){CreateItem(item[1], CreateRamdomPosition(), Quaternion.identity);}for(int i0;i20;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-1010的两列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 i0;iitemPositionList.Count;i){if(createPositemPositionList[i]){return true;}}return false;}//产生敌人的方法private void CreateEnemy(){int num Random.Range(0, 3);Vector3 EnemyPos new Vector3();if(num0){EnemyPos new Vector3(-10, 8, 0);}else if(num1){EnemyPos new Vector3(0, 8, 0);}else{EnemyPos new Vector3(10, 8, 0);}CreateItem(item[3],EnemyPos,Quaternion.identity);}} MapCreation.cs using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Born : MonoBehaviour {public GameObject playerPrefab;public GameObject[] enemyPrefabList;//判断是否产生敌人public bool createPlay;// Use this for initializationvoid Start () {Invoke(BornTank,1f);Destroy(gameObject,1f);}private void Update(){}private void BornTank(){if (createPlay){Instantiate(playerPrefab, transform.position, Quaternion.identity);}else{int num Random.Range(0, 2);Instantiate(enemyPrefabList[num], transform.position, Quaternion.identity);}}
} Born.cs using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Enemy : MonoBehaviour {//属性值public float moveSpeed 3;private Vector3 bullectEulerAugles;private float v;private float h;//引用private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左public GameObject bullectPrefab;public GameObject explosionPrefab;//计时器public float timeVal;public float timeValChangeDirection4;// Use this for initializationvoid Start(){sr GetComponentSpriteRenderer();}// Update is called once per framevoid Update(){//攻击的时间间隔if (timeVal 0.3f){//间隔大于0.4的时候才有攻击效果Attack();}else{timeVal Time.deltaTime;}}private void FixedUpdate(){Move();}//坦克的攻击方法private void Attack(){//子弹参数的角度当前坦克的角度子弹应该旋转的角度Instantiate(bullectPrefab, transform.position, Quaternion.Euler(transform.eulerAngles bullectEulerAugles));timeVal 0;}//坦克的移动方法private void Move(){if(timeValChangeDirection4){int num Random.Range(0,8);if(num5){v -1;h 0;}else if (num 0){v 1;h 0;}else if (num 0 num 2){h -1;v 0;}else if (num 2 num 4){h 1;v 0;}timeValChangeDirection 0;}else{timeValChangeDirection Time.fixedDeltaTime;}//监听玩家垂直轴输入transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v 0){sr.sprite tankSprite[2];bullectEulerAugles new Vector3(0, 0, -180);}else if (v 0){sr.sprite tankSprite[0];bullectEulerAugles new Vector3(0, 0, 0);}if (v ! 0){return;}//监听玩家水平轴输入transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World);if (h 0){sr.sprite tankSprite[3];bullectEulerAugles new Vector3(0, 0, 90);}else if (h 0){sr.sprite tankSprite[1];bullectEulerAugles new Vector3(0, 0, -90);}}//坦克的死亡方法private void Die(){//产生爆炸特效Instantiate(explosionPrefab, transform.position, transform.rotation);//死亡Destroy(gameObject);}//优化敌人AIprivate void OnCollisionEnter2D(Collision2D collision){if(collision.gameObject.tagEnemy){timeValChangeDirection 4;}}} Enemy.cs using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Explosion : MonoBehaviour {// Use this for initializationvoid Start () {//坦克销毁后0.167秒销毁爆炸特效Destroy(gameObject,0.167f);}// Update is called once per framevoid Update () {}
} Explosion using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Heart : MonoBehaviour {private SpriteRenderer sr;public GameObject explosionPrefab;public Sprite BrokenSprite; // Use this for initializationvoid Start () {sr GetComponentSpriteRenderer();}private void Die(){sr.sprite BrokenSprite;Instantiate(explosionPrefab,transform.position,transform.rotation);}
} Heart.cs using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Bullect : MonoBehaviour {public float moveSpeed 10;public bool isPlayerBullect;// Use this for initializationvoid Start () {}// Update is called once per framevoid Update () {transform.Translate(transform.up*moveSpeed*Time.deltaTime,Space.World);}//子弹触发碰撞检测private void OnTriggerEnter2D(Collider2D collision){switch(collision.tag){case Tank:if(!isPlayerBullect){collision.SendMessage(Die);Destroy(gameObject);}break;case Heart:collision.SendMessage(Die);Destroy(gameObject);break;case Enemy:if(isPlayerBullect){collision.SendMessage(Die);Destroy(gameObject);}break;case Wall://销毁自身和墙Destroy(collision.gameObject);Destroy(gameObject);break;case Barrier:Destroy(gameObject);break;default:break;}}} Bullect.cs 玩家状态管理 游戏中添加空物体PlayerManager对象 添加游戏的属性值 public int lifeVale 3;public int playerScore 0;public bool isDead; 坦克的死亡方法 private void Die(){if(isDefended){return;}PlayerManager.Instance.isDead true;//产生爆炸特效Instantiate(explosionPrefab, transform.position, transform.rotation);//死亡Destroy(gameObject);} 玩家状态管理类监听玩家状态当玩家被子弹击中时生命值开始降低 void Update () {if(isDead){Recover();}}private void Recover(){if (lifeVale 0){//游戏失败返回主界面
SceneManager.LoadScene(Game);}else{lifeVale--;GameObject go Instantiate(born,new Vector3(-2,-8,0),Quaternion.identity);go.GetComponentBorn().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 defendTimeVal3;private bool isDefendedtrue;//引用private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左public GameObject bullectPrefab;public GameObject explosionPrefab;public GameObject defendEffectPrefab;// Use this for initializationvoid Start () {sr GetComponentSpriteRenderer();}// Update is called once per framevoid Update () {//保护是否处于无敌状态if(isDefended){defendEffectPrefab.SetActive(true);defendTimeVal - Time.deltaTime;if (defendTimeVal0){isDefended false;defendEffectPrefab.SetActive(false);}}}private void FixedUpdate(){if(PlayerManager.Instance.isDefeat){return;}Move();//攻击的CDif (timeVal 0.4f){//间隔大于0.4的时候才有攻击效果Attack();}else{timeVal Time.fixedDeltaTime;}}//坦克的攻击方法private void Attack(){if(Input.GetKeyDown(KeyCode.Space)){//子弹参数的角度当前坦克的角度子弹应该旋转的角度Instantiate(bullectPrefab,transform.position,Quaternion.Euler(transform.eulerAnglesbullectEulerAugles));timeVal 0;}}//坦克的移动方法private void Move(){//监听玩家垂直轴输入float v Input.GetAxisRaw(Vertical);transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v 0){sr.sprite tankSprite[2];bullectEulerAugles new Vector3(0, 0, -180);}else if (v 0){sr.sprite tankSprite[0];bullectEulerAugles new Vector3(0, 0, 0);}if (v ! 0){return;}//监听玩家水平轴输入float h Input.GetAxisRaw(Horizontal); //返回-1 0 1transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World);if (h 0){sr.sprite tankSprite[3];bullectEulerAugles new Vector3(0, 0, 90);}else if (h 0){sr.sprite tankSprite[1];bullectEulerAugles new Vector3(0, 0, -90);}}//坦克的死亡方法private void Die(){if(isDefended){return;}PlayerManager.Instance.isDead true;//产生爆炸特效Instantiate(explosionPrefab, transform.position, transform.rotation);//死亡Destroy(gameObject);}
} Player.cs 游戏玩家 using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;public class PlayerManager : MonoBehaviour {//属性值public int lifeVale 3;public int playerScore 0;public bool isDeadfalse;public bool isDefeat;//引用public GameObject born;//单例private static PlayerManager instance;public static PlayerManager Instance{get{return instance;}set{instance value;}}public void Awake(){Instance this;}// Use this for initializationvoid Start () {}// Update is called once per framevoid Update () {if(isDead){Recover();}}private void Recover(){if (lifeVale 0){//游戏失败返回主界面
SceneManager.LoadScene(Game);}else{lifeVale--;GameObject go Instantiate(born,new Vector3(-2,-8,0),Quaternion.identity);go.GetComponentBorn().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 ListVector3 itemPositionList new ListVector3();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;i2;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;i12;i){CreateItem(item[6], new Vector3(i, 9, 0), Quaternion.identity);}for(int i-11;i12;i){CreateItem(item[6], new Vector3(i, -9, 0), Quaternion.identity);}for(int i-8;i9;i){CreateItem(item[6], new Vector3(-11, i, 0), Quaternion.identity);}for(int i-8;i9;i){CreateItem(item[6], new Vector3(11, i, 0), Quaternion.identity);}//初始化玩家GameObject go Instantiate(item[3], new Vector3(-2, -8, 0), Quaternion.identity);go.GetComponentBorn().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 i0;i60;i){CreateItem(item[1], CreateRamdomPosition(), Quaternion.identity);}for(int i0;i20;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-1010的两列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 i0;iitemPositionList.Count;i){if(createPositemPositionList[i]){return true;}}return false;}//产生敌人的方法private void CreateEnemy(){int num Random.Range(0, 3);Vector3 EnemyPos new Vector3();if(num0){EnemyPos new Vector3(-10, 8, 0);}else if(num1){EnemyPos new Vector3(0, 8, 0);}else{EnemyPos new Vector3(10, 8, 0);}CreateItem(item[3],EnemyPos,Quaternion.identity);}} MapCreation.cs 初始化地图 using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Born : MonoBehaviour {public GameObject playerPrefab;public GameObject[] enemyPrefabList;//判断是否产生敌人public bool createPlay;// Use this for initializationvoid Start () {Invoke(BornTank,1f);Destroy(gameObject,1f);}private void Update(){}private void BornTank(){if (createPlay){Instantiate(playerPrefab, transform.position, Quaternion.identity);}else{int num Random.Range(0, 2);Instantiate(enemyPrefabList[num], transform.position, Quaternion.identity);}}
} Born.cs 玩家敌人坦克出生 using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Enemy : MonoBehaviour {//属性值public float moveSpeed 3;private Vector3 bullectEulerAugles;private float v-1;private float h;//引用private SpriteRenderer sr;public Sprite[] tankSprite; //上 右 下 左public GameObject bullectPrefab;public GameObject explosionPrefab;//计时器public float timeVal;public float timeValChangeDirection0;// Use this for initializationvoid Start(){sr GetComponentSpriteRenderer();}// Update is called once per framevoid Update(){//攻击的时间间隔if (timeVal 0.3f){//间隔大于0.4的时候才有攻击效果Attack();}else{timeVal Time.deltaTime;}}private void FixedUpdate(){Move();}//坦克的攻击方法private void Attack(){//子弹参数的角度当前坦克的角度子弹应该旋转的角度Instantiate(bullectPrefab, transform.position, Quaternion.Euler(transform.eulerAngles bullectEulerAugles));timeVal 0;}//坦克的移动方法private void Move(){if(timeValChangeDirection4){int num Random.Range(0,8);if(num5){v -1;h 0;}else if (num 0){v 1;h 0;}else if (num 0 num 2){h -1;v 0;}else if (num 2 num 4){h 1;v 0;}timeValChangeDirection 0;}else{timeValChangeDirection Time.fixedDeltaTime;}//监听玩家垂直轴输入transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v 0){sr.sprite tankSprite[2];bullectEulerAugles new Vector3(0, 0, -180);}else if (v 0){sr.sprite tankSprite[0];bullectEulerAugles new Vector3(0, 0, 0);}if (v ! 0){return;}//监听玩家水平轴输入transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World);if (h 0){sr.sprite tankSprite[3];bullectEulerAugles new Vector3(0, 0, 90);}else if (h 0){sr.sprite tankSprite[1];bullectEulerAugles new Vector3(0, 0, -90);}}//坦克的死亡方法private void Die(){PlayerManager.Instance.playerScore;//产生爆炸特效Instantiate(explosionPrefab, transform.position, transform.rotation);//死亡Destroy(gameObject);}//优化敌人AIprivate void OnCollisionEnter2D(Collision2D collision){if(collision.gameObject.tagEnemy){timeValChangeDirection 4;}}} Enemy.cs 敌人坦克 using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Explosion : MonoBehaviour {// Use this for initializationvoid Start () {//坦克销毁后0.167秒销毁爆炸特效Destroy(gameObject,0.167f);}// Update is called once per framevoid Update () {}
} Explosion.cs 游戏销毁特效 using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Heart : MonoBehaviour {private SpriteRenderer sr;public GameObject explosionPrefab;public Sprite BrokenSprite; // Use this for initializationvoid Start () {sr GetComponentSpriteRenderer();}private void Die(){sr.sprite BrokenSprite;Instantiate(explosionPrefab,transform.position,transform.rotation);PlayerManager.Instance.isDefeat true;}
} Heart.cs 心脏 using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;public class Bullect : MonoBehaviour {public float moveSpeed 10;public bool isPlayerBullect;// Use this for initializationvoid Start () {}// Update is called once per framevoid Update () {transform.Translate(transform.up*moveSpeed*Time.deltaTime,Space.World);}//子弹触发碰撞检测private void OnTriggerEnter2D(Collider2D collision){switch(collision.tag){case Tank:if(!isPlayerBullect){collision.SendMessage(Die);Destroy(gameObject);}break;case Heart:collision.SendMessage(Die);Destroy(gameObject);SceneManager.LoadScene(Game);break;case Enemy:if(isPlayerBullect){collision.SendMessage(Die);Destroy(gameObject);}break;case Wall://销毁自身和墙Destroy(collision.gameObject);Destroy(gameObject);break;case Barrier:Destroy(gameObject);break;default:break;}}} Bullect.cs 子弹 转载于:https://www.cnblogs.com/1138720556Gary/p/9795316.html