diff --git a/res/levels/test.level b/res/levels/test.level index 53bec45..13232da 100644 --- a/res/levels/test.level +++ b/res/levels/test.level @@ -4,19 +4,82 @@ background:CloudBackground nextLevel:levels/second.level - [0-1] -spawn:EnemyBoss,1,1,50 +spawn:EnemyTwo,1,4,5 +spawn:EnemyTwo,1,4,25 +spawn:EnemyTwo,1,4,45 +spawn:EnemyTwo,1,4,65 +spawn:EnemyTwo,1,4,85 +spawn:EnemyTwo,1,4,100 [1-2] +spawn:EnemyTwo,1,6,15 +spawn:EnemyTwo,1,6,35 +spawn:EnemyTwo,1,6,55 +spawn:EnemyTwo,1,6,75 +spawn:EnemyTwo,1,6,95 +[2-3] +spawn:EnemyTwo,1,4,5 +spawn:EnemyTwo,1,4,25 +spawn:EnemyTwo,1,4,45 +spawn:EnemyTwo,1,4,65 +spawn:EnemyTwo,1,4,85 +spawn:EnemyTwo,1,4,100 +[3-4] +spawn:EnemyTwo,1,6,15 +spawn:EnemyTwo,1,6,35 +spawn:EnemyTwo,1,6,55 +spawn:EnemyTwo,1,6,75 +spawn:EnemyTwo,1,6,95 +[4-5] +spawn:EnemyTwo,1,4,5 +spawn:EnemyTwo,1,4,25 +spawn:EnemyTwo,1,4,45 +spawn:EnemyTwo,1,4,65 +spawn:EnemyTwo,1,4,85 +spawn:EnemyTwo,1,4,100 +[5-6] +spawn:EnemyTwo,1,6,15 +spawn:EnemyTwo,1,6,35 +spawn:EnemyTwo,1,6,55 +spawn:EnemyTwo,1,6,75 +spawn:EnemyTwo,1,6,95 +[6-7] +spawn:EnemyTwo,1,4,5 +spawn:EnemyTwo,1,4,25 +spawn:EnemyTwo,1,4,45 +spawn:EnemyTwo,1,4,65 +spawn:EnemyTwo,1,4,85 +spawn:EnemyTwo,1,4,100 +[7-8] +spawn:EnemyTwo,1,6,15 +spawn:EnemyTwo,1,6,35 +spawn:EnemyTwo,1,6,55 +spawn:EnemyTwo,1,6,75 +spawn:EnemyTwo,1,6,95 +[8-9] +spawn:EnemyTwo,1,4,5 +spawn:EnemyTwo,1,4,25 +spawn:EnemyTwo,1,4,45 +spawn:EnemyTwo,1,4,65 +spawn:EnemyTwo,1,4,85 +spawn:EnemyTwo,1,4,100 +[9-10] +spawn:EnemyTwo,1,6,15 +spawn:EnemyTwo,1,6,35 +spawn:EnemyTwo,1,6,55 +spawn:EnemyTwo,1,6,75 +spawn:EnemyTwo,1,6,95 +[10-12] spawn:StoneOne,2,1,0 spawn:StoneOne,2,1,80 spawn:StoneThree,2,1,90 spawn:StoneThree,2,1,100 -[2-4] +[12-14] spawn:EnemyOne,1,5,20 spawn:StoneOne,4,5,50 -[4-10] +[14-20] spawn:EnemyTwo,1,10,60 -[10-25] +[20-35] spawn:EnemyThree,2,4,33 spawn:EnemyTwo,5,6,10 -[25-30] +[35-40] spawn:EnemyBoss,1,1,50 diff --git a/src/de/teamteamteam/spacescooter/control/Keyboard.java b/src/de/teamteamteam/spacescooter/control/Keyboard.java index dcb3bc2..0b507ad 100644 --- a/src/de/teamteamteam/spacescooter/control/Keyboard.java +++ b/src/de/teamteamteam/spacescooter/control/Keyboard.java @@ -117,7 +117,7 @@ public class Keyboard implements KeyListener { } if(e.getKeyCode() == KeyEvent.VK_4) { ArrayList points = new ArrayList(); - points.add(new Point(398,306));; + points.add(new Point(398,306)); points.add(new Point(10,300)); new EnemyFour(700,51,points); } diff --git a/src/de/teamteamteam/spacescooter/entity/enemy/EnemyFour.java b/src/de/teamteamteam/spacescooter/entity/enemy/EnemyFour.java index 36aa40c..42826f2 100644 --- a/src/de/teamteamteam/spacescooter/entity/enemy/EnemyFour.java +++ b/src/de/teamteamteam/spacescooter/entity/enemy/EnemyFour.java @@ -4,6 +4,8 @@ import java.awt.Point; import java.util.ArrayList; import de.teamteamteam.spacescooter.entity.explosion.ExplosionOne; +import de.teamteamteam.spacescooter.entity.item.Item; +import de.teamteamteam.spacescooter.utility.Random; public class EnemyFour extends Enemy{ @@ -21,7 +23,8 @@ public class EnemyFour extends Enemy{ this.setImage("images/enemy01.png"); this.setPrimaryShotImage("images/shots/laser_yellow.png"); this.setShootSpeed(4); - this.setShootDelay(62); + this.setShootDelay(60); + this.setCanShoot(false); this.setShootSpawn(-10, 10); this.setShootDamage(5); this.setCollisionDamage(5); @@ -70,4 +73,13 @@ public class EnemyFour extends Enemy{ new ExplosionOne(this.getCenteredX(), this.getCenteredY()); } + /** + * This enemy spawns an Item on its death and causes another enemy to appear. + */ + @Override + public void die() { + if(Random.nextInt(100) < 5) Item.create(getX(), getY()); + super.die(); + } + } diff --git a/src/de/teamteamteam/spacescooter/gui/LevelHeadline.java b/src/de/teamteamteam/spacescooter/gui/LevelHeadline.java new file mode 100644 index 0000000..fff32f5 --- /dev/null +++ b/src/de/teamteamteam/spacescooter/gui/LevelHeadline.java @@ -0,0 +1,56 @@ +package de.teamteamteam.spacescooter.gui; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; + +import de.teamteamteam.spacescooter.brain.GameConfig; +import de.teamteamteam.spacescooter.entity.Entity; + +/** + * A headline that is being displayed at the beginning of each level, + * disappearing by fading out after 1-2 seconds. + */ +public class LevelHeadline extends Entity { + + + private int lifeTime; + private int lifeTimeCounter; + + private String text; + + public LevelHeadline(int x, int y, String text) { + super(x, y); + this.text = text; + this.lifeTime = 150; + this.lifeTimeCounter = this.lifeTime; + } + + /** + * Make the headline stay for a while, then let it disappear. + */ + @Override + public void update() { + if(this.lifeTimeCounter > 0) { + this.lifeTimeCounter--; + } + if(lifeTime == 0) { + this.remove(); + } + } + + /** + * Draw the Headline + */ + public void paint(Graphics2D g) { + g.setFont(new Font("Monospace", 0, 60)); + float alpha = (float) (this.lifeTimeCounter / (this.lifeTime * 1.0)); + int textWidth = g.getFontMetrics().stringWidth(this.text); + int textHeight = g.getFontMetrics().getHeight(); + int x = (GameConfig.gameScreenWidth/2 - textWidth/2); + int y = (int) (GameConfig.gameScreenHeight/2 - textHeight); + g.setColor(new Color(1.0F, 1.0F, 1.0F, alpha)); + g.drawString(this.text, x, y); + } + +} diff --git a/src/de/teamteamteam/spacescooter/level/Level.java b/src/de/teamteamteam/spacescooter/level/Level.java index e1d05a9..b8c34f7 100644 --- a/src/de/teamteamteam/spacescooter/level/Level.java +++ b/src/de/teamteamteam/spacescooter/level/Level.java @@ -1,5 +1,8 @@ package de.teamteamteam.spacescooter.level; +import java.awt.Point; +import java.util.ArrayList; + import de.teamteamteam.spacescooter.background.CloudBackground; import de.teamteamteam.spacescooter.background.EarthBackground; import de.teamteamteam.spacescooter.background.StarBackground; @@ -10,6 +13,7 @@ import de.teamteamteam.spacescooter.entity.Entity; import de.teamteamteam.spacescooter.entity.Player; import de.teamteamteam.spacescooter.entity.enemy.Enemy; import de.teamteamteam.spacescooter.entity.enemy.EnemyBoss; +import de.teamteamteam.spacescooter.entity.enemy.EnemyFour; import de.teamteamteam.spacescooter.entity.enemy.EnemyOne; import de.teamteamteam.spacescooter.entity.enemy.EnemyThree; import de.teamteamteam.spacescooter.entity.enemy.EnemyTwo; @@ -17,6 +21,7 @@ import de.teamteamteam.spacescooter.entity.obstacle.Obstacle; import de.teamteamteam.spacescooter.entity.obstacle.StoneOne; import de.teamteamteam.spacescooter.entity.obstacle.StoneThree; import de.teamteamteam.spacescooter.entity.obstacle.StoneTwo; +import de.teamteamteam.spacescooter.gui.LevelHeadline; import de.teamteamteam.spacescooter.screen.GameScreen; import de.teamteamteam.spacescooter.screen.Screen; import de.teamteamteam.spacescooter.sound.SoundSystem; @@ -83,12 +88,14 @@ public final class Level { } /** - * Initialize the level based on the LevelConfig attributes. + * Initialize the level based on the LevelConfig attributes, + * show the level name in a LevelHeadline. */ public void doBuildUp() { - this.spawnEntityByAvailableName(Entity.availableNames.valueOf(this.config.background), 0, 50); + this.spawnEntityByAvailableName(Entity.availableNames.valueOf(this.config.background), 0, 50, null); GameScreen.setPlayer(new Player(200, 300)); this.backgroundMusic = SoundSystem.playSound(this.config.backgroundMusic); + new LevelHeadline(100,100, this.config.name); } /** @@ -116,21 +123,30 @@ public final class Level { * - 2: Amount - The amount of Entities to spawn at a time. * - 3: SpawnRate - The rate at which the Entities are supposed to be spawned. * - 4: SpawnPosition - percentage of GameConfig.windowHeight - Where the Enemy shall spawn. + * - 5: Points - points for EnemyFour */ - for(int[] spawnRule : this.config.spawnRuleList) { + for(String[] spawnRule : this.config.spawnRuleList) { //Skip spawn rules that are not in the current spawn interval. - if(spawnRule[0] != currentIntervalIndex) continue; + if(Integer.parseInt(spawnRule[0]) != currentIntervalIndex) continue; //Divide the current interval by spawnrate - int intervalModulus = intervalLength / spawnRule[3]; + int intervalModulus = intervalLength / Integer.parseInt(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 points = null; //Minus one because the upper border is _excluded_ from the range! int x = GameConfig.gameScreenWidth + GameConfig.gameScreenXOffset - 1; + if (!spawnRule[5].equals("")) { + points = new ArrayList(); + String [] lol = spawnRule[5].split(";"); + for(int run = 0; run < lol.length; run = run+2) { + points.add(new Point(Integer.parseInt(lol[run]),Integer.parseInt(lol[run+1]))); + } + } //Minus one because the upper border is _excluded_ from the range! - int y = Math.round((GameConfig.gameScreenHeight * spawnRule[4]) / 100) + GameConfig.gameScreenYOffset - 1; - this.spawnEntityByAvailableName(Entity.availableNames.values()[spawnRule[1]], x, y); + int y = Math.round((GameConfig.gameScreenHeight * Integer.parseInt(spawnRule[4])) / 100) + GameConfig.gameScreenYOffset - 1; + this.spawnEntityByAvailableName(Entity.availableNames.values()[Integer.parseInt(spawnRule[1])], x, y, points); } } } @@ -207,7 +223,7 @@ public final class Level { * Spawn an Entity by name on the given position. * Uses Entity.availableNames to determine the actual Entity to spawn. */ - private void spawnEntityByAvailableName(Entity.availableNames entity, int x, int y) { + private void spawnEntityByAvailableName(Entity.availableNames entity, int x, int y, ArrayList points) { switch(entity) { case StarBackground: new StarBackground(x, y); @@ -228,7 +244,7 @@ public final class Level { new EnemyThree(x, y); break; case EnemyFour: - //TODO: FIX CONSTRUCTOR new EnemyFour(x, y); + new EnemyFour(x, y, points); break; case EnemyBoss: new EnemyBoss(x, y); @@ -247,5 +263,4 @@ public final class Level { break; } } - } diff --git a/src/de/teamteamteam/spacescooter/level/LevelConfig.java b/src/de/teamteamteam/spacescooter/level/LevelConfig.java index 72181a8..915641f 100644 --- a/src/de/teamteamteam/spacescooter/level/LevelConfig.java +++ b/src/de/teamteamteam/spacescooter/level/LevelConfig.java @@ -50,12 +50,12 @@ public class LevelConfig { * - 3: SpawnRate - The rate at which the Entities are supposed to be spawned. * - 4: SpawnPosition - percentage of GameConfig.windowHeight - Where the Enemy shall spawn. */ - public List spawnRuleList; + public List spawnRuleList; public LevelConfig() { this.intervalList = new ArrayList(); - this.spawnRuleList = new ArrayList(); + this.spawnRuleList = new ArrayList(); } public String toString() { @@ -70,7 +70,7 @@ public class LevelConfig { sb.append(" nextLevelName="); sb.append(this.nextLevel); sb.append("\\\n\tRules:\n"); - for(int[] rule : this.spawnRuleList) { + for(String[] rule : this.spawnRuleList) { sb.append("\t"); sb.append(rule); sb.append("\n"); @@ -126,17 +126,19 @@ public class LevelConfig { /** * Add a given EntitySpawnRule to the ruleList. + * @param wayPoints + * @param enemyWayPoints */ - public void addEntitySpawnRule(int intervalStart, int intervalEnd, String entityName, int amount, int spawnRate, int spawnPositionPercentage) { + public void addEntitySpawnRule(int intervalStart, int intervalEnd, String entityName, String amount, String spawnRate, String spawnPositionPercentage, String wayPoints) { int intervalIndex = this.getIntervalIndexByBorders(intervalStart, intervalEnd); if(intervalIndex == -1) { throw new LevelConfigException("No Interval for rule found!\nRule: " + intervalStart + " to " + intervalEnd + ": " + entityName + ", " + amount + ", " + spawnRate + ", " + spawnPositionPercentage); } else { int enemyNumber = Entity.availableNames.valueOf(entityName).ordinal(); - if(spawnPositionPercentage < 0 || spawnPositionPercentage > 100) { + if(Integer.parseInt(spawnPositionPercentage) < 0 || Integer.parseInt(spawnPositionPercentage) > 100) { throw new LevelConfigException("Invalid spawnPosition percentage!\nRule: " + intervalStart + " to " + intervalEnd + ": " + entityName + ", " + amount + ", " + spawnRate + ", " + spawnPositionPercentage); } - int[] newRule = {intervalIndex, enemyNumber, amount, spawnRate, spawnPositionPercentage}; + String[] newRule = {""+intervalIndex, ""+enemyNumber, ""+amount, ""+spawnRate, ""+spawnPositionPercentage, wayPoints}; this.spawnRuleList.add(newRule); } } diff --git a/src/de/teamteamteam/spacescooter/level/LevelConfigParser.java b/src/de/teamteamteam/spacescooter/level/LevelConfigParser.java index 84727a0..96714bb 100644 --- a/src/de/teamteamteam/spacescooter/level/LevelConfigParser.java +++ b/src/de/teamteamteam/spacescooter/level/LevelConfigParser.java @@ -31,6 +31,11 @@ public class LevelConfigParser { */ private int currentIntervalStart; + /** + * The start of the last read interval. + */ + private String wayPoints; + /** * The end of the last read interval. */ @@ -88,14 +93,20 @@ public class LevelConfigParser { } else { String[] rule = line.split(":", 2); if(rule[0].equals("spawn")) { - String[] entitySpawnRule = rule[1].split(",", 4); + String[] entitySpawnRule = rule[1].split(",", 5); + if (entitySpawnRule.length <= 4) { + wayPoints = ""; + } else { + wayPoints = entitySpawnRule[4]; + } this.levelConfig.addEntitySpawnRule( this.currentIntervalStart, this.currentIntervalEnd, entitySpawnRule[0], - Integer.parseInt(entitySpawnRule[1]), - Integer.parseInt(entitySpawnRule[2]), - Integer.parseInt(entitySpawnRule[3]) + entitySpawnRule[1], + entitySpawnRule[2], + entitySpawnRule[3], + wayPoints ); } else { throw new LevelConfigException("Unknown rule type: '"+rule[0]+"' : '"+line+"'");