zoukankan      html  css  js  c++  java
  • 2D Platformer 学习

    using UnityEngine;
    using System.Collections;
    
    /// <summary>
    /// 玩家控制
    /// </summary>
    public class PlayerControl : MonoBehaviour
    {
        /// <summary>
        /// 是否面向右边
        /// </summary>
        [HideInInspector]
        public bool facingRight = true;            
        /// <summary>
        /// 是否在跳跃状态
        /// </summary>
        [HideInInspector]
        public bool jump = false;                
    
        /// <summary>
        /// 玩家左右移动的力
        /// </summary>
        public float moveForce = 365f;            
        /// <summary>
        /// 玩家在x轴的最大移动速度
        /// </summary>
        public float maxSpeed = 5f;                
        /// <summary>
        /// 跳跃声音
        /// </summary>
        public AudioClip[] jumpClips;            
        /// <summary>
        /// 跳跃力
        /// </summary>
        public float jumpForce = 1000f;            
        /// <summary>
        /// 嘲讽声音
        /// </summary>
        public AudioClip[] taunts;                
        /// <summary>
        /// 嘲讽阈值
        /// </summary>
        public float tauntProbability = 50f;    
        /// <summary>
        /// 嘲讽延迟
        /// </summary>
        public float tauntDelay = 1f;            
    
        /// <summary>
        /// 上一次的嘲讽索引
        /// </summary>
        private int tauntIndex;                    
        /// <summary>
        /// 检查玩家是否在地上的go
        /// </summary>
        private Transform groundCheck;            
        /// <summary>
        /// 玩家是否在地上
        /// </summary>
        private bool grounded = false;            
        /// <summary>
        /// Animator
        /// </summary>
        private Animator anim;                                                 
    
    
        void Awake()
        {
            groundCheck = transform.Find("groundCheck");
            anim = GetComponent<Animator>();
        }
    
    
        void Update()
        {
            //发射射线检测玩家是否在地面
            grounded = Physics2D.Linecast(transform.position, groundCheck.position, 1 << LayerMask.NameToLayer("Ground"));  
    
            //如果按下跳跃键且玩家在地上,玩家跳
            if(Input.GetButtonDown("Jump") && grounded)
                jump = true;
        }
    
    
        void FixedUpdate ()
        {
            //获取水平的输入
            float h = Input.GetAxis("Horizontal");
    
            //设置水平方向的移动速度
            anim.SetFloat("Speed", Mathf.Abs(h));
    
            //如果玩家速度没有到达最大速度,让玩家到达最大速度
            if(h * GetComponent<Rigidbody2D>().velocity.x < maxSpeed)
                GetComponent<Rigidbody2D>().AddForce(Vector2.right * h * moveForce);
    
            //如果x轴的速度大于最大速度,限制玩家速度为最大速度
            if(Mathf.Abs(GetComponent<Rigidbody2D>().velocity.x) > maxSpeed)
                GetComponent<Rigidbody2D>().velocity = new Vector2(Mathf.Sign(GetComponent<Rigidbody2D>().velocity.x) * maxSpeed, GetComponent<Rigidbody2D>().velocity.y);
    
            //设置玩家的朝向
            if(h > 0 && !facingRight)
                Flip();
            else if(h < 0 && facingRight)
                Flip();
    
            //如果玩家跳
            if(jump)
            {
                //播放跳动画
                anim.SetTrigger("Jump");
    
                //随机播放跳跃声音
                int i = Random.Range(0, jumpClips.Length);
                AudioSource.PlayClipAtPoint(jumpClips[i], transform.position);
    
                //添加跳跃力
                GetComponent<Rigidbody2D>().AddForce(new Vector2(0f, jumpForce));
    
                //设置跳跃标志位为false
                jump = false;
            }
        }
        
        /// <summary>
        /// 转向
        /// </summary>
        void Flip ()
        {
            facingRight = !facingRight;
    
            Vector3 theScale = transform.localScale;
            theScale.x *= -1;
            transform.localScale = theScale;
        }
    
        /// <summary>
        /// 嘲讽协程
        /// </summary>
        /// <returns></returns>
        public IEnumerator Taunt()
        {
            //计算嘲讽几率
            float tauntChance = Random.Range(0f, 100f);
            //如果嘲讽几率大于阈值
            if(tauntChance > tauntProbability)
            {
                
                yield return new WaitForSeconds(tauntDelay);
    
                
                if(!GetComponent<AudioSource>().isPlaying)
                {
                    tauntIndex = TauntRandom();
    
                    GetComponent<AudioSource>().clip = taunts[tauntIndex];
                    GetComponent<AudioSource>().Play();
                }
            }
        }
    
        /// <summary>
        /// 随机播放嘲讽
        /// </summary>
        /// <returns></returns>
        int TauntRandom()
        {
            int i = Random.Range(0, taunts.Length);
    
            //如果和上次的嘲讽索引一样,再随机一次
            if(i == tauntIndex)
                return TauntRandom();
            else
                return i;
        }
    }
    PlayerControl
    using UnityEngine;
    using System.Collections;
    
    /// <summary>
    /// 玩家生命
    /// </summary>
    public class PlayerHealth : MonoBehaviour
    {    
        /// <summary>
        /// 玩家生命
        /// </summary>
        public float health = 100f;                    
        /// <summary>
        /// 玩家能被伤害的时间间隔
        /// </summary>
        public float repeatDamagePeriod = 2f;        
        /// <summary>
        /// 玩家受到伤害的声音数组
        /// </summary>
        public AudioClip[] ouchClips;                
        /// <summary>
        /// 玩家受到伤害时受到的力
        /// </summary>
        public float hurtForce = 10f;                
        /// <summary>
        /// 敌人碰到玩家后,玩家受到的伤害
        /// </summary>
        public float damageAmount = 10f;            
    
        /// <summary>
        /// 玩家血条
        /// </summary>
        private SpriteRenderer healthBar;            
        /// <summary>
        /// 上一次受到的伤害
        /// </summary>
        private float lastHitTime;                    
        /// <summary>
        /// 血条缩放
        /// </summary>
        private Vector3 healthScale;                
        /// <summary>
        /// 玩家控制
        /// </summary>
        private PlayerControl playerControl;        
        /// <summary>
        /// Animator
        /// </summary>
        private Animator anim;                                                  
    
    
        void Awake ()
        {
            playerControl = GetComponent<PlayerControl>();
            healthBar = GameObject.Find("HealthBar").GetComponent<SpriteRenderer>();
            anim = GetComponent<Animator>();
    
            healthScale = healthBar.transform.localScale;
        }
    
    
        void OnCollisionEnter2D (Collision2D col)
        {
            //如果碰到敌人
            if(col.gameObject.tag == "Enemy")
            {
                //如果时间大于 上次受到伤害的时间 + 玩家能被伤害的时间间隔
                if (Time.time > lastHitTime + repeatDamagePeriod) 
                {
                    //如果玩家生命>0
                    if(health > 0f)
                    {
                        TakeDamage(col.transform); 
                        //设置上次受到伤害的时间
                        lastHitTime = Time.time; 
                    }
                    //如果玩家生命<=,让玩家掉下河
                    else
                    {
                        //将玩家的碰撞器修改为触发器
                        Collider2D[] cols = GetComponents<Collider2D>();
                        foreach(Collider2D c in cols)
                        {
                            c.isTrigger = true;
                        }
    
                        //修改玩家及其子物体的 SorintLayer
                        SpriteRenderer[] spr = GetComponentsInChildren<SpriteRenderer>();
                        foreach(SpriteRenderer s in spr)
                        {
                            s.sortingLayerName = "UI";
                        }
    
                        //关闭玩家控制脚本
                        GetComponent<PlayerControl>().enabled = false;
    
                        //关闭 gun脚本
                        GetComponentInChildren<Gun>().enabled = false;
    
                        //播放死亡动画
                        anim.SetTrigger("Die");
                    }
                }
            }
        }
    
        /// <summary>
        /// 受到伤害
        /// </summary>
        /// <param name="enemy"></param>
        void TakeDamage (Transform enemy)
        {
            //让玩家不能跳
            playerControl.jump = false;
    
            //设置受伤的方向
            Vector3 hurtVector = transform.position - enemy.position + Vector3.up * 5f;
    
            //给刚体施加力
            GetComponent<Rigidbody2D>().AddForce(hurtVector * hurtForce);
    
            //减血
            health -= damageAmount;
    
            //更新血条
            UpdateHealthBar();
    
            //随机播放受到伤害的声音
            int i = Random.Range (0, ouchClips.Length);
            AudioSource.PlayClipAtPoint(ouchClips[i], transform.position);
        }
    
        /// <summary>
        /// 更新血条
        /// </summary>
        public void UpdateHealthBar ()
        {
            //设置血条颜色
            healthBar.material.color = Color.Lerp(Color.green, Color.red, 1 - health * 0.01f);
    
            //设置血条缩放
            healthBar.transform.localScale = new Vector3(healthScale.x * health * 0.01f, 1, 1);
        }
    }
    PlayerHealth
    using UnityEngine;
    using System.Collections;
    
    /// <summary>
    /// 玩家放置炸弹
    /// </summary>
    public class LayBombs : MonoBehaviour
    {
        /// <summary>
        /// 炸弹是否已放置
        /// </summary>
        [HideInInspector]
        public bool bombLaid = false;        
        /// <summary>
        /// 玩家拥有的炸弹数量
        /// </summary>
        public int bombCount = 0;            
        /// <summary>
        /// 放置炸弹的声音
        /// </summary>
        public AudioClip bombsAway;            
        /// <summary>
        /// 炸弹预设
        /// </summary>
        public GameObject bomb;                
    
        /// <summary>
        /// 炸弹HUD
        /// </summary>
        private GUITexture bombHUD;                  
    
    
        void Awake ()
        {
            bombHUD = GameObject.Find("ui_bombHUD").GetComponent<GUITexture>();
        }
    
    
        void Update ()
        {
            //放置炸弹
            if(Input.GetButtonDown("Fire2") && !bombLaid && bombCount > 0)
            {
                bombCount--;
                bombLaid = true;
                AudioSource.PlayClipAtPoint(bombsAway,transform.position);
                Instantiate(bomb, transform.position, transform.rotation);
            }
            bombHUD.enabled = bombCount > 0;
        }
    }
    LayBombs
    using UnityEngine;
    using System.Collections;
    
    /// <summary>
    /// 玩家的枪
    /// </summary>
    public class Gun : MonoBehaviour
    {
        /// <summary>
        /// 火箭预设
        /// </summary>
        public Rigidbody2D rocket;                
        /// <summary>
        /// 火箭速度
        /// </summary>
        public float speed = 20f;                
    
        /// <summary>
        /// 玩家控制
        /// </summary>
        private PlayerControl playerCtrl;        
        /// <summary>
        /// Animator
        /// </summary>
        private Animator anim;                              
    
    
        void Awake()
        {
            anim = transform.root.gameObject.GetComponent<Animator>();
            playerCtrl = transform.root.GetComponent<PlayerControl>();
        }
    
    
        void Update ()
        {
            //按下发射键
            if(Input.GetButtonDown("Fire1"))
            {
                //播放动画
                anim.SetTrigger("Shoot");
                //播放声音
                GetComponent<AudioSource>().Play();
    
                //玩家朝右
                if(playerCtrl.facingRight)
                {
                    //实例化向右的子弹
                    Rigidbody2D bulletInstance = Instantiate(rocket, transform.position, Quaternion.Euler(new Vector3(0,0,0))) as Rigidbody2D;
                    bulletInstance.velocity = new Vector2(speed, 0);
                }
                //玩家朝左
                else
                {
                    //实例化向左的子弹
                    Rigidbody2D bulletInstance = Instantiate(rocket, transform.position, Quaternion.Euler(new Vector3(0,0,180f))) as Rigidbody2D;
                    bulletInstance.velocity = new Vector2(-speed, 0);
                }
            }
        }
    }
    Gun
    using UnityEngine;
    using System.Collections;
    
    /// <summary>
    /// 火箭
    /// </summary>
    public class Rocket : MonoBehaviour 
    {
        /// <summary>
        /// 爆炸预设
        /// </summary>
        public GameObject explosion;        
    
    
        void Start () 
        {
            //炸弹没有碰到任何东西,默认2秒内销毁
            Destroy(gameObject, 2);
        }
    
        /// <summary>
        /// 爆炸
        /// </summary>
        void OnExplode()
        {
            //实例化爆炸效果,让爆炸效果在z轴随机旋转
            Quaternion randomRotation = Quaternion.Euler(0f, 0f, Random.Range(0f, 360f));
            Instantiate(explosion, transform.position, randomRotation);
        }
        
        void OnTriggerEnter2D (Collider2D col) 
        {
            //撞到敌人
            if(col.tag == "Enemy")
            {
                //敌人受伤
                col.gameObject.GetComponent<Enemy>().Hurt();
                OnExplode();
                Destroy (gameObject);
            }
            //撞到炸弹收集物
            else if(col.tag == "BombPickup")
            {
                //炸弹爆炸
                col.gameObject.GetComponent<Bomb>().Explode();
                Destroy (col.transform.root.gameObject);
                Destroy (gameObject);
            }
            //其余情况
            else if(col.gameObject.tag != "Player")
            {
                OnExplode();
                Destroy (gameObject);
            }
        }
    }
    Rocket
    using UnityEngine;
    using System.Collections;
    
    /// <summary>
    /// 自动销毁
    /// </summary>
    public class Destroyer : MonoBehaviour
    {
        /// <summary>
        /// 是否在开始时间就进入自动销毁
        /// </summary>
        public bool destroyOnAwake;            
        /// <summary>
        /// 自动销毁的延迟
        /// </summary>
        public float awakeDestroyDelay;        
        /// <summary>
        /// 是否查找子物体
        /// </summary>
        public bool findChild = false;        
        /// <summary>
        /// 子物体的名称
        /// </summary>
        public string namedChild;                                                    
    
    
        void Awake ()
        {
            if(destroyOnAwake)
            {
                if(findChild)
                {
                    Destroy (transform.Find(namedChild).gameObject);
                }
                else
                {
                    Destroy(gameObject, awakeDestroyDelay);
                }
    
            }
    
        }
    
        /// <summary>
        /// 销毁子物体
        /// </summary>
        void DestroyChildGameObject ()
        {
            if(transform.Find(namedChild).gameObject != null)
                Destroy (transform.Find(namedChild).gameObject);
        }
    
        /// <summary>
        /// 禁用子物体
        /// </summary>
        void DisableChildGameObject ()
        {
            if(transform.Find(namedChild).gameObject.activeSelf == true)
                transform.Find(namedChild).gameObject.SetActive(false);
        }
    
        /// <summary>
        /// 销毁物体
        /// </summary>
        void DestroyGameObject ()
        {
            Destroy (gameObject);
        }
    }
    Destroyer
    using UnityEngine;
    using System.Collections;
    
    /// <summary>
    /// 血条跟随玩家
    /// </summary>
    public class FollowPlayer : MonoBehaviour
    {
        /// <summary>
        /// 相对于玩家的偏移
        /// </summary>
        public Vector3 offset;            
        
        /// <summary>
        /// 玩家
        /// </summary>
        private Transform player;                                                   
    
    
        void Awake ()
        {
            player = GameObject.FindGameObjectWithTag("Player").transform;
        }
    
        void Update ()
        {
            transform.position = player.position + offset;
        }
    }
    FollowPlayer
    using UnityEngine;
    using System.Collections;
    
    /// <summary>
    /// 收集物的孵化器
    /// </summary>
    public class PickupSpawner : MonoBehaviour
    {
        /// <summary>
        /// 收集物预设
        /// </summary>
        public GameObject[] pickups;                
        /// <summary>
        /// 收集物在空中的时间
        /// </summary>
        public float pickupDeliveryTime = 5f;        
        /// <summary>
        /// 掉落范围左
        /// </summary>
        public float dropRangeLeft;                    
        /// <summary>
        /// 掉落范围右
        /// </summary>
        public float dropRangeRight;                
        /// <summary>
        /// 高于这个阈值,投递炸弹
        /// </summary>
        public float highHealthThreshold = 75f;     
        /// <summary>
        /// 低于这个阈值,投递血药
        /// </summary>
        public float lowHealthThreshold = 25f;        
    
        /// <summary>
        /// 玩家血量
        /// </summary>
        private PlayerHealth playerHealth;                                                  
    
    
        void Awake ()
        {
            playerHealth = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerHealth>();
        }
    
    
        void Start ()
        {
            StartCoroutine(DeliverPickup());
        }
    
        /// <summary>
        /// 派送收集物协程
        /// </summary>
        /// <returns></returns>
        public IEnumerator DeliverPickup()
        {
            yield return new WaitForSeconds(pickupDeliveryTime);
    
            //随机获得掉落在x轴的位置
            float dropPosX = Random.Range(dropRangeLeft, dropRangeRight);
    
            //计算掉落位置
            Vector3 dropPos = new Vector3(dropPosX, 15f, 1f);
    
            //高于阈值,实例化炸弹
            if(playerHealth.health >= highHealthThreshold)
                Instantiate(pickups[0], dropPos, Quaternion.identity);
            //低于阈值,实例化药
            else if(playerHealth.health <= lowHealthThreshold)
                Instantiate(pickups[1], dropPos, Quaternion.identity);
            //随机实例化
            else
            {
                int pickupIndex = Random.Range(0, pickups.Length);
                Instantiate(pickups[pickupIndex], dropPos, Quaternion.identity);
            }
        }
    }
    PickupSpawner
    using UnityEngine;
    using System.Collections;
    
    /// <summary>
    /// 炸弹收集物
    /// </summary>
    public class BombPickup : MonoBehaviour
    {
        /// <summary>
        /// 收集声音
        /// </summary>
        public AudioClip pickupClip;        
    
        /// <summary>
        /// Animator
        /// </summary>
        private Animator anim;                
        /// <summary>
        /// 是否着陆
        /// </summary>
        private bool landed = false;                    
    
    
        void Awake()
        {
            anim = transform.root.GetComponent<Animator>();
        }
    
    
        void OnTriggerEnter2D (Collider2D other)
        {
            //碰到玩家
            if(other.tag == "Player")
            {
                AudioSource.PlayClipAtPoint(pickupClip, transform.position);
    
                other.GetComponent<LayBombs>().bombCount++;
    
                Destroy(transform.root.gameObject);
            }
            //碰到地面
            else if(other.tag == "ground" && !landed)
            {
                anim.SetTrigger("Land");
                transform.parent = null;
                gameObject.AddComponent<Rigidbody2D>();
                landed = true;        
            }
        }
    }
    BombPickup
    using UnityEngine;
    using System.Collections;
    
    /// <summary>
    /// 生命收集物
    /// </summary>
    public class HealthPickup : MonoBehaviour
    {
        /// <summary>
        /// 提供的生命值
        /// </summary>
        public float healthBonus;                
        /// <summary>
        /// 被收集后的声音
        /// </summary>
        public AudioClip collect;                
    
        /// <summary>
        /// 收集物孵化器
        /// </summary>
        private PickupSpawner pickupSpawner;    
        /// <summary>
        /// Animator
        /// </summary>
        private Animator anim;                    
        /// <summary>
        /// 是否着陆
        /// </summary>
        private bool landed;                                 
    
    
        void Awake ()
        {
            pickupSpawner = GameObject.Find("pickupManager").GetComponent<PickupSpawner>();
            anim = transform.root.GetComponent<Animator>();
        }
    
    
        void OnTriggerEnter2D (Collider2D other)
        {
            //如果碰到玩家
            if(other.tag == "Player")
            {
                PlayerHealth playerHealth = other.GetComponent<PlayerHealth>();
                //给玩家加血
                playerHealth.health += healthBonus;
                //限制玩家的最大生命
                playerHealth.health = Mathf.Clamp(playerHealth.health, 0f, 100f);
    
                //更新血条
                playerHealth.UpdateHealthBar();
    
                pickupSpawner.StartCoroutine(pickupSpawner.DeliverPickup());
    
                AudioSource.PlayClipAtPoint(collect,transform.position);
    
                Destroy(transform.root.gameObject);
            }
            //如果碰到地面
            else if(other.tag == "ground" && !landed)
            {
                anim.SetTrigger("Land");
    
                transform.parent = null;
                gameObject.AddComponent<Rigidbody2D>();
                landed = true;    
            }
        }
    }
    HealthPickup
    using UnityEngine;
    using System.Collections;
    
    /// <summary>
    /// 炸弹
    /// </summary>
    public class Bomb : MonoBehaviour
    {
        /// <summary>
        /// 爆炸影响的半径
        /// </summary>
        public float bombRadius = 10f;            
        /// <summary>
        /// 爆炸力
        /// </summary>
        public float bombForce = 100f;            
        /// <summary>
        /// 爆炸声音
        /// </summary>
        public AudioClip boom;                    
        /// <summary>
        /// 炸弹引爆的声音
        /// </summary>
        public AudioClip fuse;                    
        /// <summary>
        /// 引爆持续时间
        /// </summary>
        public float fuseTime = 1.5f;
        /// <summary>
        /// 爆炸特效
        /// </summary>
        public GameObject explosion;            
    
        /// <summary>
        /// 玩家放置炸弹
        /// </summary>
        private LayBombs layBombs;                
        /// <summary>
        /// 收集物孵化器
        /// </summary>
        private PickupSpawner pickupSpawner;    
        /// <summary>
        /// 爆炸粒子系统
        /// </summary>
        private ParticleSystem explosionFX;           
    
    
        void Awake ()
        {
            explosionFX = GameObject.FindGameObjectWithTag("ExplosionFX").GetComponent<ParticleSystem>();
            pickupSpawner = GameObject.Find("pickupManager").GetComponent<PickupSpawner>();
            if(GameObject.FindGameObjectWithTag("Player"))
                layBombs = GameObject.FindGameObjectWithTag("Player").GetComponent<LayBombs>();
        }
    
        void Start ()
        {
            
            //如果炸弹没有父物体,说明炸弹已被放置,开始引爆
            if(transform.root == transform)
                StartCoroutine(BombDetonation());
        }
    
        /// <summary>
        /// 炸弹引爆协程
        /// </summary>
        /// <returns></returns>
        IEnumerator BombDetonation()
        {
            AudioSource.PlayClipAtPoint(fuse, transform.position);
    
            yield return new WaitForSeconds(fuseTime);
    
            Explode();
        }
    
        /// <summary>
        /// 爆炸
        /// </summary>
        public void Explode()
        {
            
            //玩家可以放置炸弹
            layBombs.bombLaid = false;
    
            //开始新的投递
            pickupSpawner.StartCoroutine(pickupSpawner.DeliverPickup());
    
            //获取范围内的敌人
            Collider2D[] enemies = Physics2D.OverlapCircleAll(transform.position, bombRadius, 1 << LayerMask.NameToLayer("Enemies"));
    
            foreach(Collider2D en in enemies)
            {
                Rigidbody2D rb = en.GetComponent<Rigidbody2D>();
                if(rb != null && rb.tag == "Enemy")
                {
                    //秒杀敌人
                    rb.gameObject.GetComponent<Enemy>().HP = 0;
    
                    //将敌人推出一段距离
                    Vector3 deltaPos = rb.transform.position - transform.position;
                    Vector3 force = deltaPos.normalized * bombForce;
                    rb.AddForce(force);
                }
            }
    
            //播放爆炸效果
            explosionFX.transform.position = transform.position;
            explosionFX.Play();
    
            Instantiate(explosion,transform.position, Quaternion.identity);
    
            AudioSource.PlayClipAtPoint(boom, transform.position);
    
            Destroy (gameObject);
        }
    }
    Bomb
    using UnityEngine;
    using System.Collections;
    
    /// <summary>
    /// 敌人
    /// </summary>
    public class Enemy : MonoBehaviour
    {
        /// <summary>
        /// 移动速度
        /// </summary>
        public float moveSpeed = 2f;        
        /// <summary>
        /// 玩家被击杀需要的次数
        /// </summary>
        public int HP = 2;                    
        /// <summary>
        /// 死亡的动画
        /// </summary>
        public Sprite deadEnemy;            
        /// <summary>
        /// 受到伤害的动画
        /// </summary>
        public Sprite damagedEnemy;            
        /// <summary>
        /// 死亡声音
        /// </summary>
        public AudioClip[] deathClips;        
        /// <summary>
        /// 敌人死亡后生成的 得分物体
        /// </summary>
        public GameObject hundredPointsUI;    
        /// <summary>
        /// 
        /// </summary>
        public float deathSpinMin = -100f;    
        /// <summary>
        /// 
        /// </summary>
        public float deathSpinMax = 100f;    
    
        /// <summary>
        /// 精灵渲染器
        /// </summary>
        private SpriteRenderer ren;            
        /// <summary>
        /// 检查前方的go
        /// </summary>
        private Transform frontCheck;        
        /// <summary>
        /// 是否死亡
        /// </summary>
        private bool dead = false;            
        /// <summary>
        /// 玩家得分脚本
        /// </summary>
        private Score score;                                                                   
    
        
        void Awake()
        {
            ren = transform.Find("body").GetComponent<SpriteRenderer>();
            frontCheck = transform.Find("frontCheck").transform;
            score = GameObject.Find("Score").GetComponent<Score>();
        }
    
        void FixedUpdate ()
        {
            //检测碰撞
            Collider2D[] frontHits = Physics2D.OverlapPointAll(frontCheck.position, 1);
    
            foreach(Collider2D c in frontHits)
            {
                //如果碰到障碍物
                if(c.tag == "Obstacle")
                {
                    //转向
                    Flip ();
                    break;
                }
            }
    
            GetComponent<Rigidbody2D>().velocity = new Vector2(transform.localScale.x * moveSpeed, GetComponent<Rigidbody2D>().velocity.y);    
    
            
            if(HP == 1 && damagedEnemy != null)
                ren.sprite = damagedEnemy;
    
            if(HP <= 0 && !dead)
                Death ();
        }
        
        /// <summary>
        /// 受到伤害
        /// </summary>
        public void Hurt()
        {
            HP--;
        }
        
        void Death()
        {
            //关闭所有的精灵渲染器
            SpriteRenderer[] otherRenderers = GetComponentsInChildren<SpriteRenderer>();
            foreach(SpriteRenderer s in otherRenderers)
            {
                s.enabled = false;
            }
    
            //打开自身的渲染器,设置为死亡精灵
            ren.enabled = true;
            ren.sprite = deadEnemy;
    
            //玩家得分+100
            score.score += 100;
    
            //死亡标志位设为true
            dead = true;
    
            GetComponent<Rigidbody2D>().fixedAngle = false;
            GetComponent<Rigidbody2D>().AddTorque(Random.Range(deathSpinMin,deathSpinMax));
    
            //修改碰撞器为触发器
            Collider2D[] cols = GetComponents<Collider2D>();
            foreach(Collider2D c in cols)
            {
                c.isTrigger = true;
            }
    
            //播放随机的死亡声音
            int i = Random.Range(0, deathClips.Length);
            AudioSource.PlayClipAtPoint(deathClips[i], transform.position);
    
            //实例化得分效果        
            Vector3 scorePos;
            scorePos = transform.position;
            scorePos.y += 1.5f;
            Instantiate(hundredPointsUI, scorePos, Quaternion.identity);
        }
    
        /// <summary>
        /// 转向
        /// </summary>
        public void Flip()
        {
            Vector3 enemyScale = transform.localScale;
            enemyScale.x *= -1;
            transform.localScale = enemyScale;
        }
    }
    Enemy
    using UnityEngine;
    using System.Collections;
    
    /// <summary>
    /// 移除器
    /// </summary>
    public class Remover : MonoBehaviour
    {
        /// <summary>
        /// 水的飞溅效果
        /// </summary>
        public GameObject splash;
    
    
        void OnTriggerEnter2D(Collider2D col)
        {
            //如果碰到玩家
            if(col.gameObject.tag == "Player")
            {
                //禁用摄像机跟随玩家的脚本
                GameObject.FindGameObjectWithTag("MainCamera").GetComponent<CameraFollow>().enabled = false;
    
                //禁用玩家血条
                if(GameObject.FindGameObjectWithTag("HealthBar").activeSelf)
                {
                    GameObject.FindGameObjectWithTag("HealthBar").SetActive(false);
                }
    
                Instantiate(splash, col.transform.position, transform.rotation);
                Destroy (col.gameObject);
                StartCoroutine("ReloadGame");
            }
            else
            {
                Instantiate(splash, col.transform.position, transform.rotation);
                Destroy (col.gameObject);    
            }
        }
    
        /// <summary>
        /// 重新加载游戏协程
        /// </summary>
        /// <returns></returns>
        IEnumerator ReloadGame()
        {            
            yield return new WaitForSeconds(2);
            Application.LoadLevel(Application.loadedLevel);
        }
    }
    Remover

      

    using UnityEngine;
    using System.Collections;
    
    /// <summary>
    /// 玩家得分
    /// </summary>
    public class Score : MonoBehaviour
    {
        /// <summary>
        /// 玩家得分
        /// </summary>
        public int score = 0;                    
    
        /// <summary>
        /// 玩家控制脚本
        /// </summary>
        private PlayerControl playerControl;    
        /// <summary>
        /// 上一帧的得分
        /// </summary>
        private int previousScore = 0;                     
    
    
        void Awake ()
        {
            playerControl = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerControl>();
        }
    
    
        void Update ()
        {
            //设置得分文本
            GetComponent<GUIText>().text = "Score: " + score;
    
            //如果上一帧的得分不等与现在的得分
            if(previousScore != score)
                //播放嘲讽
                playerControl.StartCoroutine(playerControl.Taunt());
    
            //设置上一帧的额得分为 现在的得分
            previousScore = score;
        }
    
    }
    Score
    using UnityEngine;
    using System.Collections;
    
    /// <summary>
    /// 分数阴影
    /// </summary>
    public class ScoreShadow : MonoBehaviour
    {
        /// <summary>
        /// Score Go
        /// </summary>
        public GameObject guiCopy;          
    
    
        void Awake()
        {
            //设置阴影的位置
            Vector3 behindPos = transform.position;
            behindPos = new Vector3(guiCopy.transform.position.x, guiCopy.transform.position.y-0.005f, guiCopy.transform.position.z-1);
            transform.position = behindPos;
        }
    
    
        void Update ()
        {
            GetComponent<GUIText>().text = guiCopy.GetComponent<GUIText>().text;
        }
    }
    ScoreShadow
    using UnityEngine;
    using System.Collections;
    
    /// <summary>
    /// 暂停器
    /// </summary>
    public class Pauser : MonoBehaviour {
        /// <summary>
        /// 是否已暂停
        /// </summary>
        private bool paused = false;
        
        void Update () {
            if(Input.GetKeyUp(KeyCode.P))
            {
                paused = !paused;
            }
    
            if(paused)
                Time.timeScale = 0;
            else
                Time.timeScale = 1;
        }
    }
    Pauser
    using UnityEngine;
    using System.Collections;
    
    /// <summary>
    /// 并行背景
    /// </summary>
    public class BackgroundParallax : MonoBehaviour
    {
        /// <summary>
        /// 并行背景数组
        /// </summary>
        public Transform[] backgrounds;                
        /// <summary>
        /// 
        /// </summary>
        public float parallaxScale;                    
        /// <summary>
        /// 
        /// </summary>
        public float parallaxReductionFactor;        
        /// <summary>
        /// 
        /// </summary>
        public float smoothing;                        
    
        /// <summary>
        /// 摄像机
        /// </summary>
        private Transform cam;                        
        /// <summary>
        /// 上一帧的相机位置
        /// </summary>
        private Vector3 previousCamPos;                                        
    
    
        void Awake ()
        {
            cam = Camera.main.transform;
        }
    
    
        void Start ()
        {
            previousCamPos = cam.position;
        }
    
    
        void Update ()
        {
            float parallax = (previousCamPos.x - cam.position.x) * parallaxScale;
    
            for(int i = 0; i < backgrounds.Length; i++)
            {
                float backgroundTargetPosX = backgrounds[i].position.x + parallax * (i * parallaxReductionFactor + 1);
                Vector3 backgroundTargetPos = new Vector3(backgroundTargetPosX, backgrounds[i].position.y, backgrounds[i].position.z);
                backgrounds[i].position = Vector3.Lerp(backgrounds[i].position, backgroundTargetPos, smoothing * Time.deltaTime);
            }
            previousCamPos = cam.position;
        }
    }
    BackgroundParallax
    using UnityEngine;
    using System.Collections;
    
    /// <summary>
    /// 背景道具孵化器
    /// </summary>
    public class BackgroundPropSpawner : MonoBehaviour
    {
        /// <summary>
        /// 背景道具的刚体
        /// </summary>
        public Rigidbody2D backgroundProp;        
        /// <summary>
        /// 左侧的x轴孵化点
        /// </summary>
        public float leftSpawnPosX;                
        /// <summary>
        /// 右侧的x轴孵化点
        /// </summary>
        public float rightSpawnPosX;            
        /// <summary>
        /// 
        /// </summary>
        public float minSpawnPosY;                
        public float maxSpawnPosY;                
        /// <summary>
        /// 最短的孵化时间间隔
        /// </summary>
        public float minTimeBetweenSpawns;        
        /// <summary>
        /// 最长的孵化时间间隔
        /// </summary>
        public float maxTimeBetweenSpawns;        
        /// <summary>
        /// 道具的最小速度
        /// </summary>
        public float minSpeed;                    
        /// <summary>
        /// 道具的最大速度
        /// </summary>
        public float maxSpeed;                                                   
    
        void Start ()
        {
            //随机种子
            Random.seed = System.DateTime.Today.Millisecond;
    
            StartCoroutine("Spawn");
        }
    
        /// <summary>
        /// 孵化协程
        /// </summary>
        /// <returns></returns>
        IEnumerator Spawn ()
        {
            //随机等待时间
            float waitTime = Random.Range(minTimeBetweenSpawns, maxTimeBetweenSpawns);
            yield return new WaitForSeconds(waitTime);
    
            //随机方向
            bool facingLeft = Random.Range(0,2) == 0;
    
            float posX = facingLeft ? rightSpawnPosX : leftSpawnPosX;
    
            //随机y轴位置
            float posY = Random.Range(minSpawnPosY, maxSpawnPosY);
    
            Vector3 spawnPos = new Vector3(posX, posY, transform.position.z);
    
            Rigidbody2D propInstance = Instantiate(backgroundProp, spawnPos, Quaternion.identity) as Rigidbody2D;
    
            if(!facingLeft)
            {
                Vector3 scale = propInstance.transform.localScale;
                scale.x *= -1;
                propInstance.transform.localScale = scale;
            }
    
            //随机速度
            float speed = Random.Range(minSpeed, maxSpeed);
    
            speed *= facingLeft ? -1f : 1f;
    
            propInstance.velocity = new Vector2(speed, 0);
    
            //重新孵化
            StartCoroutine(Spawn());
    
            while(propInstance != null)
            {
                if(facingLeft)
                {
                    if(propInstance.transform.position.x < leftSpawnPosX - 0.5f)
                        Destroy(propInstance.gameObject);
                }
                else
                {
                    if(propInstance.transform.position.x > rightSpawnPosX + 0.5f)
                        Destroy(propInstance.gameObject);
                }
                yield return null;
            }
        }
    }
    BackgroundPropSpawner
    using UnityEngine;
    using System.Collections;
    
    /// <summary>
    /// 摄像机跟随玩家
    /// </summary>
    public class CameraFollow : MonoBehaviour 
    {
        public float xMargin = 1f;        
        public float yMargin = 1f;        
        public float xSmooth = 8f;        
        public float ySmooth = 8f;        
        public Vector2 maxXAndY;        
        public Vector2 minXAndY;                                
    
    
        private Transform player;        
    
    
        void Awake ()
        {
            player = GameObject.FindGameObjectWithTag("Player").transform;
        }
    
    
        bool CheckXMargin()
        {
            return Mathf.Abs(transform.position.x - player.position.x) > xMargin;
        }
    
    
        bool CheckYMargin()
        {
            return Mathf.Abs(transform.position.y - player.position.y) > yMargin;
        }
    
    
        void FixedUpdate ()
        {
            TrackPlayer();
        }
        
        
        void TrackPlayer ()
        {
            float targetX = transform.position.x;
            float targetY = transform.position.y;
    
            if(CheckXMargin())
                targetX = Mathf.Lerp(transform.position.x, player.position.x, xSmooth * Time.deltaTime);
    
            if(CheckYMargin())
                targetY = Mathf.Lerp(transform.position.y, player.position.y, ySmooth * Time.deltaTime);
    
            targetX = Mathf.Clamp(targetX, minXAndY.x, maxXAndY.x);
            targetY = Mathf.Clamp(targetY, minXAndY.y, maxXAndY.y);
    
            transform.position = new Vector3(targetX, targetY, transform.position.z);
        }
    }
    CameraFollow
    using UnityEngine;
    using System.Collections;
    
    /// <summary>
    /// 设置粒子系统的SortingLayer
    /// </summary>
    public class SetParticleSortingLayer : MonoBehaviour
    {
        /// <summary>
        /// SortingLayer名
        /// </summary>
        public string sortingLayerName;        
    
    
        void Start ()
        {
            //设置粒子系统的sortingLayer名
            GetComponent<ParticleSystem>().GetComponent<Renderer>().sortingLayerName = sortingLayerName;
        }
    }
    SetParticleSortingLayer

    视频:https://pan.baidu.com/s/1skBrKnF

    项目:https://pan.baidu.com/s/1qXDvBWg

  • 相关阅读:
    基于Twisted的简单聊天室
    小学题的python实现
    初识Go(8)
    初识Go(7)
    初识Go(6)
    初识Go(5)
    初识Go(4)
    初识Go(3)
    初识Go(2)
    初识Go(1)
  • 原文地址:https://www.cnblogs.com/revoid/p/6439978.html
Copyright © 2011-2022 走看看