首先说明一点,音乐节拍检测和弹幕生成要分开。因为节拍检测非常消耗性能,所以要提前做好节拍检测,记录下节拍的时间。在发射弹幕时去读取文件中的时间。另外如果发射的弹幕子弹数量比较多,建议使用对象池来优化性能。
读取节拍检测文件发射弹幕
前面的弹幕和节拍检测实现后,这里就比较简单了。只需要读取文件,到时间就发射弹幕就可以了。只是再发射弹幕的时候根据是否为高潮和声能比例,来发射不同弹幕,让游戏变的更有趣。可以自由发挥,这里放一下我设计的弹幕发射逻辑。
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;
}
}
}
}
}
}
网友评论