Unity案例课程 - 涂鸦跳跳 Day 2

1.随机生成Tile(一)

在GameManager中添加随机生成砖块和从资源池取出物体的代码

    

public enum ObjectType
{
    Tile,
    Item,
    Coin,
    Enemy,
    Bullet
}
    //tile池子
    public Queue tilePool = new Queue();
    public Queue itemPool = new Queue();
    public Queue coinPool = new Queue();
    public Queue enemyPool = new Queue();
    public Queue bulletPool = new Queue();

    /// 
    /// 随机生成砖块
    /// 
    void GenerateTile()
    {
        GameObject go = GetInactiveObject(ObjectType.Tile);
    }

    /// 
    /// 从池子取物体
    /// 
    /// 
    /// 
    public GameObject GetInactiveObject(ObjectType type)
    {
        switch (type)
        {
            case ObjectType.Tile:
                return tilePool.Dequeue();
            case ObjectType.Item:
                return itemPool.Dequeue();
            case ObjectType.Coin:
                return coinPool.Dequeue();
            case ObjectType.Enemy:
                return enemyPool.Dequeue();
            case ObjectType.Bullet:
                return bulletPool.Dequeue();
            default:
                return null;
        }
    }


在GameSetting中给每个砖块添加权重(生成的概率)

2.随机生成Tile(二)

给所有tile赋值,然后在GameManager中计算它们的权值并且随机生成

    //获取权值所有
    void GetAllWeight()
    {
        float sum = 0;
        sum += advance.normalTile.weight;
        sum += advance.brokenTile.weight;
        sum += advance.oneTimeOnly.weight;
        sum += advance.springTile.weight;
        sum += advance.movingVertically.weight;
        sum += advance.movingHorizontally.weight;
        totalsum = sum;
    }

    /// 
    /// 随机生成砖块
    /// 
    void GenerateTile()
    {
        GameObject go = GetInactiveObject(ObjectType.Tile);
        float rand = Random.Range(0, totalsum);
    }

    private void Start()
    {
        //sum赋值
        GetAllWeight();
        //初始化对象池
        GenerateTilePool();

        //生成物体
        for (int i = 0; i < initialSize; i++)
        {
            GenerateTile();
        }
    }

3.随机生成Tile(三)

GameManager中添加通过权值来设置tile类型的代码

    int SetTileByRandomNumber(float number)
    {
        if (number <= advance.normalTile.weight)
            return 0;
        else if (number <= (advance.normalTile.weight + advance.brokenTile.weight))
            return 1;
        else if (number <= (advance.normalTile.weight + advance.brokenTile.weight + advance.oneTimeOnly.weight))
            return 2;
        else if (number <= (advance.normalTile.weight + advance.brokenTile.weight + advance.oneTimeOnly.weight + advance.springTile.weight))
            return 3;
        else if (number <= (advance.normalTile.weight + advance.brokenTile.weight + advance.oneTimeOnly.weight + advance.springTile.weight + advance.movingHorizontally.weight))
            return 4;
        else if (number <= (advance.normalTile.weight + advance.brokenTile.weight + advance.oneTimeOnly.weight + advance.springTile.weight + advance.movingHorizontally.weight + advance.movingVertically.weight))
            return 5;

        return -1;
    }

4.随机生成Tile(四)

完善随机生成砖块

 /// 
    /// 随机生成砖块
    /// 
    void GenerateTile()
    {
        GameObject go = GetInactiveObject(ObjectType.Tile);
        float rand = Random.Range(0, totalsum);
        int randNumber = SetTileByRandomNumber(rand);

        Vector2 pos = new Vector2(Random.Range(-4.5f, 4.5f), currentY);
        switch (randNumber)
        {
            case 0:
                go.transform.position = pos;
                currentY += Random.Range(advance.normalTile.minHeight, advance.normalTile.maxHeight);
                go.name = "0";
                go.SetActive(true);
                break;
            case 1:
                go.transform.position = pos;
                currentY += Random.Range(advance.brokenTile.minHeight, advance.brokenTile.maxHeight);
                go.name = "1";
                go.SetActive(true);
                break;
            case 2:
                go.transform.position = pos;
                currentY += Random.Range(advance.oneTimeOnly.minHeight, advance.oneTimeOnly.maxHeight);
                go.name = "2";
                go.SetActive(true);
                break;
            case 3:
                go.transform.position = pos;
                currentY += Random.Range(advance.springTile.minHeight, advance.springTile.maxHeight);
                go.name = "3";
                go.SetActive(true);
                break;
            case 4:
                go.transform.position = pos;
                currentY += Random.Range(advance.movingHorizontally.minHeight, advance.movingHorizontally.maxHeight);
                go.name = "4";
                go.SetActive(true);
                break;
            case 5:
                go.transform.position = pos;
                currentY += Random.Range(advance.movingVertically.minHeight, advance.movingVertically.maxHeight);
                go.name = "5";
                go.SetActive(true);
                break;
            default:
                break;
        }
    }

运行程序如下

Unity案例课程 - 涂鸦跳跳 Day 2_第1张图片

5.回收Tile

在主相机下建立一个回收池

Unity案例课程 - 涂鸦跳跳 Day 2_第2张图片

在GameManager中添加下面的方法

public GameObject floor;
public void AddInActiveObjectToPool(GameObject go,ObjectType type)
    {
        go.SetActive(false);
        switch (type)
        {
            case ObjectType.Tile:
                tilePool.Enqueue(go);
                //TODO:生成tile
                break;
            case ObjectType.Item:
                itemPool.Enqueue(go);
                break;
            case ObjectType.Coin:
                coinPool.Enqueue(go);
                break;
            case ObjectType.Enemy:
                enemyPool.Enqueue(go);
                break;
            case ObjectType.Bullet:
                bulletPool.Enqueue(go);
                break;
            default:
                break;
        }
    }

在Tile中进行调用

    private void Update()
    {
        if (GameManager.Instance.floor.transform.position.y > transform.position.y + 1)
        {
            GetComponent().gravityScale = 0f;
            GameManager.Instance.AddInActiveObjectToPool(gameObject, ObjectType.Tile);
        }
    }

运行程序结果如下,下面的tile都被回收

Unity案例课程 - 涂鸦跳跳 Day 2_第3张图片

6.砖块水平竖直移动

在Tile脚本中添加代码,让tile可以自己移动

    //方块的移动速度和距离
    float speed;
    float distance;
    Vector3 startPos;
    int direction;  //0:left & up 1:right & down 
    void Init()
    {
        sp = GetComponent();
        tileType = int.Parse(gameObject.name);
        switch (tileType)
        {
            case 0:
                sp.sprite = sprites[0];
                break;
            case 1:
                sp.sprite = sprites[1];
                break;
            case 2:
                sp.sprite = sprites[2];
                break;
            case 3:
                sp.sprite = sprites[3];
                break;
            case 4:
                sp.sprite = sprites[4];
                speed = GameManager.Instance.advance.movingHorizontally.speed;
                distance = GameManager.Instance.advance.movingHorizontally.distance;
                startPos = transform.position;
                break;
            case 5:
                sp.sprite = sprites[5];
                speed = GameManager.Instance.advance.movingVertically.speed;
                distance = GameManager.Instance.advance.movingVertically.distance;
                startPos = transform.position;
                break;
            default:
                break;
        }
    }
    private void Update()
    {
        switch (tileType)
        {
            case 4:
                if (direction == 0)
                {
                    transform.Translate(new Vector2(-speed * Time.deltaTime, 0));
                    if (startPos.x - transform.position.x > distance)
                    {
                        direction = 1;
                    }
                }
                else
                {
                    transform.Translate(new Vector2(speed * Time.deltaTime, 0));
                    if (startPos.x - transform.position.x < -distance)
                    {
                        direction = 0;
                    }
                }
                break;
            case 5:
                if (direction == 0)
                {
                    transform.Translate(new Vector2(0,-speed * Time.deltaTime));
                    if (startPos.y - transform.position.y > distance)
                    {
                        direction = 1;
                    }
                }
                else
                {
                    transform.Translate(new Vector2(0,speed * Time.deltaTime));
                    if (startPos.y - transform.position.y < -distance)
                    {
                        direction = 0;
                    }
                }
                break;
            default:
                break;
        }
}

运行结果如下

Unity案例课程 - 涂鸦跳跳 Day 2_第4张图片Unity案例课程 - 涂鸦跳跳 Day 2_第5张图片

7.设置游戏状态

在GameManager中添加三种状态并添加游戏结束的代码

public enum GameState
{
    PAUSED,
    RUNNING,
    GAMEOVER
}
    //游戏状态
    public GameState gameState = GameState.PAUSED;
    //结束游戏
    public void EndGame()
    {
        if(gameState != GameState.GAMEOVER)
        {
            gameState = GameState.GAMEOVER;
            //TODO:save data UI
        }
    }

在Player脚本中进行调用

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.tag == "Platform")
        {
            Jump(1);
        }
        if(collision.tag == "Floor")
        {
            GameManager.Instance.EndGame();
        }
    }

运行程序结果如下

Unity案例课程 - 涂鸦跳跳 Day 2_第6张图片Unity案例课程 - 涂鸦跳跳 Day 2_第7张图片

8.无限生成Tile

在GameManager中添加重新生成tile的方法

    /// 
    /// 当一个tile销毁时,调用此方法
    /// 
    void CreateTile()
    {
        if(gameState != GameState.GAMEOVER)
        {
            GenerateTile();
            //添加道具
            //难度曲线
            //分数

        }
    }

并在砖块销毁的时候进行调用

Unity案例课程 - 涂鸦跳跳 Day 2_第8张图片

运行程序结果如下

Unity案例课程 - 涂鸦跳跳 Day 2_第9张图片

9.Item的开发(一)

在场景中创建道具并添加PowerUp的脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PowerUp : MonoBehaviour
{
    public int itemType;
    SpriteRenderer sp;

    //图片
    public Sprite[] sprites;
    //技能时间
    public float[] powerTime;

    private void OnEnable()
    {
        Init();
    }

    void Init()
    {
        sp = GetComponent();
        itemType = int.Parse(gameObject.name);
        sp.sprite = sprites[itemType];
    }
}

10.Item的开发(二)

完善PowerUp脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PowerUp : MonoBehaviour
{
    public int itemType;
    SpriteRenderer sp;

    //图片
    public Sprite[] sprites;
    //技能时间
    public float[] powerTime;
    //技能释放物体
    public GameObject[] used;

    GameObject player;

    private void OnEnable()
    {
        Init();
    }

    void Init()
    {
        sp = GetComponent();
        itemType = int.Parse(gameObject.name);
        sp.sprite = sprites[itemType];
    }

    public void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.tag == "Player")
        {
            player = collision.gameObject;
            //隐藏
            sp.enabled = false;
            //速度为0
            player.GetComponent().velocity = Vector2.zero;
            //让重力不影响我们的运动
            player.GetComponent().isKinematic = true;
            //无敌
            GetComponent().enabled = false;
            //显示图片
            used[itemType].SetActive(true);
            //fly
            StartCoroutine("StopFly");
        }
    }

    IEnumerator StopFly()
    {

    }
}

11.Item的开发(三)

完善PowerUp脚本,让Player添加道具飞行

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PowerUp : MonoBehaviour
{
    public int itemType;
    public SpriteRenderer sp;

    //图片
    public Sprite[] sprites;
    //技能时间
    public float[] powerTime;
    //技能释放物体
    public GameObject[] used;

    GameObject player;

    bool fly;

    private void OnEnable()
    {
        Init();
    }

    void Init()
    {
        sp.enabled = true;
        itemType = int.Parse(gameObject.name);
        sp.sprite = sprites[itemType];
        fly = false;
    }

    public void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.tag == "Player")
        {
            player = collision.gameObject;
            //隐藏
            sp.enabled = false;
            //速度为0
            player.GetComponent().velocity = Vector2.zero;
            //让重力不影响我们的运动
            player.GetComponent().isKinematic = true;
            //无敌
            GetComponent().enabled = false;
            //显示图片
            used[itemType].SetActive(true);
            //fly
            fly = true;
            StartCoroutine("StopFly");
        }
    }

    IEnumerator StopFly()
    {
        yield return new WaitForSeconds(powerTime[itemType]);
        player.GetComponent().isKinematic = false;
        GetComponent().enabled = true;
        used[itemType].SetActive(false);
        fly = false;
    }

    private void Update()
    {
        if (fly)
        {
            player.transform.Translate(new Vector2(0, 12 * Time.deltaTime));
        }
        else if (GameManager.Instance.floor.transform.position.y > transform.position.y + 1)
        {
            GameManager.Instance.AddInActiveObjectToPool(gameObject, ObjectType.Item);
        }
    }
}

运行程序结果如下

Unity案例课程 - 涂鸦跳跳 Day 2_第10张图片

 

 

你可能感兴趣的:(Unity3D)