diff --git a/res/levels/test.level b/res/levels/test.level index 2931038..1d572bf 100644 --- a/res/levels/test.level +++ b/res/levels/test.level @@ -2,10 +2,10 @@ name:Lustiger Levelname backgroundMusic:music/bla.wav background:FooBackground - -[0-2025] -spawn:GegnerOne,2,6 -[2026-2168] -spawn:GegnerOne,2,4 -spawn:GegnerTwo,5,6 -[2169-2170] -spawn:BossGegner,1,1 \ No newline at end of file +[0-20] +spawn:EnemyTwo,2,2 +[21-25] +spawn:EnemyThree,2,4 +spawn:EnemyTwo,5,6 +[26-30] +spawn:EnemyBoss,1,1 \ No newline at end of file diff --git a/src/de/teamteamteam/spacescooter/level/Level.java b/src/de/teamteamteam/spacescooter/level/Level.java index c57e99b..e99f5d4 100644 --- a/src/de/teamteamteam/spacescooter/level/Level.java +++ b/src/de/teamteamteam/spacescooter/level/Level.java @@ -9,9 +9,10 @@ import de.teamteamteam.spacescooter.entity.enemy.EnemyOne; import de.teamteamteam.spacescooter.entity.enemy.EnemyThree; import de.teamteamteam.spacescooter.entity.enemy.EnemyTwo; import de.teamteamteam.spacescooter.entity.Entity; -import de.teamteamteam.spacescooter.entity.Entity.availableNames; import de.teamteamteam.spacescooter.screen.GameScreen; +import de.teamteamteam.spacescooter.utility.GameConfig; import de.teamteamteam.spacescooter.utility.Loader; +import de.teamteamteam.spacescooter.utility.Random; /** * Implementation of the actual level based gameplay logic. @@ -31,13 +32,14 @@ public final class Level { * Internal levelClock counter thing. * This is the "level time, we will use in our configs and such. */ - private long levelClock; + private int levelClock; /** * Constructor creating a LevelConfig based on a given config file. */ public Level(String levelConfig) { + this.levelClock = 0; this.config = Loader.getLevelConfigByFilename(levelConfig); System.out.println(this.config); } @@ -49,7 +51,6 @@ public final class Level { public void doBuildUp() { new StarBackground(0, 50); GameScreen.setPlayer(new Player(200, 300)); - } /** @@ -73,7 +74,37 @@ public final class Level { if (Keyboard.isKeyDown(KeyEvent.VK_0)) { new EnemyBoss(400,400); } + //Increase levelClock this.levelClock++; + //Check whether the current interval is configured + int currentIntervalIndex = this.config.getIntervalIndexByCurrentTime(this.levelClock); + if(currentIntervalIndex == -1) return; //Nothing to do + //Fetch the current interval + int[] currentInterval = this.config.intervalList.get(currentIntervalIndex); + int relativeTimeWithinCurrentInterval = this.levelClock - currentInterval[0]; + int intervalLength = currentInterval[1] - currentInterval[0]; + /* + * @see + * Get all the spawnrules for the current interval. + * - 0: Interval this rule belongs to + * - 1: EntityNumber - This helps to find out what Entity to actually spawn. + * - 2: Amount - The amount of Entities to spawn at a time. + * - 3: SpawnRate - The rate at which the Entities are supposed to be spawned. + */ + for(int[] spawnrule : this.config.spawnRuleList) { + //Skip spawn rules that are not in the current spawn interval. + if(spawnrule[0] != currentIntervalIndex) continue; + //Divide the current interval by spawnrate + int intervalModulus = intervalLength / spawnrule[3]; + //Check whether the spawn rate strikes right now. + if(relativeTimeWithinCurrentInterval % Math.max(1,intervalModulus) == 0) { + //If the rule matches the current time, spawn the configured Entity in the configured amount: + for(int i=0; i ruleList; + public List spawnRuleList; public LevelConfig() { this.intervalList = new ArrayList(); - this.ruleList = new ArrayList(); + this.spawnRuleList = new ArrayList(); } public String toString() { @@ -51,7 +53,7 @@ public class LevelConfig { sb.append(" bossEnemy="); sb.append(this.bossEnemy); sb.append("\\\n\tRules:\n"); - for(int[] rule : this.ruleList) { + for(int[] rule : this.spawnRuleList) { sb.append("\t"); sb.append(rule); sb.append("\n"); @@ -65,7 +67,7 @@ public class LevelConfig { * TODO: Catch overlapping intervals and more! */ public void addIntervalToList(int intervalStart, int intervalEnd) { - if(this.getIntervalByBorders(intervalStart, intervalEnd) != -1) { + if(this.getIntervalIndexByBorders(intervalStart, intervalEnd) != -1) { System.err.println("Duplicate interval - not added!"); } else { int[] newInterval= {intervalStart, intervalEnd}; @@ -77,7 +79,7 @@ public class LevelConfig { * Return index of given interval. * Returns -1 in case the interval is not in the list. */ - public int getIntervalByBorders(int intervalStart, int intervalEnd) { + public int getIntervalIndexByBorders(int intervalStart, int intervalEnd) { for(int[] interval : this.intervalList) { if(interval[0] == intervalStart && interval[1] == intervalEnd) { return this.intervalList.indexOf(interval); @@ -86,18 +88,31 @@ public class LevelConfig { return -1; } + /** + * Returns the index of the current interval the given time fits into. + */ + public int getIntervalIndexByCurrentTime(int time) { + for(int[] interval : this.intervalList) { + if(interval[0] <= time && interval[1] >= time) { + return this.intervalList.indexOf(interval); + } + } + return -1; + } + /** * Add a given EntitySpawnRule to the ruleList. */ - public void addEntitySpawnRule(int intervalStart, int intervalEnd, String enemyName, int amount, int spawnRate) { - System.out.println("Adding rule for " + intervalStart + " to " + intervalEnd + ": " + enemyName + ", " + amount + ", " + spawnRate); - if(this.getIntervalByBorders(intervalStart, intervalEnd) == -1) { + public void addEntitySpawnRule(int intervalStart, int intervalEnd, String entityName, int amount, int spawnRate) { + System.out.println("Adding rule for " + intervalStart + " to " + intervalEnd + ": " + entityName + ", " + amount + ", " + spawnRate); + int intervalIndex = this.getIntervalIndexByBorders(intervalStart, intervalEnd); + if(intervalIndex == -1) { System.err.println("No Interval for rule found!"); - System.err.println("Rule: " + intervalStart + " to " + intervalEnd + ": " + enemyName + ", " + amount + ", " + spawnRate); + System.err.println("Rule: " + intervalStart + " to " + intervalEnd + ": " + entityName + ", " + amount + ", " + spawnRate); } else { - int enemyNumber = -1; //TODO: implement this! - int[] newRule = {enemyNumber, amount, spawnRate}; - this.ruleList.add(newRule); + int enemyNumber = Entity.availableNames.valueOf(entityName).ordinal(); + int[] newRule = {intervalIndex, enemyNumber, amount, spawnRate}; + this.spawnRuleList.add(newRule); } } diff --git a/src/de/teamteamteam/spacescooter/level/LevelConfigParser.java b/src/de/teamteamteam/spacescooter/level/LevelConfigParser.java index 2c869f3..18e72ae 100644 --- a/src/de/teamteamteam/spacescooter/level/LevelConfigParser.java +++ b/src/de/teamteamteam/spacescooter/level/LevelConfigParser.java @@ -78,6 +78,7 @@ public class LevelConfigParser { } break; case 1: + // Handle interval based rules if (line.startsWith("[") && line.endsWith("]")) { //Handle interval definition String interval = line.substring(1, line.length() - 1); String[] intervalBorder = interval.split("-", 2); diff --git a/src/de/teamteamteam/spacescooter/screen/GameScreen.java b/src/de/teamteamteam/spacescooter/screen/GameScreen.java index c894658..9bfb091 100644 --- a/src/de/teamteamteam/spacescooter/screen/GameScreen.java +++ b/src/de/teamteamteam/spacescooter/screen/GameScreen.java @@ -27,6 +27,10 @@ public class GameScreen extends Screen { */ private Level level; + /** + * Internal counter that has to match a certain modulo to trigger the Level class within update(). + */ + private long gameClockTrigger; /** * GameScreen Constructor. @@ -37,6 +41,8 @@ public class GameScreen extends Screen { this.level = new Level(levelConfigName); this.level.doBuildUp(); //Have the level build up the whole setting. + this.gameClockTrigger = 0; + //Basic UI buildup - it's the same across all levels. new InterfaceBar(0, 0); new HealthBar(10, 5); @@ -63,8 +69,12 @@ public class GameScreen extends Screen { */ @Override protected void update() { - //The level will take care of whatever happens next. - this.level.handleUpdateTick(); + this.gameClockTrigger++; + //The level will take care of whatever happens next every second. + if(this.gameClockTrigger % 100 == 0) { + this.gameClockTrigger = 0; + this.level.handleUpdateTick(); + } //Take care of the usual bussiness this.entityUpdateIterator.reset();