美文网首页
音乐弹幕的设计与实现(三)结合音乐节拍生成弹幕

音乐弹幕的设计与实现(三)结合音乐节拍生成弹幕

作者: 周末的游戏之旅 | 来源:发表于2019-08-07 11:28 被阅读0次

首先说明一点,音乐节拍检测和弹幕生成要分开。因为节拍检测非常消耗性能,所以要提前做好节拍检测,记录下节拍的时间。在发射弹幕时去读取文件中的时间。另外如果发射的弹幕子弹数量比较多,建议使用对象池来优化性能。

读取节拍检测文件发射弹幕

前面的弹幕和节拍检测实现后,这里就比较简单了。只需要读取文件,到时间就发射弹幕就可以了。只是再发射弹幕的时候根据是否为高潮和声能比例,来发射不同弹幕,让游戏变的更有趣。可以自由发挥,这里放一下我设计的弹幕发射逻辑。

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

public class EnemyShoot : MonoBehaviour
{

    //背景音乐
    AudioSource audio;
    //节拍时间
    Queue<float> beatTime = new Queue<float>();
    //是否高潮
    Queue<bool> isHight = new Queue<bool>();
    //散弹数量
    Queue<int> bulletNum = new Queue<int>();
    //子弹发射点
    Transform firePositon;
    //子弹持续时间
    float timer = 0;

    //子弹外观
    List<string> bulletNames = new List<string>();

    //初始累计时间
    float startTime = 0;

    //是否开始生成弹幕
    bool isSpawnBarrage;

    //两侧的点
    public Transform[] points;

    private void Awake()
    {
        audio = GetComponent<AudioSource>();

        firePositon = transform.GetChild(0);

        if (!File.Exists(Application.persistentDataPath + "/" + GameStorage.Instance.BeatFileName(GameStorage.Instance.UnLockCheckPoint)))
        {
            //如果数据库文件没有被创建,则创建数据库文件
            WWW loadDB = new WWW("jar:file://" + Application.dataPath + "!/assets/" + GameStorage.Instance.BeatFileName(GameStorage.Instance.UnLockCheckPoint));
            while (!loadDB.isDone)
            {
            }
            File.WriteAllBytes(Application.persistentDataPath + "/" + GameStorage.Instance.BeatFileName(GameStorage.Instance.UnLockCheckPoint), loadDB.bytes);
        }

        //读取文件
        StreamReader sr = new StreamReader(Application.persistentDataPath + "/" + GameStorage.Instance.BeatFileName(GameStorage.Instance.UnLockCheckPoint));
        Debug.Log(GameStorage.Instance.BeatFileName(GameStorage.Instance.UnLockCheckPoint));
        string s = string.Empty;
        while ((s = sr.ReadLine()) != null)
        {
            string[] str = s.Split(' ');
            beatTime.Enqueue(float.Parse(str[0]));
            isHight.Enqueue(bool.Parse(str[1]));
            bulletNum.Enqueue(int.Parse(str[2]));
        }
        Debug.Log(beatTime.Count);

        //初始化子类外观
        bulletNames.Add(ShootConst.ENEMYBLUEBULLET);
        bulletNames.Add(ShootConst.ENEMYPURPELBULLET);
        bulletNames.Add(ShootConst.ENEMYREDBULLET);
    }

    void Update()
    {
        if (CheckPointController.instance.isEnemyAttack && isSpawnBarrage == false)
        {
            //获取游戏开始到玩家可控之前的时间
            startTime = Time.time;
            //播放音乐
            audio.Play();
            //开始游戏
            isSpawnBarrage = true;
        }

        //音乐播放完毕
        if (isSpawnBarrage && Mathf.Abs(audio.time - audio.clip.length) <= 0.5f)
        {
            CheckPointController.instance.isOut = true;
            //敌人爆炸
            GetComponent<Enemy1>().EnemyBoom();
        }

        if (isSpawnBarrage)
        {
            timer -= Time.deltaTime;
            if (beatTime.Count > 0 && Time.time - startTime > beatTime.Peek())
            {
                //节拍出队
                beatTime.Dequeue();
                //高潮出队
                bool ish = isHight.Dequeue();
                //数量出队
                int num = bulletNum.Dequeue();
                //随机一个子弹外观
                int bulletID = Random.Range(0, GameStorage.Instance.UnLockCheckPoint);

                if (timer < 0)
                {
                    if (points != null && points.Length >= 2)
                    {
                        Barrage.instance.FanBarrage(bulletID, Mathf.Clamp(num, 1, 3), points[0].position);
                        Barrage.instance.FanBarrage(bulletID, Mathf.Clamp(num, 1, 3), points[1].position);
                    }

                    int i = ish ? Random.Range(1, 11) : Random.Range(1, 8);
                    if (i < 8)
                    {
                        //Barrage.instance.FanBarrage(Random.Range(1, 9), firePositon.position);
                        Barrage.instance.FanBarrage(bulletID, num, firePositon.position);
                        //beatTime.Dequeue();
                        timer = 0.05f;
                    }
                    else if (i < 10)
                    {
                        int k = Random.Range(2, 4);
                        Barrage.instance.ScatteredBarrage(bulletID, k, firePositon.position);
                        //beatTime.Dequeue();
                        timer = k / 2;
                    }
                    else
                    {

                        //Barrage.instance.SpiralBarrage(Random.Range(1, 2), firePositon.position);
                        Barrage.instance.SpiralBarrage(bulletID, 1, firePositon.position);
                        //beatTime.Dequeue();
                        timer = 1.5f;
                    }
                }
            }
        }
    }
}

相关文章

网友评论

      本文标题:音乐弹幕的设计与实现(三)结合音乐节拍生成弹幕

      本文链接:https://www.haomeiwen.com/subject/kefodctx.html