//makes the dml map for the Wave public string MakeMap() { string map="";//starts as nothing memblock block;//block memory containing sound information (or pointers to it) //goes through the Wave and keeps track of energy levels at points in time for (int i = 0; i < soundInformation.Length; i++) { block = wave.next(wavAudio.framesAvailable());//looks at the next memblock in the Wave soundInformation[i] = new SoundInfo(false, Math.Abs(wave.getStereoObject(block).getAvg()));//saves the energy level } wave.reset();//resets the wave (so you're looking at the first memblock again) //goes through the SBD object and keeps track of if there is a beat at each point in time for (int i = 0; i < soundInformation.Length; i++) { //if statement needed since the lengths of SBD and wave are always 1 or 2 off from eachother if (SBD.hasNext()) { soundInformation[i].isBeat = SBD.next() != 0; } else { soundInformation[i].isBeat = false; } } SBD.release(); wave.reset(); //defines the 2 bullets that will be used map+=DefineGenericBullet("Standard", "bullets/circle10r12g0080ff", 90, 5); map += DefineGenericBullet("HighLeeway", "bullets/circle10r12g0080ff", 90, 5, 40); //begins the dml timeline string timeline = "Timeline <"; //starts the update for left and right generator bullets in the top corners of the screen //they are only there to BurstSpawn since it's not implemented in the timeline string leftGenUpdate = ""; string rightGenUpdate = ""; int waveSize = 0;//number of bullets that would be spawned in a wave int consecutiveBeatCount = 0;//consecutives beats after this point int curSweepCount = 0;//how many sweeps are currently spawning int curLineCount = 0;//how many lines are currently spawning int countReleaseTime = 0;//when the previous 2 counts can be set back to 0 int burstBulCount = 0;//minimum number of bullets that would be spawned in a burst DirectedSpawnLocation curDSL;//current spawn location for a specific pattern //spawns the LeftGen and RightGen bullets timeline += "\r\n"; timeline += SpawnBullet(1, 0, "LeftGen", new Vector2(-10, 0)); timeline += "\r\n"; timeline += SpawnBullet(1, 0, "RightGen", new Vector2(Options.Resolutions.X + 10, 0)); //note that every spot represents approximately 1/10 of a second //goes through each piece of sound information in the song for (int i = 0; i < soundInformation.Count(); i++) { //checks if this point in time is a beat if (soundInformation[i].isBeat) { // if (i == countReleaseTime) { curSweepCount = 0; curLineCount = 0; } //checks if the next few times are also beats, if so, spawn a wave or a line of bullets instead of the regular mishmash for (int j = 0; j < 15; j++) { if (i + j < soundInformation.Count() && soundInformation[i + j].isBeat) { consecutiveBeatCount = j;//so i don't have to reset it } else { break; } } //if there are some consecutive beats if (consecutiveBeatCount > 5) { countReleaseTime = i + consecutiveBeatCount;//sets the time when the lines and sweeps won't be spawning curDSL = spawnLocations[Globals.randGen.Next(0, 5)];//chooses a location to spawn the line/sweep //1/3 chance of spawning each time //random generator doesn't really stop a line from spawning, it just makes it more likely spawn later since consecutivebeatcount is only 1 lower from //the next spot in soundinformation, which is usually over 5 //only 3 lines can be spawning at once if (Globals.randGen.Next(0, 3) == 0 && curLineCount < 3) { curLineCount++; timeline += SpawnLine(1,//1 indent in i * scale,//start time converted to ms (i + consecutiveBeatCount) * scale,//end time converted to ms consecutiveBeatCount,//1 bullet for each beat "Standard",//standard bullets curDSL.location,//spawning from a prechosen location Globals.randGen.Next(curDSL.minAngle, curDSL.maxAngle + 1),//randomly chosen angle between 2 bounds based on location soundInformation[i].speed);//the pregenerated speed for that time } //1/3 chance of spawning each time //only 3 sweeps can be spawning at once if (Globals.randGen.Next(0, 3) == 0 && curSweepCount < 3) { curSweepCount++; //direction the sweep sweeps is chosen based on position if (curDSL.location.X < Options.Resolutions.X / 2) { timeline += SpawnSweep(1,//1 indent in i * scale,//start time converted to ms (i + consecutiveBeatCount) * scale,//end time converted to ms consecutiveBeatCount * 2,//2 bullets for each beat "Standard",//standard bullets curDSL.location,//spawning from a prechosen location 30,150,//sweeps sweep across the map so they don't use the normal bounds for their spawn location -1,//if it's spawning from the left, it goes counterclockwise soundInformation[i].speed);//the pregenerated speed for that time } else if (curDSL.location.X == Options.Resolutions.X / 2) { timeline += SpawnSweep(1, i * scale, (i + consecutiveBeatCount) * scale, consecutiveBeatCount * 2, "Standard", curDSL.location, 30, 150, 2 * Globals.randGen.Next(0, 2) - 1,//if it's spawning from the middle, it goes a random direction soundInformation[i].speed); } else if (curDSL.location.X > Options.Resolutions.X / 2) { timeline += SpawnSweep(1, i * scale, (i + consecutiveBeatCount) * scale, consecutiveBeatCount * 2, "Standard", curDSL.location, 30, 150, 1,//if it's spawning from the right, it goes clockwise soundInformation[i].speed); } } } timeline += "\r\n"; //1/2 chance to spawn a wave if (Globals.randGen.Next(0, 2) == 0) { //calculates what the wavesize would be before spawning waveSize = (int)(soundInformation[i].energyLevel / 5000) + 3; if (waveSize > 5) { curDSL = spawnLocations[Globals.randGen.Next(0, 5)]; timeline += SpawnWave(1, i * scale, waveSize, "HighLeeway",//needs a higher leeway since some bullets may start outside the regular leeway (int)(soundInformation[i].energyLevel / 500) + 50,//spawnpoint distance from origin spawn point decided by energylevel+constant curDSL.location - new Vector2(0, 50),//origin is 50 units up from the regular spawnpoints Globals.randGen.Next(curDSL.minAngle, curDSL.maxAngle + 1),//kept within the normal angle bounds soundInformation[i].speed - 1.5);//wave is meant to be slower than normal bullets } } //if this point in time is significantly louder than the last second if (0 <= i - 10 && soundInformation[i].energyLevel > 4 * AverageEnergyInRange(soundInformation, i - 10, i)) { //calculates the minimum amount of bullets in the burst would be burstBulCount = (int)(soundInformation[i].energyLevel / 3000); if (burstBulCount > 5) { //writes the burst to the Update of the generator bullets //both bursts happen at the same time leftGenUpdate += "\r\n"; leftGenUpdate += SpawnBurst(2, i * scale, burstBulCount, "Standard", 20, 60, burstBulCount, burstBulCount + 4);//the speed of the bullets is also aproximately how many there are expected to be rightGenUpdate += "\r\n"; rightGenUpdate += SpawnBurst(2, i * scale, burstBulCount, "Standard", 120, 160, burstBulCount, burstBulCount + 4); } } timeline += "\r\n"; //it will always spawn a ring when there's a beat curDSL = spawnLocations[Globals.randGen.Next(0, 5)]; //where it's spawned is decided at random timeline += SpawnRing(1, i * scale, Globals.randGen.Next(8, 12) + (int)(soundInformation[i].energyLevel / 1000), //how many spawned decided by energy level and some randomness "Standard", curDSL.location, soundInformation[i].speed, Globals.randGen.Next(-30, 31)); //its shift is also random } } timeline += "\r\n>"; //adds the definitions for the generator bullets map+=String.Format(DefineGeneratorBullet("LeftGen"), leftGenUpdate); map+="\r\n"; map+=String.Format(DefineGeneratorBullet("RightGen"), rightGenUpdate); map+="\r\n"; //adds the timeline map+=timeline; return map; }
//makes the dml map for the Wave public string MakeMap() { string map = ""; //starts as nothing memblock block; //block memory containing sound information (or pointers to it) //goes through the Wave and keeps track of energy levels at points in time for (int i = 0; i < soundInformation.Length; i++) { block = wave.next(wavAudio.framesAvailable()); //looks at the next memblock in the Wave soundInformation[i] = new SoundInfo(false, Math.Abs(wave.getStereoObject(block).getAvg())); //saves the energy level } wave.reset();//resets the wave (so you're looking at the first memblock again) //goes through the SBD object and keeps track of if there is a beat at each point in time for (int i = 0; i < soundInformation.Length; i++) { //if statement needed since the lengths of SBD and wave are always 1 or 2 off from eachother if (SBD.hasNext()) { soundInformation[i].isBeat = SBD.next() != 0; } else { soundInformation[i].isBeat = false; } } SBD.release(); wave.reset(); //defines the 2 bullets that will be used map += DefineGenericBullet("Standard", "bullets/circle10r12g0080ff", 90, 5); map += DefineGenericBullet("HighLeeway", "bullets/circle10r12g0080ff", 90, 5, 40); //begins the dml timeline string timeline = "Timeline <"; //starts the update for left and right generator bullets in the top corners of the screen //they are only there to BurstSpawn since it's not implemented in the timeline string leftGenUpdate = ""; string rightGenUpdate = ""; int waveSize = 0; //number of bullets that would be spawned in a wave int consecutiveBeatCount = 0; //consecutives beats after this point int curSweepCount = 0; //how many sweeps are currently spawning int curLineCount = 0; //how many lines are currently spawning int countReleaseTime = 0; //when the previous 2 counts can be set back to 0 int burstBulCount = 0; //minimum number of bullets that would be spawned in a burst DirectedSpawnLocation curDSL; //current spawn location for a specific pattern //spawns the LeftGen and RightGen bullets timeline += "\r\n"; timeline += SpawnBullet(1, 0, "LeftGen", new Vector2(-10, 0)); timeline += "\r\n"; timeline += SpawnBullet(1, 0, "RightGen", new Vector2(Options.Resolutions.X + 10, 0)); //note that every spot represents approximately 1/10 of a second //goes through each piece of sound information in the song for (int i = 0; i < soundInformation.Count(); i++) { //checks if this point in time is a beat if (soundInformation[i].isBeat) { // if (i == countReleaseTime) { curSweepCount = 0; curLineCount = 0; } //checks if the next few times are also beats, if so, spawn a wave or a line of bullets instead of the regular mishmash for (int j = 0; j < 15; j++) { if (i + j < soundInformation.Count() && soundInformation[i + j].isBeat) { consecutiveBeatCount = j;//so i don't have to reset it } else { break; } } //if there are some consecutive beats if (consecutiveBeatCount > 5) { countReleaseTime = i + consecutiveBeatCount; //sets the time when the lines and sweeps won't be spawning curDSL = spawnLocations[Globals.randGen.Next(0, 5)]; //chooses a location to spawn the line/sweep //1/3 chance of spawning each time //random generator doesn't really stop a line from spawning, it just makes it more likely spawn later since consecutivebeatcount is only 1 lower from //the next spot in soundinformation, which is usually over 5 //only 3 lines can be spawning at once if (Globals.randGen.Next(0, 3) == 0 && curLineCount < 3) { curLineCount++; timeline += SpawnLine(1, //1 indent in i * scale, //start time converted to ms (i + consecutiveBeatCount) * scale, //end time converted to ms consecutiveBeatCount, //1 bullet for each beat "Standard", //standard bullets curDSL.location, //spawning from a prechosen location Globals.randGen.Next(curDSL.minAngle, curDSL.maxAngle + 1), //randomly chosen angle between 2 bounds based on location soundInformation[i].speed); //the pregenerated speed for that time } //1/3 chance of spawning each time //only 3 sweeps can be spawning at once if (Globals.randGen.Next(0, 3) == 0 && curSweepCount < 3) { curSweepCount++; //direction the sweep sweeps is chosen based on position if (curDSL.location.X < Options.Resolutions.X / 2) { timeline += SpawnSweep(1, //1 indent in i * scale, //start time converted to ms (i + consecutiveBeatCount) * scale, //end time converted to ms consecutiveBeatCount * 2, //2 bullets for each beat "Standard", //standard bullets curDSL.location, //spawning from a prechosen location 30, 150, //sweeps sweep across the map so they don't use the normal bounds for their spawn location -1, //if it's spawning from the left, it goes counterclockwise soundInformation[i].speed); //the pregenerated speed for that time } else if (curDSL.location.X == Options.Resolutions.X / 2) { timeline += SpawnSweep(1, i * scale, (i + consecutiveBeatCount) * scale, consecutiveBeatCount * 2, "Standard", curDSL.location, 30, 150, 2 * Globals.randGen.Next(0, 2) - 1,//if it's spawning from the middle, it goes a random direction soundInformation[i].speed); } else if (curDSL.location.X > Options.Resolutions.X / 2) { timeline += SpawnSweep(1, i * scale, (i + consecutiveBeatCount) * scale, consecutiveBeatCount * 2, "Standard", curDSL.location, 30, 150, 1,//if it's spawning from the right, it goes clockwise soundInformation[i].speed); } } } timeline += "\r\n"; //1/2 chance to spawn a wave if (Globals.randGen.Next(0, 2) == 0) { //calculates what the wavesize would be before spawning waveSize = (int)(soundInformation[i].energyLevel / 5000) + 3; if (waveSize > 5) { curDSL = spawnLocations[Globals.randGen.Next(0, 5)]; timeline += SpawnWave(1, i * scale, waveSize, "HighLeeway", //needs a higher leeway since some bullets may start outside the regular leeway (int)(soundInformation[i].energyLevel / 500) + 50, //spawnpoint distance from origin spawn point decided by energylevel+constant curDSL.location - new Vector2(0, 50), //origin is 50 units up from the regular spawnpoints Globals.randGen.Next(curDSL.minAngle, curDSL.maxAngle + 1), //kept within the normal angle bounds soundInformation[i].speed - 1.5); //wave is meant to be slower than normal bullets } } //if this point in time is significantly louder than the last second if (0 <= i - 10 && soundInformation[i].energyLevel > 4 * AverageEnergyInRange(soundInformation, i - 10, i)) { //calculates the minimum amount of bullets in the burst would be burstBulCount = (int)(soundInformation[i].energyLevel / 3000); if (burstBulCount > 5) { //writes the burst to the Update of the generator bullets //both bursts happen at the same time leftGenUpdate += "\r\n"; leftGenUpdate += SpawnBurst(2, i * scale, burstBulCount, "Standard", 20, 60, burstBulCount, burstBulCount + 4);//the speed of the bullets is also aproximately how many there are expected to be rightGenUpdate += "\r\n"; rightGenUpdate += SpawnBurst(2, i * scale, burstBulCount, "Standard", 120, 160, burstBulCount, burstBulCount + 4); } } timeline += "\r\n"; //it will always spawn a ring when there's a beat curDSL = spawnLocations[Globals.randGen.Next(0, 5)]; //where it's spawned is decided at random timeline += SpawnRing(1, i * scale, Globals.randGen.Next(8, 12) + (int)(soundInformation[i].energyLevel / 1000), //how many spawned decided by energy level and some randomness "Standard", curDSL.location, soundInformation[i].speed, Globals.randGen.Next(-30, 31)); //its shift is also random } } timeline += "\r\n>"; //adds the definitions for the generator bullets map += String.Format(DefineGeneratorBullet("LeftGen"), leftGenUpdate); map += "\r\n"; map += String.Format(DefineGeneratorBullet("RightGen"), rightGenUpdate); map += "\r\n"; //adds the timeline map += timeline; return(map); }
//returns the average energy level of a list of SoundInfo between 2 indices private double AverageEnergyInRange(SoundInfo[] soundInformation, int startIndex, int endIndex) { double total = 0; for (int i = startIndex; i < endIndex; i++) { total += soundInformation[i].energyLevel; } return total / (endIndex - startIndex); }