diff --git a/src/dk/itu/mario/level/PCGLevel.java b/src/dk/itu/mario/level/PCGLevel.java index bb8decb..08378ec 100644 --- a/src/dk/itu/mario/level/PCGLevel.java +++ b/src/dk/itu/mario/level/PCGLevel.java @@ -121,15 +121,26 @@ public class PCGLevel extends Level { int length = 0; if (TESTING) { + difficulty = 6; + length = buildStraight(0, width - 64, true); + length += buildFreebie(length, width - 64 - length); length += buildBowlingAlley(length, width - 64 - length, SpriteTemplate.ARMORED_TURTLE); - length += buildLemmingTrap(length, width - 64 - length, - random.nextInt(3) + 1); + length += buildFreebie(length, width - 64 - length); + + length += buildLemmingTrap(length, width - 64 - length); + length += buildFreebie(length, width - 64 - length); + length += buildPlatformJump(length, width - 64 - length); + length += buildFreebie(length, width - 64 - length); + length += buildMaze(length, width - 64 - length); + length += buildFreebie(length, width - 64 - length); + length += buildPipeJump(length, width - 64 - length); + length += buildFreebie(length, width - 64 - length); // create all of the medium sections while (length < width - 64) { @@ -186,10 +197,44 @@ public class PCGLevel extends Level { fillEndPiece(length, floor); } + private int buildFreebie(int xo, int maxLength) { + if (maxLength >= 5) { + + int floor = height - 1 - random.nextInt(4); + for (int x = 0; x < 5; x++) { + for (int y = 0; y < height; y++) { + if (y >= floor) { + setBlock(xo + x, y, GROUND); + } + } + } + + if (random.nextBoolean()) { + setBlock(xo, floor - 1, Level.BLOCK_EMPTY); + setBlock(xo + 4, floor - 1, Level.BLOCK_POWERUP); + + setSpriteTemplate(xo + 3, floor - 1, new SpriteTemplate( + SpriteTemplate.GREEN_TURTLE, false)); + } + + else { + setBlock(xo + 2, floor - 3, Level.BLOCK_POWERUP); + } + + return 5; + } + return 0; + } + private int buildBowlingAlley(int xo, int maxLength, int enemyType) { if (maxLength >= 26 && (enemyType == SpriteTemplate.ARMORED_TURTLE || enemyType == SpriteTemplate.GREEN_TURTLE)) { + int numEnemies = 0; + for (int i = 0; i < 10; i++) { + numEnemies += shouldAddChallenge() ? 1 : 0; + } + // Create the pit. setBlock(xo, this.height - 2, Level.GROUND); setBlock(xo, this.height - 1, Level.GROUND); @@ -209,22 +254,26 @@ public class PCGLevel extends Level { setBlock(xo + x, this.height - 2, Level.GROUND); setBlock(xo + x, this.height - 3, Level.GROUND); - if (x > 16) { + if (x >= 26 - numEnemies) { setSpriteTemplate(xo + x, this.height - 4, new SpriteTemplate(enemyType, false)); } } - return 25; + return 26; } return 0; } - private int buildLemmingTrap(int xo, int maxLength, int enemyType) { - if (maxLength >= 14 - && (enemyType == SpriteTemplate.GOOMPA - || enemyType == SpriteTemplate.GREEN_TURTLE || enemyType == SpriteTemplate.ARMORED_TURTLE)) { + private int buildLemmingTrap(int xo, int maxLength) { + if (maxLength >= 14) { + int enemyType = shouldAddChallenge() ? (shouldAddChallenge() ? SpriteTemplate.ARMORED_TURTLE + : SpriteTemplate.GREEN_TURTLE) + : SpriteTemplate.GOOMPA; + boolean flying = shouldAddChallenge() && shouldAddChallenge() + && shouldAddChallenge(); + for (int x = 0; x < 18; x++) { if (x > 5) { for (int y = 0; y < 5; y++) { @@ -237,7 +286,7 @@ public class PCGLevel extends Level { if (x > 6 && x % 2 == 0) { setSpriteTemplate(xo + x, this.height - 6, - new SpriteTemplate(enemyType, false)); + new SpriteTemplate(enemyType, flying)); } } return 18; @@ -388,148 +437,161 @@ public class PCGLevel extends Level { } } + // This is basically just a randomizer function to call whenever I need to + // randomly add difficulty based on the user's skill level. + private boolean shouldAddChallenge() { + return random.nextInt(11) + 1 <= difficulty; + } + private int buildMaze(int xo, int maxLength) { - int length = random.nextInt(maxLength - 19) + 20; - int soFar = 6; - int next; - // boolean skipUp = false; - // boolean skipDown = false; + if (maxLength >= 19) { - class Stretch { - public int len; - public LevelComponent.MazeLevel lvl; + int length = random.nextInt(maxLength - 19) + 20; + int soFar = 6; + int next; + // boolean skipUp = false; + // boolean skipDown = false; - public Stretch(int lngth) { - len = lngth; + class Stretch { + public int len; + public LevelComponent.MazeLevel lvl; - switch (random.nextInt(3)) { - case 0: - lvl = LevelComponent.MazeLevel.TOP; - break; - case 1: - lvl = LevelComponent.MazeLevel.MID; - break; - default: - lvl = LevelComponent.MazeLevel.BOT; + public Stretch(int lngth) { + len = lngth; + + switch (random.nextInt(3)) { + case 0: + lvl = LevelComponent.MazeLevel.TOP; + break; + case 1: + lvl = LevelComponent.MazeLevel.MID; + break; + default: + lvl = LevelComponent.MazeLevel.BOT; + } } } + + ArrayList maze = new ArrayList(); + + loop: while (soFar < length) { + if (soFar + 3 > length) { + length = soFar; + break loop; + } + + next = random.nextInt(18) + 5; + + if (soFar + next > length) { + next = length - soFar; + } + + maze.add(new Stretch(next)); + + soFar += next; + } + + setBlock(xo, this.height - 1, Level.GROUND); + setBlock(xo + 1, this.height - 1, Level.GROUND); + setBlock(xo + 2, this.height - 1, Level.GROUND); + soFar = 3; + + Stretch str; + // Stretch nxt; + boolean stretchEnd; + boolean midLine; + boolean addEnemy; + int heightMod; + int enemyType; + for (int i = 0; i < maze.size(); i++) { + + str = maze.get(i); + + for (int x = 0; x < str.len; x++) { + + setBlock(xo + soFar + x, this.height - 1, Level.GROUND); + + // skipUp = (skipUp && (x == str.len - 2)) + // || (str.len >= 5 && x == (str.len / 2)); + // skipDown = (skipDown && (x == str.len - 2)) + // || (str.len >= 5 && x == (str.len / 2)); + midLine = (str.len >= 5 && x == (str.len / 2) - 1); + addEnemy = (str.len >= 5 && x == (str.len / 2)); + stretchEnd = (x == str.len - 1); + + if // ((stretchEnd && nxt != null && nxt.lvl != + // MazeLevel.BOT) + // || + (midLine && str.lvl != LevelComponent.MazeLevel.BOT) // ) + { + setBlock(xo + soFar + x, this.height - 2, Level.ROCK); + setBlock(xo + soFar + x, this.height - 3, Level.ROCK); + } + if // ((stretchEnd && nxt != null && nxt.lvl != + // MazeLevel.MID) + // || + (midLine && str.lvl != LevelComponent.MazeLevel.MID)// ) + { + setBlock(xo + soFar + x, this.height - 5, Level.ROCK); + setBlock(xo + soFar + x, this.height - 6, Level.ROCK); + } + if // ((stretchEnd && nxt != null && nxt.lvl != + // MazeLevel.TOP) + // || + (midLine && str.lvl != LevelComponent.MazeLevel.TOP)// ) + { + setBlock(xo + soFar + x, this.height - 8, Level.ROCK); + setBlock(xo + soFar + x, this.height - 9, Level.ROCK); + setBlock(xo + soFar + x, this.height - 10, Level.ROCK); + setBlock(xo + soFar + x, this.height - 11, Level.ROCK); + setBlock(xo + soFar + x, this.height - 12, Level.ROCK); + setBlock(xo + soFar + x, this.height - 13, Level.ROCK); + setBlock(xo + soFar + x, this.height - 14, Level.ROCK); + setBlock(xo + soFar + x, this.height - 15, Level.ROCK); + } + + if (!stretchEnd) { + setBlock(xo + soFar + x, this.height - 7, Level.ROCK); + } + + if (!stretchEnd) { + setBlock(xo + soFar + x, this.height - 4, Level.ROCK); + } + + if (addEnemy && shouldAddChallenge()) { + + enemyType = shouldAddChallenge() ? (shouldAddChallenge() ? (shouldAddChallenge() ? SpriteTemplate.ARMORED_TURTLE + : SpriteTemplate.RED_TURTLE) + : SpriteTemplate.GREEN_TURTLE) + : SpriteTemplate.GOOMPA; + + switch (str.lvl) { + case TOP: + heightMod = 8; + break; + case MID: + heightMod = 5; + break; + default: + heightMod = 2; + } + + setSpriteTemplate(xo + soFar + x, this.height + - heightMod, new SpriteTemplate(enemyType, + shouldAddChallenge())); + } + } + + soFar += str.len; + } + + setBlock(xo + length - 1, this.height - 1, Level.GROUND); + setBlock(xo + length - 2, this.height - 1, Level.GROUND); + setBlock(xo + length - 3, this.height - 1, Level.GROUND); + + return length; } - - ArrayList maze = new ArrayList(); - - loop: while (soFar < length) { - if (soFar + 3 > length) { - length = soFar; - break loop; - } - - next = random.nextInt(18) + 5; - - if (soFar + next > length) { - next = length - soFar; - } - - maze.add(new Stretch(next)); - - soFar += next; - } - - setBlock(xo, this.height - 1, Level.GROUND); - setBlock(xo + 1, this.height - 1, Level.GROUND); - setBlock(xo + 2, this.height - 1, Level.GROUND); - soFar = 3; - - Stretch str; - // Stretch nxt; - boolean stretchEnd; - boolean midLine; - for (int i = 0; i < maze.size(); i++) { - - str = maze.get(i); - - // if (i < maze.size() - 1) { - // nxt = maze.get(i + 1); - // } else { - // nxt = null; - // } - - // if (nxt != null) { - // skipUp = ((nxt.lvl != MazeLevel.TOP) && (str.lvl == - // MazeLevel.TOP)) - // || ((nxt.lvl == MazeLevel.TOP) && (str.lvl != MazeLevel.TOP)); - // - // skipDown = ((nxt.lvl != MazeLevel.BOT) && (str.lvl == - // MazeLevel.BOT)) - // || ((str.lvl != MazeLevel.BOT) && (nxt.lvl == MazeLevel.BOT)); - // } - // - // else { - // skipUp = false; - // skipDown = false; - // } - - for (int x = 0; x < str.len; x++) { - - setBlock(xo + soFar + x, this.height - 1, Level.GROUND); - - // skipUp = (skipUp && (x == str.len - 2)) - // || (str.len >= 5 && x == (str.len / 2)); - // skipDown = (skipDown && (x == str.len - 2)) - // || (str.len >= 5 && x == (str.len / 2)); - midLine = (str.len >= 5 && x == (str.len / 2) - 1); - stretchEnd = (x == str.len - 1); - - if // ((stretchEnd && nxt != null && nxt.lvl != MazeLevel.BOT) - // || - (midLine && str.lvl != LevelComponent.MazeLevel.BOT) // ) - { - setBlock(xo + soFar + x, this.height - 2, Level.BLOCK_EMPTY); - setBlock(xo + soFar + x, this.height - 3, Level.BLOCK_EMPTY); - } - if // ((stretchEnd && nxt != null && nxt.lvl != MazeLevel.MID) - // || - (midLine && str.lvl != LevelComponent.MazeLevel.MID)// ) - { - setBlock(xo + soFar + x, this.height - 5, Level.BLOCK_EMPTY); - setBlock(xo + soFar + x, this.height - 6, Level.BLOCK_EMPTY); - } - if // ((stretchEnd && nxt != null && nxt.lvl != MazeLevel.TOP) - // || - (midLine && str.lvl != LevelComponent.MazeLevel.TOP)// ) - { - setBlock(xo + soFar + x, this.height - 8, Level.BLOCK_EMPTY); - setBlock(xo + soFar + x, this.height - 9, Level.BLOCK_EMPTY); - setBlock(xo + soFar + x, this.height - 10, - Level.BLOCK_EMPTY); - setBlock(xo + soFar + x, this.height - 11, - Level.BLOCK_EMPTY); - setBlock(xo + soFar + x, this.height - 12, - Level.BLOCK_EMPTY); - setBlock(xo + soFar + x, this.height - 13, - Level.BLOCK_EMPTY); - setBlock(xo + soFar + x, this.height - 14, - Level.BLOCK_EMPTY); - setBlock(xo + soFar + x, this.height - 15, - Level.BLOCK_EMPTY); - } - - if (!stretchEnd) { - setBlock(xo + soFar + x, this.height - 7, Level.BLOCK_EMPTY); - } - - if (!stretchEnd) { - setBlock(xo + soFar + x, this.height - 4, Level.BLOCK_EMPTY); - } - } - - soFar += str.len; - } - - setBlock(xo + length - 1, this.height - 1, Level.GROUND); - setBlock(xo + length - 2, this.height - 1, Level.GROUND); - setBlock(xo + length - 3, this.height - 1, Level.GROUND); - - return length; + return 0; } private int buildPipeJump(int xo, int maxLength) { @@ -599,7 +661,12 @@ public class PCGLevel extends Level { private int buildPlatformJump(int xo, int maxLength) { int length = 0; - int numPlatforms = random.nextInt((maxLength - 3) / 8); + int gapLength; + + for (gapLength = 1; shouldAddChallenge() && gapLength < 4; gapLength++) { + } + + int numPlatforms = random.nextInt((maxLength - 3) / (4 + gapLength)); if (numPlatforms > 1) { boolean found = false; @@ -607,10 +674,11 @@ public class PCGLevel extends Level { LevelComponent.PlatformLevel last; LevelComponent.PlatformLevel next; ArrayList jumps = new ArrayList(); - int heightMod; + int heightMod = 0; + int lastHeightMod = 0; + int enemyType; - jumps.add(random.nextBoolean() ? LevelComponent.PlatformLevel.BOT - : LevelComponent.PlatformLevel.MID_D); + jumps.add(LevelComponent.PlatformLevel.BOT); for (int i = 1; i < numPlatforms; i++) { last = jumps.get(i - 1); @@ -667,6 +735,10 @@ public class PCGLevel extends Level { length = 3; for (int x = 0; x < jumps.size(); x++) { + if (x > 0) { + lastHeightMod = heightMod; + } + switch (jumps.get(x)) { case TOP: heightMod = 12; @@ -681,19 +753,35 @@ public class PCGLevel extends Level { heightMod = 3; } - heightMod += (random.nextBoolean() ? random.nextInt(2) : -1 - * random.nextInt(2)); + heightMod += (x > 0 && random.nextBoolean() ? random.nextInt(2) + : -1 * random.nextInt(2)); - setBlock(xo + length, this.height - heightMod, - Level.BLOCK_EMPTY); - setBlock(xo + length + 1, this.height - heightMod, - Level.BLOCK_EMPTY); - setBlock(xo + length + 2, this.height - heightMod, - Level.BLOCK_EMPTY); - setBlock(xo + length + 3, this.height - heightMod, - Level.BLOCK_EMPTY); + while (x > 0 && heightMod - lastHeightMod >= 5) { + heightMod--; + } - length += 8; + setBlock(xo + length, this.height - heightMod, Level.ROCK); + setBlock(xo + length + 1, this.height - heightMod, Level.ROCK); + setBlock(xo + length + 2, this.height - heightMod, Level.ROCK); + setBlock(xo + length + 3, this.height - heightMod, Level.ROCK); + + if (shouldAddChallenge()) { + + enemyType = shouldAddChallenge() ? (shouldAddChallenge() ? (shouldAddChallenge() ? SpriteTemplate.ARMORED_TURTLE + : SpriteTemplate.RED_TURTLE) + : SpriteTemplate.GREEN_TURTLE) + : SpriteTemplate.GOOMPA; + + setSpriteTemplate( + xo + length + 3, + this.height - heightMod - 1, + new SpriteTemplate( + enemyType, + (enemyType == SpriteTemplate.RED_TURTLE && shouldAddChallenge()) + || enemyType != SpriteTemplate.RED_TURTLE)); + } + + length += 4 + gapLength; } }