LevelConfig should work now. Intervals are roughly seconds.

This commit is contained in:
Jan Philipp Timme 2014-11-25 13:37:13 +01:00
parent df8077874c
commit 922544effd
5 changed files with 83 additions and 27 deletions

View File

@ -2,10 +2,10 @@ name:Lustiger Levelname
backgroundMusic:music/bla.wav backgroundMusic:music/bla.wav
background:FooBackground background:FooBackground
- -
[0-2025] [0-20]
spawn:GegnerOne,2,6 spawn:EnemyTwo,2,2
[2026-2168] [21-25]
spawn:GegnerOne,2,4 spawn:EnemyThree,2,4
spawn:GegnerTwo,5,6 spawn:EnemyTwo,5,6
[2169-2170] [26-30]
spawn:BossGegner,1,1 spawn:EnemyBoss,1,1

View File

@ -9,9 +9,10 @@ import de.teamteamteam.spacescooter.entity.enemy.EnemyOne;
import de.teamteamteam.spacescooter.entity.enemy.EnemyThree; import de.teamteamteam.spacescooter.entity.enemy.EnemyThree;
import de.teamteamteam.spacescooter.entity.enemy.EnemyTwo; import de.teamteamteam.spacescooter.entity.enemy.EnemyTwo;
import de.teamteamteam.spacescooter.entity.Entity; import de.teamteamteam.spacescooter.entity.Entity;
import de.teamteamteam.spacescooter.entity.Entity.availableNames;
import de.teamteamteam.spacescooter.screen.GameScreen; import de.teamteamteam.spacescooter.screen.GameScreen;
import de.teamteamteam.spacescooter.utility.GameConfig;
import de.teamteamteam.spacescooter.utility.Loader; import de.teamteamteam.spacescooter.utility.Loader;
import de.teamteamteam.spacescooter.utility.Random;
/** /**
* Implementation of the actual level based gameplay logic. * Implementation of the actual level based gameplay logic.
@ -31,13 +32,14 @@ public final class Level {
* Internal levelClock counter thing. * Internal levelClock counter thing.
* This is the "level time, we will use in our configs and such. * 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. * Constructor creating a LevelConfig based on a given config file.
*/ */
public Level(String levelConfig) { public Level(String levelConfig) {
this.levelClock = 0;
this.config = Loader.getLevelConfigByFilename(levelConfig); this.config = Loader.getLevelConfigByFilename(levelConfig);
System.out.println(this.config); System.out.println(this.config);
} }
@ -49,7 +51,6 @@ public final class Level {
public void doBuildUp() { public void doBuildUp() {
new StarBackground(0, 50); new StarBackground(0, 50);
GameScreen.setPlayer(new Player(200, 300)); GameScreen.setPlayer(new Player(200, 300));
} }
/** /**
@ -73,7 +74,37 @@ public final class Level {
if (Keyboard.isKeyDown(KeyEvent.VK_0)) { if (Keyboard.isKeyDown(KeyEvent.VK_0)) {
new EnemyBoss(400,400); new EnemyBoss(400,400);
} }
//Increase levelClock
this.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 <LevelConfig>
* 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<spawnrule[2]; i++) {
//TODO: More beautiful positions!
this.spawnEntityByAvailableName(Entity.availableNames.values()[spawnrule[1]], GameConfig.windowWidth - 75, Random.nextInt(GameConfig.windowHeight));
}
}
}
} }
/** /**
@ -89,8 +120,7 @@ public final class Level {
* Spawn an Entity by name on the given position. * Spawn an Entity by name on the given position.
* Uses Entity.availableNames to determine the actual Entity to spawn. * Uses Entity.availableNames to determine the actual Entity to spawn.
*/ */
private void spawnEntityByName(String entityName, int x, int y) { private void spawnEntityByAvailableName(Entity.availableNames entity, int x, int y) {
availableNames entity = Entity.availableNames.valueOf(entityName);
switch(entity) { switch(entity) {
case EnemyOne: case EnemyOne:
new EnemyOne(x, y); new EnemyOne(x, y);
@ -108,7 +138,7 @@ public final class Level {
new EnemyBoss(x, y); new EnemyBoss(x, y);
break; break;
default: default:
System.err.println("Fuck you, i don't know what you mean with this!"); System.err.println("Fuck you, i don't know what you mean with this: " + entity);
break; break;
} }
} }

View File

@ -3,6 +3,8 @@ package de.teamteamteam.spacescooter.level;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import de.teamteamteam.spacescooter.entity.Entity;
/** /**
* The actual LevelConfig. * The actual LevelConfig.
* It contains all the important details that are required to build the level up * It contains all the important details that are required to build the level up
@ -31,12 +33,12 @@ public class LevelConfig {
* - 2: Amount - The amount of Entities to spawn at a time. * - 2: Amount - The amount of Entities to spawn at a time.
* - 3: SpawnRate - The rate at which the Entities are supposed to be spawned. * - 3: SpawnRate - The rate at which the Entities are supposed to be spawned.
*/ */
public List<int[]> ruleList; public List<int[]> spawnRuleList;
public LevelConfig() { public LevelConfig() {
this.intervalList = new ArrayList<int[]>(); this.intervalList = new ArrayList<int[]>();
this.ruleList = new ArrayList<int[]>(); this.spawnRuleList = new ArrayList<int[]>();
} }
public String toString() { public String toString() {
@ -51,7 +53,7 @@ public class LevelConfig {
sb.append(" bossEnemy="); sb.append(" bossEnemy=");
sb.append(this.bossEnemy); sb.append(this.bossEnemy);
sb.append("\\\n\tRules:\n"); sb.append("\\\n\tRules:\n");
for(int[] rule : this.ruleList) { for(int[] rule : this.spawnRuleList) {
sb.append("\t"); sb.append("\t");
sb.append(rule); sb.append(rule);
sb.append("\n"); sb.append("\n");
@ -65,7 +67,7 @@ public class LevelConfig {
* TODO: Catch overlapping intervals and more! * TODO: Catch overlapping intervals and more!
*/ */
public void addIntervalToList(int intervalStart, int intervalEnd) { 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!"); System.err.println("Duplicate interval - not added!");
} else { } else {
int[] newInterval= {intervalStart, intervalEnd}; int[] newInterval= {intervalStart, intervalEnd};
@ -77,7 +79,7 @@ public class LevelConfig {
* Return index of given interval. * Return index of given interval.
* Returns -1 in case the interval is not in the list. * 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) { for(int[] interval : this.intervalList) {
if(interval[0] == intervalStart && interval[1] == intervalEnd) { if(interval[0] == intervalStart && interval[1] == intervalEnd) {
return this.intervalList.indexOf(interval); return this.intervalList.indexOf(interval);
@ -86,18 +88,31 @@ public class LevelConfig {
return -1; 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. * Add a given EntitySpawnRule to the ruleList.
*/ */
public void addEntitySpawnRule(int intervalStart, int intervalEnd, String enemyName, int amount, int spawnRate) { public void addEntitySpawnRule(int intervalStart, int intervalEnd, String entityName, int amount, int spawnRate) {
System.out.println("Adding rule for " + intervalStart + " to " + intervalEnd + ": " + enemyName + ", " + amount + ", " + spawnRate); System.out.println("Adding rule for " + intervalStart + " to " + intervalEnd + ": " + entityName + ", " + amount + ", " + spawnRate);
if(this.getIntervalByBorders(intervalStart, intervalEnd) == -1) { int intervalIndex = this.getIntervalIndexByBorders(intervalStart, intervalEnd);
if(intervalIndex == -1) {
System.err.println("No Interval for rule found!"); 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 { } else {
int enemyNumber = -1; //TODO: implement this! int enemyNumber = Entity.availableNames.valueOf(entityName).ordinal();
int[] newRule = {enemyNumber, amount, spawnRate}; int[] newRule = {intervalIndex, enemyNumber, amount, spawnRate};
this.ruleList.add(newRule); this.spawnRuleList.add(newRule);
} }
} }

View File

@ -78,6 +78,7 @@ public class LevelConfigParser {
} }
break; break;
case 1: case 1:
// Handle interval based rules
if (line.startsWith("[") && line.endsWith("]")) { //Handle interval definition if (line.startsWith("[") && line.endsWith("]")) { //Handle interval definition
String interval = line.substring(1, line.length() - 1); String interval = line.substring(1, line.length() - 1);
String[] intervalBorder = interval.split("-", 2); String[] intervalBorder = interval.split("-", 2);

View File

@ -27,6 +27,10 @@ public class GameScreen extends Screen {
*/ */
private Level level; private Level level;
/**
* Internal counter that has to match a certain modulo to trigger the Level class within update().
*/
private long gameClockTrigger;
/** /**
* GameScreen Constructor. * GameScreen Constructor.
@ -37,6 +41,8 @@ public class GameScreen extends Screen {
this.level = new Level(levelConfigName); this.level = new Level(levelConfigName);
this.level.doBuildUp(); //Have the level build up the whole setting. this.level.doBuildUp(); //Have the level build up the whole setting.
this.gameClockTrigger = 0;
//Basic UI buildup - it's the same across all levels. //Basic UI buildup - it's the same across all levels.
new InterfaceBar(0, 0); new InterfaceBar(0, 0);
new HealthBar(10, 5); new HealthBar(10, 5);
@ -63,8 +69,12 @@ public class GameScreen extends Screen {
*/ */
@Override @Override
protected void update() { protected void update() {
//The level will take care of whatever happens next. this.gameClockTrigger++;
this.level.handleUpdateTick(); //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 //Take care of the usual bussiness
this.entityUpdateIterator.reset(); this.entityUpdateIterator.reset();