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,  << 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);

        //设置玩家的朝向
         && !facingRight)
            Flip();
         && facingRight)
            Flip();

        //如果玩家跳
        if(jump)
        {
            //播放跳动画
            anim.SetTrigger("Jump");

            //随机播放跳跃声音
            , 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 *= -;
        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()
    {
        , 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();

        //随机播放受到伤害的声音
        , ouchClips.Length);
        AudioSource.PlayClipAtPoint(ouchClips[i], transform.position);
    }

    /// <summary>
    /// 更新血条
    /// </summary>
    public void UpdateHealthBar ()
    {
        //设置血条颜色
        healthBar.material.color = Color.Lerp(Color.green, Color.red,  - health * 0.01f);

        //设置血条缩放
        healthBar.transform.localScale = , );
    }
}

PlayerHealth

using UnityEngine;
using System.Collections;

/// <summary>
/// 玩家放置炸弹
/// </summary>
public class LayBombs : MonoBehaviour
{
    /// <summary>
    /// 炸弹是否已放置
    /// </summary>
    [HideInInspector]
    public bool bombLaid = false;
    /// <summary>
    /// 玩家拥有的炸弹数量
    /// </summary>
    ;
    /// <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 ()
    {
        //放置炸弹
        )
        {
            bombCount--;
            bombLaid = true;
            AudioSource.PlayClipAtPoint(bombsAway,transform.position);
            Instantiate(bomb, transform.position, transform.rotation);
        }
        bombHUD.enabled = bombCount > ;
    }
}

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(,,))) as Rigidbody2D;
                bulletInstance.velocity = );
            }
            //玩家朝左
            else
            {
                //实例化向左的子弹
                Rigidbody2D bulletInstance = Instantiate(rocket, transform.position, Quaternion.Euler(,,180f))) as Rigidbody2D;
                bulletInstance.velocity = );
            }
        }
    }
}

Gun

using UnityEngine;
using System.Collections;

/// <summary>
/// 火箭
/// </summary>
public class Rocket : MonoBehaviour
{
    /// <summary>
    /// 爆炸预设
    /// </summary>
    public GameObject explosion;        

    void Start ()
    {
        //炸弹没有碰到任何东西,默认2秒内销毁
        Destroy(gameObject, );
    }

    /// <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[], dropPos, Quaternion.identity);
        //低于阈值,实例化药
        else if(playerHealth.health <= lowHealthThreshold)
            Instantiate(pickups[], dropPos, Quaternion.identity);
        //随机实例化
        else
        {
            , 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,  << LayerMask.NameToLayer("Enemies"));

        foreach(Collider2D en in enemies)
        {
            Rigidbody2D rb = en.GetComponent<Rigidbody2D>();
            if(rb != null && rb.tag == "Enemy")
            {
                //秒杀敌人
                rb.gameObject.GetComponent<Enemy>().HP = ;

                //将敌人推出一段距离
                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>
    ;
    /// <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, );

        foreach(Collider2D c in frontHits)
        {
            //如果碰到障碍物
            if(c.tag == "Obstacle")
            {
                //转向
                Flip ();
                break;
            }
        }

        GetComponent<Rigidbody2D>().velocity = new Vector2(transform.localScale.x * moveSpeed, GetComponent<Rigidbody2D>().velocity.y);    

         && damagedEnemy != null)
            ren.sprite = damagedEnemy;

         && !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 += ;

        //死亡标志位设为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;
        }

        //播放随机的死亡声音
        , 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 *= -;
        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()
    {
        );
        Application.LoadLevel(Application.loadedLevel);
    }
}

Remover

using UnityEngine;
using System.Collections;

/// <summary>
/// 玩家得分
/// </summary>
public class Score : MonoBehaviour
{
    /// <summary>
    /// 玩家得分
    /// </summary>
    ;                    

    /// <summary>
    /// 玩家控制脚本
    /// </summary>
    private PlayerControl playerControl;
    /// <summary>
    /// 上一帧的得分
    /// </summary>
    ;                     

    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 = );
        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 = ;
        else
            Time.timeScale = ;
    }
}

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;

        ; i < backgrounds.Length; i++)
        {
            );
            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);

        //随机方向
        ,) == ;

        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 *= -;
            propInstance.transform.localScale = scale;
        }

        //随机速度
        float speed = Random.Range(minSpeed, maxSpeed);

        speed *= facingLeft ? -1f : 1f;

        propInstance.velocity = );

        //重新孵化
        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

2D Platformer 学习的更多相关文章

  1. Cocos 2d TestCPP 学习

    Cocos 2d testcpp包含了大量的demo, 对于新手学习cocos引擎具有非常大的帮助.因为接下来的开发项目有可能会用到该引擎,所以希望可以利用自己的业余时间提前熟悉起来.该篇文章会记录自 ...

  2. [Unity] 2D开发学习教程

    豆子先生,据说是官方的一个Demo, 在蛮牛网上有大部分代码的视频讲解. 这个是我学习过程中边看教程边写出来的,功能和原版基本一样,增加了手游的操控. Blog: http://www.cnblogs ...

  3. u3d 2D开发学习

    http://gad.qq.com/article/detail/45365 https://blog.csdn.net/s556699/article/details/55224830 UI层设计  ...

  4. Android 2D Graphics学习 Region和Canvas裁剪

    1.首先介绍Region类 Region,中文意思即区域的意思,它表示的是canvas图层上的某一块封闭的区域. /**构造方法*/ public Region()  //创建一个空的区域 publi ...

  5. 【Unity3D基础教程】给初学者看的Unity教程(四):通过制作Flappy Bird了解Native 2D中的RigidBody2D和Collider2D

    作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点[推荐].谢谢! 引子 在第一篇文章[Unity3D基础教程] ...

  6. Unity 官方教程 学习

    Interface & Essentials Using the Unity Interface 1.Interface Overview https://unity3d.com/cn/lea ...

  7. Quartz 2D编程指南(1) - 概览

    Quartz 2D编程指南是论坛会员德鲁伊翻译的国外的Quartz 2D一系列学习资料,供大家参考 Quartz 2D是一个二维图形绘制引擎,支持iOS环境和Mac OS X环境.我们可以使用Quar ...

  8. 【转】通过制作Flappy Bird了解Native 2D中的RigidBody2D和Collider

    作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点[推荐].谢谢! 引子 在第一篇文章[Unity3D基础教程] ...

  9. Android UI开发第四十二篇——实现实现易信的圆形图像和对话列表的图像显示部分

    显示图像时,很多个性化显示,圆形或圆角.气泡等等,我们这一篇文章探讨一下圆形和气泡的显示,仿照易信中的实现,先看下效果图: 代码: public class RoundImageView extend ...

随机推荐

  1. node fs 解决回调地域问题

    promisify问题 promisify = require('util).promisify const read = promisify( fs.readFile); read('input.t ...

  2. 关于这次安装Oracle

    前后大概经历了一个星期,今天下午(先是用的Navicat)当我尝试性的把用户名上方的复选项从服务名换成SID时,竟然瞬间连接成功了,整个人都是蒙B的,这样就好了? 之后我又用PLsql测试了一下,秒进 ...

  3. 了解下webpack的几个命令

    [ webpack3.0.0刚刚出来  所以文章是跟着低版本 教程 操作熟悉  结果好多对不上喔] 六:了解下webpack的几个命令 webpack         // 最基本的启动webpack ...

  4. 理解mpvue的生命周期

    mpvue是美团基于vue开发的一个开发小程序的框架,从而以vue的语法来开发小程序.在生命周期上,mpvue同时支持了vue的生命周期和小程序的生命周期,这可能让新上手的同学费解.这篇文章就来讲讲m ...

  5. java学习笔记25(Collections类)

    Collections算法类: Collections是一个算法类,提供了一系列静态方法,实现对集合的排序.替换.交换.搜索.拷贝等操作: 用法:Collections.方法名(要操作的集合): 就像 ...

  6. js实现瀑布流以及加载效果

    一.瀑布流是个啥? 瀑布流,是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部. 最早采用瀑布流布局的网站是Pinteres ...

  7. linux 编译链接问题

    -rpath和-rpath-link 假设有3个文件,在同一目录下,有这样的依赖关系 test->liba.so->libd.so 如果编译test的时候这样写 gcc test.c –l ...

  8. npm http-server ubuntu

    Node.js中http-server的使用 使用阿里的npm镜像 国外的npm太慢了.查看一下自己使用的源: npm config get registry 1 应该显示https://regist ...

  9. RMQ_ST表

    ]; ]; ]; void init(int n) { int i, j; pwr[] = ; ; i<; ++i) pwr[i] = pwr[i-] << ; ; pwr[j]&l ...

  10. [LeetCode&Python] Problem 350. Intersection of Two Arrays II

    Given two arrays, write a function to compute their intersection. Example 1: Input: nums1 = [1,2,2,1 ...