Initial commit.

This commit is contained in:
Woody Folsom
2012-03-06 11:42:35 -05:00
commit 8e83234a87
124 changed files with 9621 additions and 0 deletions

View File

@@ -0,0 +1,563 @@
package dk.itu.mario.level;
import java.util.Random;
import dk.itu.mario.MarioInterface.Constraints;
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 CustomizedLevel extends Level implements LevelInterface {
Random random;
private static final int ODDS_STRAIGHT = 0;
private static final int ODDS_HILL_STRAIGHT = 1;
private static final int ODDS_TUBES = 2;
private static final int ODDS_JUMP = 3;
private static final int ODDS_CANNONS = 4;
private static final int JumpingThreshold = 3;
private int[] odds = new int[5];
private int totalOdds;
private int difficulty;
private int type;
private int gaps;
private int turtles;
private int coins;
private GamePlay playerM;
public CustomizedLevel(int width, int height, long seed, int difficulty,
int type, GamePlay playerMetrics) {
super(width, height);
this.playerM = playerMetrics;
creat(seed, difficulty, type);
}
public void creat(long seed, int difficulty, int type) {
this.type = type;
this.difficulty = difficulty;
odds[ODDS_STRAIGHT] = 30;
odds[ODDS_HILL_STRAIGHT] = 20;
odds[ODDS_TUBES] = 2 + 2 * difficulty;
int jumpDifficulty = 1;
// adapt the game so that it has a number of gaps proportional to the
// number of jumps the player made in the test level. The more the
// jumps,
// the more the gaps.
if (playerM.jumpsNumber > JumpingThreshold)
jumpDifficulty = 2;
odds[ODDS_JUMP] = jumpDifficulty;
odds[ODDS_CANNONS] = -10 + 5 * difficulty;
if (type != LevelInterface.TYPE_OVERGROUND) {
odds[ODDS_HILL_STRAIGHT] = 0;
}
for (int i = 0; i < odds.length; i++) {
// failsafe (no negative odds)
if (odds[i] < 0) {
odds[i] = 0;
}
totalOdds += odds[i];
odds[i] = totalOdds - odds[i];
}
random = new Random(seed);
// create the start location
int length = 0;
length += buildStraight(0, getWidth(), true);
// create all of the medium sections
while (length < getWidth() - 64) {
length += buildZone(length, getWidth() - length);
}
// set the end piece
int floor = height - 1 - random.nextInt(4);
// create the exit
xExit = length + 8;
yExit = floor;
for (int x = length; x < getWidth(); x++) {
for (int y = 0; y < height; y++) {
if (y >= floor) {
setBlock(x, y, Level.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 int buildZone(int x, int maxLength) {
int t = random.nextInt(totalOdds);
int type = 0;
for (int i = 0; i < odds.length; i++) {
if (odds[ODDS_JUMP] <= t * 2 + 30) {
type = ODDS_JUMP;
break;
}
if (odds[i] <= t) {
type = i;
}
}
switch (type) {
case ODDS_STRAIGHT:
return buildStraight(x, maxLength, false);
case ODDS_HILL_STRAIGHT:
return buildHillStraight(x, maxLength);
case ODDS_TUBES:
return buildTubes(x, maxLength);
case ODDS_JUMP:
if (gaps < Constraints.gaps)
return buildJump(x, maxLength);
else
return buildStraight(x, maxLength, false);
case ODDS_CANNONS:
return buildCannons(x, maxLength);
}
return 0;
}
private int buildJump(int xo, int maxLength) {
gaps++;
// jl: jump length
// js: the number of blocks that are available at either side for free
int js = random.nextInt(4) + 2;
int jl = random.nextInt(2) + 2;
int length = js * 2 + jl;
boolean hasStairs = random.nextInt(3) == 0;
int floor = height - 1 - random.nextInt(4);
// run for the from the start x position, for the whole length
for (int x = xo; x < xo + length; x++) {
if (x < xo + js || x > xo + length - js - 1) {
// run for all y's since we need to paint blocks upward
for (int y = 0; y < height; y++) { // paint ground up until the
// floor
if (y >= floor) {
setBlock(x, y, GROUND);
}
// if it is above ground, start making stairs of rocks
else if (hasStairs) { // LEFT SIDE
if (x < xo + js) { // we need to max it out and level
// because it wont
// paint ground correctly unless two bricks are side
// by side
if (y >= floor - (x - xo) + 1) {
setBlock(x, y, ROCK);
}
} else { // RIGHT SIDE
if (y >= floor - ((xo + length) - x) + 2) {
setBlock(x, y, ROCK);
}
}
}
}
}
}
return length;
}
private int buildCannons(int xo, int maxLength) {
int length = random.nextInt(10) + 2;
if (length > maxLength)
length = maxLength;
int floor = height - 1 - random.nextInt(4);
int xCannon = xo + 1 + random.nextInt(4);
for (int x = xo; x < xo + length; x++) {
if (x > xCannon) {
xCannon += 2 + random.nextInt(4);
}
if (xCannon == xo + length - 1)
xCannon += 10;
int cannonHeight = floor - random.nextInt(4) - 1;
for (int y = 0; y < height; y++) {
if (y >= floor) {
setBlock(x, y, (byte) (1 + 9 * 16));
} else {
if (x == xCannon && y >= cannonHeight) {
if (y == cannonHeight) {
setBlock(x, y, (byte) (14 + 0 * 16));
} else if (y == cannonHeight + 1) {
setBlock(x, y, (byte) (14 + 1 * 16));
} else {
setBlock(x, y, (byte) (14 + 2 * 16));
}
}
}
}
}
return length;
}
private int buildHillStraight(int xo, int maxLength) {
int length = random.nextInt(10) + 10;
if (length > maxLength)
length = maxLength;
int floor = height - 1 - random.nextInt(4);
for (int x = xo; x < xo + length; x++) {
for (int y = 0; y < height; y++) {
if (y >= floor) {
setBlock(x, y, Level.GROUND);
}
}
}
addEnemyLine(xo + 1, xo + length - 1, floor - 1);
int h = floor;
boolean keepGoing = true;
boolean[] occupied = new boolean[length];
while (keepGoing) {
h = h - 2 - random.nextInt(3);
if (h <= 0) {
keepGoing = false;
} else {
int l = random.nextInt(5) + 3;
int xxo = random.nextInt(length - l - 2) + xo + 1;
if (occupied[xxo - xo] || occupied[xxo - xo + l]
|| occupied[xxo - xo - 1] || occupied[xxo - xo + l + 1]) {
keepGoing = false;
} else {
occupied[xxo - xo] = true;
occupied[xxo - xo + l] = true;
addEnemyLine(xxo, xxo + l, h - 1);
if (random.nextInt(4) == 0) {
decorate(xxo - 1, xxo + l + 1, h);
keepGoing = false;
}
for (int x = xxo; x < xxo + l; x++) {
for (int y = h; y < floor; y++) {
int xx = 5;
if (x == xxo)
xx = 4;
if (x == xxo + l - 1)
xx = 6;
int yy = 9;
if (y == h)
yy = 8;
if (getBlock(x, y) == 0) {
setBlock(x, y, (byte) (xx + yy * 16));
} else {
if (getBlock(x, y) == Level.HILL_TOP_LEFT)
setBlock(x, y, Level.HILL_TOP_LEFT_IN);
if (getBlock(x, y) == Level.HILL_TOP_RIGHT)
setBlock(x, y, Level.HILL_TOP_RIGHT_IN);
}
}
}
}
}
}
return length;
}
private void addEnemyLine(int x0, int x1, int y) {
for (int x = x0; x < x1; x++) {
if (random.nextInt(50) < 25) {
int type = random.nextInt(4);
type = random.nextInt(3);
if (turtles < Constraints.turtels) {
if (type == Enemy.ENEMY_GREEN_KOOPA
|| type == Enemy.ENEMY_RED_KOOPA) {
turtles++;
setSpriteTemplate(x, y,
new SpriteTemplate(type,
random.nextInt(35) < difficulty));
} else {
setSpriteTemplate(x, y,
new SpriteTemplate(type,
random.nextInt(35) < difficulty));
}
} else {
setSpriteTemplate(
x,
y,
new SpriteTemplate(Enemy.ENEMY_GOOMBA, random
.nextInt(35) < difficulty));
}
}
}
}
private int buildTubes(int xo, int maxLength) {
int length = random.nextInt(10) + 5;
if (length > maxLength)
length = maxLength;
int floor = height - 1 - random.nextInt(4);
int xTube = xo + 1 + random.nextInt(4);
int tubeHeight = floor - random.nextInt(2) - 2;
for (int x = xo; x < xo + length; x++) {
if (x > xTube + 1) {
xTube += 3 + random.nextInt(4);
tubeHeight = floor - random.nextInt(2) - 2;
}
if (xTube >= xo + length - 2)
xTube += 10;
if (x == xTube && random.nextInt(11) < difficulty + 1) {
setSpriteTemplate(x, tubeHeight, new SpriteTemplate(
Enemy.ENEMY_FLOWER, false));
}
for (int y = 0; y < height; y++) {
if (y >= floor) {
setBlock(x, y, (byte) (1 + 9 * 16));
} else {
if ((x == xTube || x == xTube + 1) && y >= tubeHeight) {
int xPic = 10 + x - xTube;
if (y == tubeHeight) {
// tube top
setBlock(x, y, (byte) (xPic + 0 * 16));
} else {
// tube side
setBlock(x, y, (byte) (xPic + 1 * 16));
}
}
}
}
}
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, Level.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 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, (byte) (2 + 2 * 16));
}
}
}
s = random.nextInt(4);
e = random.nextInt(4);
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(2) == 0) {
if (random.nextInt(2) == 0) {
setBlock(x, floor - 4, BLOCK_POWERUP);
} else {
if (coins < Constraints.coinBlocks) {
coins++;
setBlock(x, floor - 4, BLOCK_COIN);
} else {
setBlock(x, floor - 4, BLOCK_EMPTY);
}
}
} 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);
}
}
}
}
}
}
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);
}
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));
}
}
}
}
}