diff --git a/android/assets/music/Beat_8.mp3 b/android/assets/music/Beat_8.mp3 new file mode 100755 index 0000000..83d0158 Binary files /dev/null and b/android/assets/music/Beat_8.mp3 differ diff --git a/core/src/zero1hd/polyjet/audio/AudioAnalyzer.java b/core/src/zero1hd/polyjet/audio/AudioAnalyzer.java index 28749e1..aad969b 100755 --- a/core/src/zero1hd/polyjet/audio/AudioAnalyzer.java +++ b/core/src/zero1hd/polyjet/audio/AudioAnalyzer.java @@ -197,6 +197,7 @@ public class AudioAnalyzer { int lastID = 0; float bassBeats = 0; float umBeats = 0; + avgBPS = -1f; for (int i = 0; i < umPrunned.size-1 && work; i++) { bassPeaks.add((bassPrunned.get(i) > bassPrunned.get(i+1) ? bassPrunned.get(i) : 0)); if (bassPeaks.get(i) > bassMaxValue) { @@ -215,7 +216,6 @@ public class AudioAnalyzer { overlappedPeaks.add(0); } - avgBPS = -1f; if (avgBPS != -1) { if (bassPeaks.get(i) == 0) { @@ -235,13 +235,15 @@ public class AudioAnalyzer { umAvg += umPeaks.get(i); umBeats++; } + } //then we minus one from the beats so it actually works out avgBPS -= umPrunned.size-lastID; avgBPS *= secondsPerWindow; avgBPS /= bassBeats; - + Gdx.app.debug("Audio Analyzer", "Avg BPS: " + avgBPS); + bassAvg /= bassBeats; umBeats /= umBeats; diff --git a/core/src/zero1hd/polyjet/audio/WavAudioData.java b/core/src/zero1hd/polyjet/audio/WavAudioData.java index 37c2c74..ce9ef87 100755 --- a/core/src/zero1hd/polyjet/audio/WavAudioData.java +++ b/core/src/zero1hd/polyjet/audio/WavAudioData.java @@ -34,7 +34,7 @@ public class WavAudioData implements AudioData { @Override public void readIndexUpdate() { - readIndex = (int) (playbackMusic.getPosition() * decoder.getSampleRate() / readWindowSize); + readIndex = (int) (playbackMusic.getPosition() * decoder.getSampleRate() / (float)readWindowSize); } @Override diff --git a/core/src/zero1hd/polyjet/audio/map/EntitySpawnInfo.java b/core/src/zero1hd/polyjet/audio/map/EntitySpawnInfo.java index 9ccbef3..ae89dd1 100755 --- a/core/src/zero1hd/polyjet/audio/map/EntitySpawnInfo.java +++ b/core/src/zero1hd/polyjet/audio/map/EntitySpawnInfo.java @@ -4,9 +4,9 @@ import zero1hd.polyjet.entity.Entities; public class EntitySpawnInfo { private Entities entityType; - private double[] parameters; + private float[] parameters; - public EntitySpawnInfo(Entities entityType, double... parameters) { + public EntitySpawnInfo(Entities entityType, float... parameters) { this.entityType = entityType; this.parameters = parameters; } @@ -19,4 +19,8 @@ public class EntitySpawnInfo { public String toString() { return entityType.name() + ": " + parameters.length; } + + public float[] getParameters() { + return parameters; + } } diff --git a/core/src/zero1hd/polyjet/audio/map/GamePlayMap.java b/core/src/zero1hd/polyjet/audio/map/GamePlayMap.java index f5f730e..a004de0 100755 --- a/core/src/zero1hd/polyjet/audio/map/GamePlayMap.java +++ b/core/src/zero1hd/polyjet/audio/map/GamePlayMap.java @@ -1,5 +1,6 @@ package zero1hd.polyjet.audio.map; +import com.badlogic.gdx.Gdx; import com.badlogic.gdx.audio.Music; import com.badlogic.gdx.utils.Array; @@ -7,19 +8,17 @@ import zero1hd.polyjet.audio.AudioData; import zero1hd.polyjet.entity.Entities; public class GamePlayMap { - private Music playableClip; + private AudioData playableClip; private float playTime; private Array spawnList; private boolean building; private int index; - /** * GamePlayMap is what the game area will use to generate entities and judge current audio data * @param audioData audio data */ public GamePlayMap(AudioData audioData) { - playableClip = audioData.getPlaybackMusic(); - playTime = audioData.getDuration(); + this.playableClip = audioData; spawnList = new Array<>(); } @@ -28,7 +27,7 @@ public class GamePlayMap { * @return */ public Music getPlayableClip() { - return playableClip; + return playableClip.getPlaybackMusic(); } /** @@ -60,7 +59,7 @@ public class GamePlayMap { * @param entityType what type of entity to spawn * @param parameters the arguments for the entity. It is important to have the same amount of parameters the entity requires to spawn */ - public void addToMap(Entities entityType, double... parameters) { + public void addToMap(Entities entityType, float... parameters) { if (building && entityType != null && parameters != null) { spawnList.add(new EntitySpawnInfo(entityType, parameters)); } @@ -80,10 +79,11 @@ public class GamePlayMap { * retrieve next entity in list. * @return */ - public EntitySpawnInfo nextEntity() { + public EntitySpawnInfo nextEntity(boolean indexUpdate) { if (!building) { - index++; - + if (indexUpdate) { + index++; + } EntitySpawnInfo spawnInfo = spawnList.get(index); return spawnInfo; } else { @@ -91,6 +91,16 @@ public class GamePlayMap { } } + public EntitySpawnInfo safeNextEntity() { + playableClip.readIndexUpdate(); + if (index != playableClip.getReadIndex()) { + index = playableClip.getReadIndex(); + return nextEntity(false); + } else { + return null; + } + } + /** * set retrieve entity index position. * @param index diff --git a/core/src/zero1hd/polyjet/audio/map/RhythmMapAlgorithm.java b/core/src/zero1hd/polyjet/audio/map/RhythmMapAlgorithm.java index 15d3c50..9c53330 100755 --- a/core/src/zero1hd/polyjet/audio/map/RhythmMapAlgorithm.java +++ b/core/src/zero1hd/polyjet/audio/map/RhythmMapAlgorithm.java @@ -60,17 +60,21 @@ public class RhythmMapAlgorithm implements Runnable { ); } if (bassPeaks.get(index) != 0) { +// float xSpawnLocation = (rand.nextFloat()*(Polyjet.GAME_AREA_WIDTH-2))+1; +// map.addToMap(Entities.PELLET, +// xSpawnLocation, +// Polyjet.GAME_AREA_HEIGHT-0.25f, +// 180*rand.nextFloat()+90, +// speedMod*(1f/avgBPS)); + map.addToMap(Entities.BAR, - MathUtils.round(rand.nextFloat()*Polyjet.GAME_AREA_WIDTH), - ((Polyjet.GAME_AREA_HEIGHT-bassPeaks.get(index)*Polyjet.GAME_AREA_HEIGHT)/avgBPS)*speedMod); + MathUtils.round(3), + (1.5f/avgBPS)*speedMod); } else { if (UMPeaks.get(index) != 0) { - float xSpawnLocation = (rand.nextFloat()*(Polyjet.GAME_AREA_WIDTH-2))+1; - map.addToMap(Entities.PELLET, - xSpawnLocation, - Polyjet.GAME_AREA_HEIGHT-0.25f, - 180+180*rand.nextFloat(), - speedMod*(Polyjet.GAME_AREA_HEIGHT/3)/avgBPS); +// map.addToMap(Entities.BAR, +// MathUtils.round(3), +// (1.5f/avgBPS)*speedMod); } } diff --git a/core/src/zero1hd/polyjet/entity/EntityController.java b/core/src/zero1hd/polyjet/entity/EntityController.java index c7bf479..a1babbb 100755 --- a/core/src/zero1hd/polyjet/entity/EntityController.java +++ b/core/src/zero1hd/polyjet/entity/EntityController.java @@ -1,10 +1,15 @@ package zero1hd.polyjet.entity; +import java.util.Arrays; + +import com.badlogic.gdx.Gdx; import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.scenes.scene2d.Stage; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Pool; +import zero1hd.polyjet.audio.map.EntitySpawnInfo; import zero1hd.polyjet.entity.ally.Laser; import zero1hd.polyjet.entity.enemies.Bar; import zero1hd.polyjet.entity.enemies.Flake; @@ -106,6 +111,61 @@ public class EntityController { } } + public Entity spawnEntity(Stage stage, EntitySpawnInfo entitySpawnInfo) { + if (entitySpawnInfo != null) { + float[] param = entitySpawnInfo.getParameters(); + Gdx.app.debug("Spawning Entity", entitySpawnInfo.toString() + " parameters: " + Arrays.toString(param)); + switch (entitySpawnInfo.getEntityType()) { + case VOID_CIRCLE: + VoidCircle voidCircle = voidCirclePool.obtain(); + voidCircle.init(param[0], param[1], param[2], param[3], param[4]); + activeEnemies.add(voidCircle); + stage.addActor(voidCircle); + return voidCircle; + case LASER: + Laser laser = laserPool.obtain(); + laser.init(param[0], param[1], param[2]); + activeAllies.add(laser); + stage.addActor(laser); + return laser; + case PELLET: + Pellet pellet = pelletPool.obtain(); + pellet.init(param[0], param[1], param[2], param[3]); + activeEnemies.add(pellet); + stage.addActor(pellet); + return pellet; + case SHARD: + Shard shard = shardPool.obtain(); + shard.init(param[0], param[1], param[2], param[3], (int) param[4]); + activeEnemies.add(shard); + stage.addActor(shard); + return shard; + case BAR: + Bar bar = barPool.obtain(); + bar.init(param[0], param[1]); + activeEnemies.add(bar); + stage.addActor(bar); + return bar; + case FLAKE: + Flake flake = flakePool.obtain(); + Shard[] shards = new Shard[(int) param[0]]; + for (int i = 0; i < shards.length; i++) { + shards[i] = (Shard) retrieveEntity(Entities.SHARD); + shards[i].init(param[6], param[7], param[8], param[9], (int) param[10]); + stage.addActor(shards[i]); + } + flake.init(param[1], param[2], param[3], param[4], param[5], shards); + activeEnemies.add(flake); + stage.addActor(flake); + return flake; + default: + return null; + } + } else { + return null; + } + } + public void free(Entity entity) { if (entity.getEntityType().isEnemy()) { activeEnemies.removeValue(entity, true); diff --git a/core/src/zero1hd/polyjet/ui/pages/AnalyzePage.java b/core/src/zero1hd/polyjet/ui/pages/AnalyzePage.java index 16cc8c0..edbc1b1 100755 --- a/core/src/zero1hd/polyjet/ui/pages/AnalyzePage.java +++ b/core/src/zero1hd/polyjet/ui/pages/AnalyzePage.java @@ -94,10 +94,10 @@ public class AnalyzePage extends Page implements MiniListener { speedModifier.addListener(new ChangeListener() { @Override public void changed(ChangeEvent event, Actor actor) { - speedModifierTitle.setText("Speed Modifier: " + speedModifier.getValue()); + speedModifierTitle.setText("Speed Modifier: x" + speedModifier.getValue()); } }); - speedModifierTitle = new Label("Speed Modifier: " + speedModifier.getValue(), skin, "sub-font", skin.getColor("default")); + speedModifierTitle = new Label("Speed Modifier: x" + speedModifier.getValue(), skin, "sub-font", skin.getColor("default")); difficultyTable.add(speedModifierTitle); difficultyTable.row(); difficultyTable.add(speedModifier).fillX(); @@ -110,10 +110,10 @@ public class AnalyzePage extends Page implements MiniListener { @Override public void changed(ChangeEvent event, Actor actor) { - healthModifierTitle.setText("Health modifier: " + healthModifier.getValue()); + healthModifierTitle.setText("Health modifier: +" + healthModifier.getValue()); } }); - healthModifierTitle = new Label("Health modifier: " + healthModifier.getValue(), skin, "sub-font", skin.getColor("default")); + healthModifierTitle = new Label("Health modifier: +" + healthModifier.getValue(), skin, "sub-font", skin.getColor("default")); difficultyTable.add(healthModifierTitle); difficultyTable.row(); difficultyTable.add(healthModifier).fillX().spaceBottom(15f); @@ -143,7 +143,7 @@ public class AnalyzePage extends Page implements MiniListener { beginTable = new Table(skin); beginTable.pad(15f); - beginButton = new TextButton("Begin!", skin); + beginButton = new TextButton("Begin", skin); beginTable.add(beginButton); beginTable.setBackground(skin.getDrawable("large-pane")); beginTable.pack(); diff --git a/core/src/zero1hd/polyjet/ui/stages/CreativeStage.java b/core/src/zero1hd/polyjet/ui/stages/CreativeStage.java index 764e818..b3fa4b6 100755 --- a/core/src/zero1hd/polyjet/ui/stages/CreativeStage.java +++ b/core/src/zero1hd/polyjet/ui/stages/CreativeStage.java @@ -42,7 +42,9 @@ public class CreativeStage extends Stage implements MiniListener { RhythmMapAlgorithm mapGen; Window toolbox; + GamePlayArea gpa; public CreativeStage(final Polyjet core, final MainMenu mainMenu, final GamePlayArea gpa) { + this.gpa = gpa; musicSelector = new MusicSelector("Select Audio File", core.getDefaultSkin(), core.getPrefs().getString("music dir"), "default"); musicSelector.miniSender.addListener(this); musicSelector.refresh(); @@ -247,15 +249,20 @@ public class CreativeStage extends Stage implements MiniListener { analyzer.runThresholdCleaning(diffWindow.getSensitivityVal()); break; case MUSIC_DATA_CLEANED: - mapGen = new RhythmMapAlgorithm(analyzer, diffWindow.getSpeedModifier(), diffWindow.getHealthModifier()); - Thread mapGenThread = new Thread(mapGen); - mapGenThread.start(); + if (analyzer != null && analyzer.isFinalized()) { + mapGen = new RhythmMapAlgorithm(analyzer, diffWindow.getSpeedModifier(), diffWindow.getHealthModifier()); + mapGen.getSender().addListener(this); + Thread mapGenThread = new Thread(mapGen); + mapGenThread.start(); + } break; case MAP_GENERATED: - musicPlayBackControls.setAudiofile(musicSelector.getSelectedMusic()); - volumeWindow.setMusic(musicPlayBackControls.getAudiofile()); - beatViewer.setMusic(musicPlayBackControls.getAudiofile(), analyzer); - graphViewer.setData(analyzer.getBassPeaks(), analyzer.getUMPeaks(), musicPlayBackControls.getAudiofile()); + Gdx.app.debug("creative", "successfully generated map."); + musicPlayBackControls.setAudiofile(analyzer.getAudioData()); + volumeWindow.setMusic(analyzer.getAudioData()); + beatViewer.setMusic(analyzer.getAudioData(), analyzer); + graphViewer.setData(analyzer.getBassPeaks(), analyzer.getUMPeaks(), analyzer.getAudioData()); + gpa.setAudioMap(mapGen.getMap()); break; default: break; diff --git a/core/src/zero1hd/polyjet/ui/stages/GamePlayArea.java b/core/src/zero1hd/polyjet/ui/stages/GamePlayArea.java index 19fcac1..194ac85 100755 --- a/core/src/zero1hd/polyjet/ui/stages/GamePlayArea.java +++ b/core/src/zero1hd/polyjet/ui/stages/GamePlayArea.java @@ -98,6 +98,8 @@ public class GamePlayArea extends Stage { //TODO batch draw background getBatch().begin(); + + if (bgShader != null) { getBatch().setShader(bgShader); bgShader.setUniformf("resolution", background.getWidth(), background.getHeight()); @@ -117,7 +119,9 @@ public class GamePlayArea extends Stage { if (audioMap != null && time < audioMap.getPlayTime()) { time += delta; } - + if (audioMap != null) { + ec.spawnEntity(this, audioMap.safeNextEntity()); + } collisionDetector.collisionCheck(); ec.deathClean(); diff --git a/core/src/zero1hd/polyjet/ui/windows/MusicSelector.java b/core/src/zero1hd/polyjet/ui/windows/MusicSelector.java index 8901773..aac1f90 100755 --- a/core/src/zero1hd/polyjet/ui/windows/MusicSelector.java +++ b/core/src/zero1hd/polyjet/ui/windows/MusicSelector.java @@ -9,6 +9,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Skin; import com.badlogic.gdx.scenes.scene2d.ui.TextButton; import com.badlogic.gdx.scenes.scene2d.ui.Window; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener.ChangeEvent; import com.badlogic.gdx.utils.Array; import zero1hd.polyjet.audio.Audio; @@ -50,7 +51,16 @@ public class MusicSelector extends Window { miniSender.send(MiniEvents.MUSIC_SELECTED); } }); - add(confirmButton).right(); + add(confirmButton); + TextButton regenMap = new TextButton("regen map", skin); + regenMap.addListener(new ChangeListener() { + + @Override + public void changed(ChangeEvent event, Actor actor) { + miniSender.send(MiniEvents.MUSIC_DATA_CLEANED); + } + }); + add(regenMap); row(); diff --git a/core/src/zero1hd/polyjet/ui/windows/VolumeWindow.java b/core/src/zero1hd/polyjet/ui/windows/VolumeWindow.java index 341b7f6..374f431 100755 --- a/core/src/zero1hd/polyjet/ui/windows/VolumeWindow.java +++ b/core/src/zero1hd/polyjet/ui/windows/VolumeWindow.java @@ -69,5 +69,6 @@ public class VolumeWindow extends Window { public void setMusic(AudioData music) { this.music = music; + music.getPlaybackMusic().setVolume(prefs.getFloat("music vol")/100f); } }