Added 'MyNewLevel' as a possible value for the 'generator' arg.

To run it,
ant clean
ant
cd dist
java -jar CS8803_P3.jar generator=MyNewLevel
This commit is contained in:
Woody Folsom
2012-03-06 15:10:33 -05:00
parent 8e83234a87
commit 903437b727
3 changed files with 416 additions and 0 deletions

View File

@@ -3,6 +3,7 @@ package dk.itu.mario.engine;
import dk.itu.mario.MarioInterface.LevelGenerator; import dk.itu.mario.MarioInterface.LevelGenerator;
import dk.itu.mario.level.generator.CustomizedLevelGenerator; import dk.itu.mario.level.generator.CustomizedLevelGenerator;
import dk.itu.mario.level.generator.MyLevelGenerator; import dk.itu.mario.level.generator.MyLevelGenerator;
import dk.itu.mario.level.generator.MyNewLevelGenerator;
import dk.itu.mario.level.generator.RandomLevelGenerator; import dk.itu.mario.level.generator.RandomLevelGenerator;
public class ParsedArgs { public class ParsedArgs {
@@ -21,6 +22,8 @@ public class ParsedArgs {
} }
if ("MyLevel".equals(generatorClass)) { if ("MyLevel".equals(generatorClass)) {
return new MyLevelGenerator(); return new MyLevelGenerator();
} else if ("MyNewLevel".equals(generatorClass)) {
return new MyNewLevelGenerator();
} else if ("CustomizedLevel".equalsIgnoreCase(generatorClass)) { } else if ("CustomizedLevel".equalsIgnoreCase(generatorClass)) {
return new CustomizedLevelGenerator(); return new CustomizedLevelGenerator();
} else if ("RandomLevel".equalsIgnoreCase(generatorClass)) { } else if ("RandomLevel".equalsIgnoreCase(generatorClass)) {

View File

@@ -0,0 +1,386 @@
package dk.itu.mario.level;
import java.util.Random;
import dk.itu.mario.MarioInterface.GamePlay;
import dk.itu.mario.MarioInterface.LevelInterface;
import dk.itu.mario.engine.sprites.Enemy;
import dk.itu.mario.engine.sprites.SpriteTemplate;
public class MyNewLevel extends Level {
public static long lastSeed;
private static Random levelSeedRandom = new Random();
public int BLOCKS_COINS = 0; // the number of coin blocks
public int BLOCKS_EMPTY = 0; // the number of empty blocks
public int BLOCKS_POWER = 0; // the number of power blocks
public int COINS = 0; // These are the coins in boxes that Mario collect
// Store information about the level
public int ENEMIES = 0; // the number of enemies the level contains
private int difficulty;
private int gaps;
private int type;
Random random;
public MyNewLevel(int width, int height) {
super(width, height);
}
public MyNewLevel(int width, int height, long seed, int difficulty,
int type, GamePlay playerMetrics) {
this(width, height);
creat(seed, difficulty, type);
}
@Override
public RandomLevel clone() throws CloneNotSupportedException {
RandomLevel clone = new RandomLevel(width, height);
clone.xExit = xExit;
clone.yExit = yExit;
byte[][] map = getMap();
SpriteTemplate[][] st = getSpriteTemplate();
for (int i = 0; i < map.length; i++)
for (int j = 0; j < map[i].length; j++) {
clone.setBlock(i, j, map[i][j]);
clone.setSpriteTemplate(i, j, st[i][j]);
}
clone.BLOCKS_COINS = BLOCKS_COINS;
clone.BLOCKS_EMPTY = BLOCKS_EMPTY;
clone.BLOCKS_POWER = BLOCKS_POWER;
clone.ENEMIES = ENEMIES;
clone.COINS = COINS;
return clone;
}
public void creat(long seed, int difficulty, int type) {
this.type = type;
this.difficulty = difficulty;
lastSeed = seed;
random = new Random(seed);
// create the start location
int length = buildStraight(0, width, true);
length += buildPipe(length, width - length, false);
length += buildStraight(length, width, true);
length += buildPipe(length, width - length, true);
// create all of the medium sections
while (length < width - 64) {
length += buildStraight(length, width, true);
}
// set the end piece
int floor = height - 1 - random.nextInt(4);
xExit = length + 8;
yExit = floor;
// fills the end piece
for (int x = length; x < width; x++) {
for (int y = 0; y < height; y++) {
if (y >= floor) {
setBlock(x, y, GROUND);
}
}
}
if (type == LevelInterface.TYPE_CASTLE
|| type == LevelInterface.TYPE_UNDERGROUND) {
int ceiling = 0;
int run = 0;
for (int x = 0; x < width; x++) {
if (run-- <= 0 && x > 4) {
ceiling = random.nextInt(4);
run = random.nextInt(4) + 4;
}
for (int y = 0; y < height; y++) {
if ((x > 4 && y <= ceiling) || x < 1) {
setBlock(x, y, GROUND);
}
}
}
}
fixWalls();
}
private void addEnemyLine(int x0, int x1, int y) {
for (int x = x0; x < x1; x++) {
if (random.nextInt(35) < difficulty + 1) {
int type = random.nextInt(4);
if (difficulty < 1) {
type = Enemy.ENEMY_GOOMBA;
} else if (difficulty < 3) {
type = random.nextInt(3);
}
setSpriteTemplate(x, y,
new SpriteTemplate(type,
random.nextInt(35) < difficulty));
ENEMIES++;
}
}
}
private void blockify(Level level, boolean[][] blocks, int width, int height) {
int to = 0;
if (type == LevelInterface.TYPE_CASTLE) {
to = 4 * 2;
} else if (type == LevelInterface.TYPE_UNDERGROUND) {
to = 4 * 3;
}
boolean[][] b = new boolean[2][2];
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
for (int xx = x; xx <= x + 1; xx++) {
for (int yy = y; yy <= y + 1; yy++) {
int _xx = xx;
int _yy = yy;
if (_xx < 0)
_xx = 0;
if (_yy < 0)
_yy = 0;
if (_xx > width - 1)
_xx = width - 1;
if (_yy > height - 1)
_yy = height - 1;
b[xx - x][yy - y] = blocks[_xx][_yy];
}
}
if (b[0][0] == b[1][0] && b[0][1] == b[1][1]) {
if (b[0][0] == b[0][1]) {
if (b[0][0]) {
level.setBlock(x, y, (byte) (1 + 9 * 16 + to));
} else {
// KEEP OLD BLOCK!
}
} else {
if (b[0][0]) {
// down grass top?
level.setBlock(x, y, (byte) (1 + 10 * 16 + to));
} else {
// up grass top
level.setBlock(x, y, (byte) (1 + 8 * 16 + to));
}
}
} else if (b[0][0] == b[0][1] && b[1][0] == b[1][1]) {
if (b[0][0]) {
// right grass top
level.setBlock(x, y, (byte) (2 + 9 * 16 + to));
} else {
// left grass top
level.setBlock(x, y, (byte) (0 + 9 * 16 + to));
}
} else if (b[0][0] == b[1][1] && b[0][1] == b[1][0]) {
level.setBlock(x, y, (byte) (1 + 9 * 16 + to));
} else if (b[0][0] == b[1][0]) {
if (b[0][0]) {
if (b[0][1]) {
level.setBlock(x, y, (byte) (3 + 10 * 16 + to));
} else {
level.setBlock(x, y, (byte) (3 + 11 * 16 + to));
}
} else {
if (b[0][1]) {
// right up grass top
level.setBlock(x, y, (byte) (2 + 8 * 16 + to));
} else {
// left up grass top
level.setBlock(x, y, (byte) (0 + 8 * 16 + to));
}
}
} else if (b[0][1] == b[1][1]) {
if (b[0][1]) {
if (b[0][0]) {
// left pocket grass
level.setBlock(x, y, (byte) (3 + 9 * 16 + to));
} else {
// right pocket grass
level.setBlock(x, y, (byte) (3 + 8 * 16 + to));
}
} else {
if (b[0][0]) {
level.setBlock(x, y, (byte) (2 + 10 * 16 + to));
} else {
level.setBlock(x, y, (byte) (0 + 10 * 16 + to));
}
}
} else {
level.setBlock(x, y, (byte) (0 + 1 * 16 + to));
}
}
}
}
private int buildPipe(int xo, int maxLength, boolean pits) {
int numPipes = 4;
int floor = height - 1;
int length = numPipes * 4;
int height;
int[] pitLens = new int[numPipes];
int[] pipeGrad = new int[numPipes];
for (int i = 0; i < numPipes; i++) {
pitLens[i] = random.nextInt(6) + 1;
pipeGrad[i] = random.nextInt(5) - 2;
length += pitLens[i];
}
if (length > maxLength) {
return 0;
}
length = 0;
height = pipeGrad[0];
for (int i = 0; i < numPipes; i++) {
if (height < 1) {
height = 1;
}
setBlock(xo + length, floor, pits ? Level.HILL_TOP_LEFT
: Level.GROUND);
setBlock(xo + length + 1, floor, pits ? Level.HILL_TOP_RIGHT
: Level.GROUND);
for (int h = 0; h < height; h++) {
setBlock(xo + length, floor - 1 - h, Level.TUBE_SIDE_LEFT);
setBlock(xo + length + 1, floor - 1 - h, Level.TUBE_SIDE_RIGHT);
}
setBlock(xo + length, floor - 1 - height, Level.TUBE_TOP_LEFT);
setBlock(xo + length + 1, floor - 1 - height, Level.TUBE_TOP_RIGHT);
for (int j = 0; j < pitLens[i]; j++) {
if (!pits) {
setBlock(xo + length + 2 + j, floor, Level.GROUND);
}
}
length += (2 + pitLens[i]);
height += (i == numPipes - 1) ? 0 : pipeGrad[i + 1];
}
return length;
}
private int buildStraight(int xo, int maxLength, boolean safe) {
int length = random.nextInt(10) + 2;
if (safe)
length = 10 + random.nextInt(5);
if (length > maxLength)
length = maxLength;
int floor = height - 1 - random.nextInt(4);
// runs from the specified x position to the length of the segment
for (int x = xo; x < xo + length; x++) {
for (int y = 0; y < height; y++) {
if (y >= floor) {
setBlock(x, y, GROUND);
}
}
}
if (!safe) {
if (length > 5) {
decorate(xo, xo + length, floor);
}
}
return length;
}
private void decorate(int xStart, int xLength, int floor) {
// if its at the very top, just return
if (floor < 1)
return;
// boolean coins = random.nextInt(3) == 0;
boolean rocks = true;
// add an enemy line above the box
addEnemyLine(xStart + 1, xLength - 1, floor - 1);
int s = random.nextInt(4);
int e = random.nextInt(4);
if (floor - 2 > 0) {
if ((xLength - 1 - e) - (xStart + 1 + s) > 1) {
for (int x = xStart + 1 + s; x < xLength - 1 - e; x++) {
setBlock(x, floor - 2, COIN);
COINS++;
}
}
}
s = random.nextInt(4);
e = random.nextInt(4);
// this fills the set of blocks and the hidden objects inside them
if (floor - 4 > 0) {
if ((xLength - 1 - e) - (xStart + 1 + s) > 2) {
for (int x = xStart + 1 + s; x < xLength - 1 - e; x++) {
if (rocks) {
if (x != xStart + 1 && x != xLength - 2
&& random.nextInt(3) == 0) {
if (random.nextInt(4) == 0) {
setBlock(x, floor - 4, BLOCK_POWERUP);
BLOCKS_POWER++;
} else { // the fills a block with a hidden coin
setBlock(x, floor - 4, BLOCK_COIN);
BLOCKS_COINS++;
}
} else if (random.nextInt(4) == 0) {
if (random.nextInt(4) == 0) {
setBlock(x, floor - 4, (byte) (2 + 1 * 16));
} else {
setBlock(x, floor - 4, (byte) (1 + 1 * 16));
}
} else {
setBlock(x, floor - 4, BLOCK_EMPTY);
BLOCKS_EMPTY++;
}
}
}
}
}
}
private void fixWalls() {
boolean[][] blockMap = new boolean[width + 1][height + 1];
for (int x = 0; x < width + 1; x++) {
for (int y = 0; y < height + 1; y++) {
int blocks = 0;
for (int xx = x - 1; xx < x + 1; xx++) {
for (int yy = y - 1; yy < y + 1; yy++) {
if (getBlockCapped(xx, yy) == GROUND) {
blocks++;
}
}
}
blockMap[x][y] = blocks == 4;
}
}
blockify(this, blockMap, width + 1, height + 1);
}
}

View File

@@ -0,0 +1,27 @@
package dk.itu.mario.level.generator;
import java.util.Random;
import dk.itu.mario.MarioInterface.GamePlay;
import dk.itu.mario.MarioInterface.LevelGenerator;
import dk.itu.mario.MarioInterface.LevelInterface;
import dk.itu.mario.level.MyLevel;
import dk.itu.mario.level.MyNewLevel;
public class MyNewLevelGenerator extends CustomizedLevelGenerator implements
LevelGenerator {
public LevelInterface generateLevel(GamePlay playerMetrics) {
System.out.println("Generating my new level");
LevelInterface level = new MyNewLevel(320, 15, new Random().nextLong(), 1,
LevelInterface.TYPE_OVERGROUND, playerMetrics);
return level;
}
@Override
public LevelInterface generateLevel(String detailedInfo) {
// TODO Auto-generated method stub
return null;
}
}