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

Binary file not shown.

View File

@@ -0,0 +1,152 @@
package dk.itu.mario.engine.sprites;
import dk.itu.mario.engine.Art;
import dk.itu.mario.scene.LevelScene;
public class BulletBill extends Sprite
{
private int width = 4;
int height = 24;
private LevelScene world;
public int facing;
public boolean avoidCliffs = false;
public int anim;
public boolean dead = false;
private int deadTime = 0;
public BulletBill(LevelScene world, float x, float y, int dir)
{
sheet = Art.enemies;
this.x = x;
this.y = y;
this.world = world;
xPicO = 8;
yPicO = 31;
height = 12;
facing = 0;
wPic = 16;
yPic = 5;
xPic = 0;
ya = -5;
this.facing = dir;
}
public void collideCheck()
{
if (dead) return;
float xMarioD = world.mario.x - x;
float yMarioD = world.mario.y - y;
float w = 16;
if (xMarioD > -16 && xMarioD < 16)
{
if (yMarioD > -height && yMarioD < world.mario.height)
{
if (world.mario.ya > 0 && yMarioD <= 0 && (!world.mario.onGround || !world.mario.wasOnGround))
{
world.mario.stomp(this);
dead = true;
xa = 0;
ya = 1;
deadTime = 100;
}
else
{
world.mario.getHurt(this);
}
}
}
}
public void move()
{
if (deadTime > 0)
{
deadTime--;
if (deadTime == 0)
{
deadTime = 1;
for (int i = 0; i < 8; i++)
{
world.addSprite(new Sparkle((int) (x + Math.random() * 16 - 8) + 4, (int) (y - Math.random() * 8) + 4, (float) (Math.random() * 2 - 1), (float) Math.random() * -1, 0, 1, 5));
}
spriteContext.removeSprite(this);
}
x += xa;
y += ya;
ya *= 0.95;
ya += 1;
return;
}
float sideWaysSpeed = 4f;
xa = facing * sideWaysSpeed;
xFlipPic = facing == -1;
move(xa, 0);
}
private boolean move(float xa, float ya)
{
x += xa;
return true;
}
public boolean fireballCollideCheck(Fireball fireball)
{
if (deadTime != 0) return false;
float xD = fireball.x - x;
float yD = fireball.y - y;
if (xD > -16 && xD < 16)
{
if (yD > -height && yD < fireball.height)
{
return true;
}
}
return false;
}
public boolean shellCollideCheck(Shell shell)
{
if (deadTime != 0) return false;
float xD = shell.x - x;
float yD = shell.y - y;
if (xD > -16 && xD < 16)
{
if (yD > -height && yD < shell.height)
{
world.sound.play(Art.samples[Art.SAMPLE_MARIO_KICK], this, 1, 1, 1);
dead = true;
xa = 0;
ya = 1;
deadTime = 100;
if(world.recorder != null)
world.recorder.shellKillRecord(this);
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,41 @@
package dk.itu.mario.engine.sprites;
import dk.itu.mario.engine.Art;
import dk.itu.mario.level.Level;
public class CoinAnim extends Sprite
{
private int life = 10;
public CoinAnim(int xTile, int yTile)
{
sheet = Art.level;
wPic = hPic = 16;
x = xTile * 16;
y = yTile * 16 - 16;
xa = 0;
ya = -6f;
xPic = 0;
yPic = 2;
}
public void move()
{
if (life-- < 0)
{
Sprite.spriteContext.removeSprite(this);
for (int xx = 0; xx < 2; xx++)
for (int yy = 0; yy < 2; yy++)
Sprite.spriteContext.addSprite(new Sparkle((int)x + xx * 8 + (int) (Math.random() * 8), (int)y + yy * 8 + (int) (Math.random() * 8), 0, 0, 0, 2, 5));
}
xPic = life & 3;
x += xa;
y += ya;
ya += 1;
}
}

View File

@@ -0,0 +1,443 @@
package dk.itu.mario.engine.sprites;
import java.awt.Graphics;
import dk.itu.mario.engine.Art;
import dk.itu.mario.level.Level;
import dk.itu.mario.scene.LevelScene;
public class Enemy extends Sprite
{
public static final int ENEMY_RED_KOOPA = 0;
public static final int ENEMY_GREEN_KOOPA = 1;
public static final int ENEMY_GOOMBA = 2;
public static final int ENEMY_SPIKY = 3;
public static final int ENEMY_FLOWER = 4;
private static float GROUND_INERTIA = 0.89f;
private static float AIR_INERTIA = 0.89f;
private float runTime;
private boolean onGround = false;
private boolean mayJump = false;
private int jumpTime = 0;
private float xJumpSpeed;
private float yJumpSpeed;
int width = 4;
int height = 24;
private LevelScene world;
public int facing;
public int deadTime = 0;
public boolean flyDeath = false;
public boolean avoidCliffs = true;
public int type;
public boolean winged = true;
private int wingTime = 0;
public boolean noFireballDeath;
public Enemy(LevelScene world, int x, int y, int dir, int type, boolean winged)
{
this.type = type;
sheet = Art.enemies;
this.winged = winged;
this.world = world;
this.x = x;
this.y = y;
xPicO = 8;
yPicO = 31;
avoidCliffs = type == Enemy.ENEMY_RED_KOOPA;
noFireballDeath = type == Enemy.ENEMY_SPIKY;
yPic = type;
if (yPic > 1) height = 12;
facing = dir;
if (facing == 0) facing = 1;
this.wPic = 16;
}
public void collideCheck()
{
if (deadTime != 0)
{
return;
}
float xMarioD = world.mario.x - x;
float yMarioD = world.mario.y - y;
float w = 16;
//if the distance to mario is within the sprite (in x)
if (xMarioD > -width*2-4 && xMarioD < width*2+4)
{
//if the distance to mario is within the sprite (in y)
if (yMarioD > -height && yMarioD < world.mario.height)
{
if (type != Enemy.ENEMY_SPIKY && world.mario.ya > 0 && yMarioD <= 0 && (!world.mario.onGround || !world.mario.wasOnGround))
{
world.mario.stomp(this);
if (winged)
{
winged = false;
ya = 0;
}
else
{
this.yPicO = 31 - (32 - 8);
hPic = 8;
if (spriteTemplate != null) spriteTemplate.isDead = true;
deadTime = 10;
winged = false;
if (type == Enemy.ENEMY_RED_KOOPA)
{
spriteContext.addSprite(new Shell(world, x, y, 0));
}
else if (type == Enemy.ENEMY_GREEN_KOOPA)
{
spriteContext.addSprite(new Shell(world, x, y, 1));
}
}
}
else
{
world.mario.getHurt(this);
}
}
}
}
public void move()
{
//TODO: some kind of suicide error when one enemy is created
if (y > world.level.getHeight() * 16 + 16 && deadTime <= 0)
{
if(world.recorder != null)
world.recorder.killSuicideRecord(this);
deadTime = 1;
}
wingTime++;
if (deadTime > 0)
{
deadTime--;
if (deadTime == 0)
{
deadTime = 1;
for (int i = 0; i < 8; i++)
{
world.addSprite(new Sparkle((int) (x + Math.random() * 16 - 8) + 4, (int) (y - Math.random() * 8) + 4, (float) (Math.random() * 2 - 1), (float) Math.random() * -1, 0, 1, 5));
}
spriteContext.removeSprite(this);
}
if (flyDeath)
{
x += xa;
y += ya;
ya *= 0.95;
ya += 1;
}
return;
}
float sideWaysSpeed = 1.75f;
// float sideWaysSpeed = onGround ? 2.5f : 1.2f;
if (xa > 2)
{
facing = 1;
}
if (xa < -2)
{
facing = -1;
}
xa = facing * sideWaysSpeed;
mayJump = (onGround);
xFlipPic = facing == -1;
runTime += (Math.abs(xa)) + 5;
int runFrame = ((int) (runTime / 20)) % 2;
if (!onGround)
{
runFrame = 1;
}
if (!move(xa, 0)) facing = -facing;
onGround = false;
move(0, ya);
ya *= winged ? 0.95f : 0.85f;
if (onGround)
{
xa *= GROUND_INERTIA;
}
else
{
xa *= AIR_INERTIA;
}
if (!onGround)
{
if (winged)
{
ya += 0.6f;
}
else
{
ya += 2;
}
}
else if (winged)
{
ya = -10;
}
if (winged) runFrame = wingTime / 4 % 2;
xPic = runFrame;
}
private boolean move(float xa, float ya)
{
while (xa > 8)
{
if (!move(8, 0)) return false;
xa -= 8;
}
while (xa < -8)
{
if (!move(-8, 0)) return false;
xa += 8;
}
while (ya > 8)
{
if (!move(0, 8)) return false;
ya -= 8;
}
while (ya < -8)
{
if (!move(0, -8)) return false;
ya += 8;
}
boolean collide = false;
if (ya > 0)
{
if (isBlocking(x + xa - width, y + ya, xa, 0)) collide = true;
else if (isBlocking(x + xa + width, y + ya, xa, 0)) collide = true;
else if (isBlocking(x + xa - width, y + ya + 1, xa, ya)) collide = true;
else if (isBlocking(x + xa + width, y + ya + 1, xa, ya)) collide = true;
}
if (ya < 0)
{
if (isBlocking(x + xa, y + ya - height, xa, ya)) collide = true;
else if (collide || isBlocking(x + xa - width, y + ya - height, xa, ya)) collide = true;
else if (collide || isBlocking(x + xa + width, y + ya - height, xa, ya)) collide = true;
}
if (xa > 0)
{
if (isBlocking(x + xa + width, y + ya - height, xa, ya)) collide = true;
if (isBlocking(x + xa + width, y + ya - height / 2, xa, ya)) collide = true;
if (isBlocking(x + xa + width, y + ya, xa, ya)) collide = true;
if (avoidCliffs && onGround && !world.level.isBlocking((int) ((x + xa + width) / 16), (int) ((y) / 16 + 1), xa, 1)) collide = true;
}
if (xa < 0)
{
if (isBlocking(x + xa - width, y + ya - height, xa, ya)) collide = true;
if (isBlocking(x + xa - width, y + ya - height / 2, xa, ya)) collide = true;
if (isBlocking(x + xa - width, y + ya, xa, ya)) collide = true;
if (avoidCliffs && onGround && !world.level.isBlocking((int) ((x + xa - width) / 16), (int) ((y) / 16 + 1), xa, 1)) collide = true;
}
if (collide)
{
if (xa < 0)
{
x = (int) ((x - width) / 16) * 16 + width;
this.xa = 0;
}
if (xa > 0)
{
x = (int) ((x + width) / 16 + 1) * 16 - width - 1;
this.xa = 0;
}
if (ya < 0)
{
y = (int) ((y - height) / 16) * 16 + height;
jumpTime = 0;
this.ya = 0;
}
if (ya > 0)
{
y = (int) (y / 16 + 1) * 16 - 1;
onGround = true;
}
return false;
}
else
{
x += xa;
y += ya;
return true;
}
}
private boolean isBlocking(float _x, float _y, float xa, float ya)
{
int x = (int) (_x / 16);
int y = (int) (_y / 16);
if (x == (int) (this.x / 16) && y == (int) (this.y / 16)) return false;
boolean blocking = world.level.isBlocking(x, y, xa, ya);
byte block = world.level.getBlock(x, y);
return blocking;
}
public boolean shellCollideCheck(Shell shell)
{
if (deadTime != 0) return false;
float xD = shell.x - x;
float yD = shell.y - y;
if (xD > -16 && xD < 16)
{
if (yD > -height && yD < shell.height)
{
world.sound.play(Art.samples[Art.SAMPLE_MARIO_KICK], this, 1, 1, 1);
xa = shell.facing * 2;
ya = -5;
flyDeath = true;
if (spriteTemplate != null) spriteTemplate.isDead = true;
deadTime = 100;
winged = false;
hPic = -hPic;
yPicO = -yPicO + 16;
if(world.recorder != null)
world.recorder.shellKillRecord(this);
return true;
}
}
return false;
}
public boolean fireballCollideCheck(Fireball fireball)
{
if (deadTime != 0) return false;
float xD = fireball.x - x;
float yD = fireball.y - y;
if (xD > -16 && xD < 16)
{
if (yD > -height && yD < fireball.height)
{
if (noFireballDeath) return true;
world.sound.play(Art.samples[Art.SAMPLE_MARIO_KICK], this, 1, 1, 1);
xa = fireball.facing * 2;
ya = -5;
flyDeath = true;
if (spriteTemplate != null) spriteTemplate.isDead = true;
deadTime = 100;
winged = false;
hPic = -hPic;
yPicO = -yPicO + 16;
if(world.recorder != null)
world.recorder.fireKillRecord(this);
return true;
}
}
return false;
}
public void bumpCheck(int xTile, int yTile)
{
if (deadTime != 0) return;
if (x + width > xTile * 16 && x - width < xTile * 16 + 16 && yTile == (int) ((y - 1) / 16))
{
world.sound.play(Art.samples[Art.SAMPLE_MARIO_KICK], this, 1, 1, 1);
xa = -world.mario.facing * 2;
ya = -5;
flyDeath = true;
if (spriteTemplate != null) spriteTemplate.isDead = true;
deadTime = 100;
winged = false;
hPic = -hPic;
yPicO = -yPicO + 16;
}
}
public void render(Graphics og, float alpha)
{
if (winged)
{
int xPixel = (int) (xOld + (x - xOld) * alpha) - xPicO;
int yPixel = (int) (yOld + (y - yOld) * alpha) - yPicO;
if (type == Enemy.ENEMY_GREEN_KOOPA || type == Enemy.ENEMY_RED_KOOPA)
{
}
else
{
xFlipPic = !xFlipPic;
og.drawImage(sheet[wingTime / 4 % 2][4], xPixel + (xFlipPic ? wPic : 0) + (xFlipPic ? 10 : -10), yPixel + (yFlipPic ? hPic : 0) - 8, xFlipPic ? -wPic : wPic, yFlipPic ? -hPic : hPic, null);
xFlipPic = !xFlipPic;
}
}
super.render(og, alpha);
if (winged)
{
int xPixel = (int) (xOld + (x - xOld) * alpha) - xPicO;
int yPixel = (int) (yOld + (y - yOld) * alpha) - yPicO;
if (type == Enemy.ENEMY_GREEN_KOOPA || type == Enemy.ENEMY_RED_KOOPA)
{
og.drawImage(sheet[wingTime / 4 % 2][4], xPixel + (xFlipPic ? wPic : 0) + (xFlipPic ? 10 : -10), yPixel + (yFlipPic ? hPic : 0) - 10, xFlipPic ? -wPic : wPic, yFlipPic ? -hPic : hPic, null);
}
else
{
og.drawImage(sheet[wingTime / 4 % 2][4], xPixel + (xFlipPic ? wPic : 0) + (xFlipPic ? 10 : -10), yPixel + (yFlipPic ? hPic : 0) - 8, xFlipPic ? -wPic : wPic, yFlipPic ? -hPic : hPic, null);
}
}
}
}

View File

@@ -0,0 +1,63 @@
package dk.itu.mario.engine.sprites;
import dk.itu.mario.engine.Art;
import dk.itu.mario.scene.LevelScene;
public class FireFlower extends Sprite
{
private int width = 4;
int height = 24;
private LevelScene world;
public int facing;
public boolean avoidCliffs = false;
private int life;
public FireFlower(LevelScene world, int x, int y)
{
sheet = Art.items;
this.x = x;
this.y = y;
this.world = world;
xPicO = 8;
yPicO = 15;
xPic = 1;
yPic = 0;
height = 12;
facing = 1;
wPic = hPic = 16;
life = 0;
}
public void collideCheck()
{
float xMarioD = world.mario.x - x;
float yMarioD = world.mario.y - y;
float w = 16;
if (xMarioD > -16 && xMarioD < 16)
{
if (yMarioD > -height && yMarioD < world.mario.height)
{
world.mario.getFlower();
spriteContext.removeSprite(this);
}
}
}
public void move()
{
if (life<9)
{
layer = 0;
y--;
life++;
return;
}
}
}

View File

@@ -0,0 +1,220 @@
package dk.itu.mario.engine.sprites;
import dk.itu.mario.engine.Art;
import dk.itu.mario.scene.LevelScene;
public class Fireball extends Sprite
{
private static float GROUND_INERTIA = 0.89f;
private static float AIR_INERTIA = 0.89f;
private float runTime;
private boolean onGround = false;
private int width = 4;
int height = 24;
private LevelScene world;
public int facing;
public boolean avoidCliffs = false;
public int anim;
public boolean dead = false;
private int deadTime = 0;
public Fireball(LevelScene world, float x, float y, int facing)
{
sheet = Art.particles;
this.x = x;
this.y = y;
this.world = world;
xPicO = 4;
yPicO = 4;
yPic = 3;
height = 8;
this.facing = facing;
wPic = 8;
hPic = 8;
xPic = 4;
ya = 4;
}
public void move()
{
if (deadTime > 0)
{
for (int i = 0; i < 8; i++)
{
world.addSprite(new Sparkle((int) (x + Math.random() * 8 - 4)+4, (int) (y + Math.random() * 8-4)+2, (float) Math.random() * 2 - 1-facing, (float) Math.random() *2 -1, 0, 1, 5));
}
spriteContext.removeSprite(this);
return;
}
if (facing != 0) anim++;
float sideWaysSpeed = 8f;
// float sideWaysSpeed = onGround ? 2.5f : 1.2f;
if (xa > 2)
{
facing = 1;
}
if (xa < -2)
{
facing = -1;
}
xa = facing * sideWaysSpeed;
world.checkFireballCollide(this);
xFlipPic = facing == -1;
runTime += (Math.abs(xa)) + 5;
xPic = (anim) % 4;
if (!move(xa, 0))
{
die();
}
onGround = false;
move(0, ya);
if (onGround) ya = -10;
ya *= 0.95f;
if (onGround)
{
xa *= GROUND_INERTIA;
}
else
{
xa *= AIR_INERTIA;
}
if (!onGround)
{
ya += 1.5;
}
}
private boolean move(float xa, float ya)
{
while (xa > 8)
{
if (!move(8, 0)) return false;
xa -= 8;
}
while (xa < -8)
{
if (!move(-8, 0)) return false;
xa += 8;
}
while (ya > 8)
{
if (!move(0, 8)) return false;
ya -= 8;
}
while (ya < -8)
{
if (!move(0, -8)) return false;
ya += 8;
}
boolean collide = false;
if (ya > 0)
{
if (isBlocking(x + xa - width, y + ya, xa, 0)) collide = true;
else if (isBlocking(x + xa + width, y + ya, xa, 0)) collide = true;
else if (isBlocking(x + xa - width, y + ya + 1, xa, ya)) collide = true;
else if (isBlocking(x + xa + width, y + ya + 1, xa, ya)) collide = true;
}
if (ya < 0)
{
if (isBlocking(x + xa, y + ya - height, xa, ya)) collide = true;
else if (collide || isBlocking(x + xa - width, y + ya - height, xa, ya)) collide = true;
else if (collide || isBlocking(x + xa + width, y + ya - height, xa, ya)) collide = true;
}
if (xa > 0)
{
if (isBlocking(x + xa + width, y + ya - height, xa, ya)) collide = true;
if (isBlocking(x + xa + width, y + ya - height / 2, xa, ya)) collide = true;
if (isBlocking(x + xa + width, y + ya, xa, ya)) collide = true;
if (avoidCliffs && onGround && !world.level.isBlocking((int) ((x + xa + width) / 16), (int) ((y) / 16 + 1), xa, 1)) collide = true;
}
if (xa < 0)
{
if (isBlocking(x + xa - width, y + ya - height, xa, ya)) collide = true;
if (isBlocking(x + xa - width, y + ya - height / 2, xa, ya)) collide = true;
if (isBlocking(x + xa - width, y + ya, xa, ya)) collide = true;
if (avoidCliffs && onGround && !world.level.isBlocking((int) ((x + xa - width) / 16), (int) ((y) / 16 + 1), xa, 1)) collide = true;
}
if (collide)
{
if (xa < 0)
{
x = (int) ((x - width) / 16) * 16 + width;
this.xa = 0;
}
if (xa > 0)
{
x = (int) ((x + width) / 16 + 1) * 16 - width - 1;
this.xa = 0;
}
if (ya < 0)
{
y = (int) ((y - height) / 16) * 16 + height;
this.ya = 0;
}
if (ya > 0)
{
y = (int) (y / 16 + 1) * 16 - 1;
onGround = true;
}
return false;
}
else
{
x += xa;
y += ya;
return true;
}
}
private boolean isBlocking(float _x, float _y, float xa, float ya)
{
int x = (int) (_x / 16);
int y = (int) (_y / 16);
if (x == (int) (this.x / 16) && y == (int) (this.y / 16)) return false;
boolean blocking = world.level.isBlocking(x, y, xa, ya);
byte block = world.level.getBlock(x, y);
return blocking;
}
public void die()
{
dead = true;
xa = -facing * 2;
ya = -5;
deadTime = 100;
}
}

View File

@@ -0,0 +1,103 @@
package dk.itu.mario.engine.sprites;
import dk.itu.mario.level.Level;
import dk.itu.mario.scene.LevelScene;
import dk.itu.mario.engine.sprites.*;
public class FlowerEnemy extends Enemy
{
private int tick;
private int yStart;
private int jumpTime = 0;
private LevelScene world;
public FlowerEnemy(LevelScene world, int x, int y)
{
super(world, x, y, 1, ENEMY_SPIKY, false);
noFireballDeath = false;
this.world = world;
this.xPic = 0;
this.yPic = 6;
this.yPicO = 24;
this.height = 12;
this.width = 2;
yStart = y;
ya = -8;
this.y-=1;
this.layer = 0;
for (int i=0; i<4; i++)
{
move();
}
}
public void move()
{
if (deadTime > 0)
{
deadTime--;
if (deadTime == 0)
{
deadTime = 1;
for (int i = 0; i < 8; i++)
{
world.addSprite(new Sparkle((int) (x + Math.random() * 16 - 8) + 4, (int) (y - Math.random() * 8) + 4, (float) (Math.random() * 2 - 1), (float) Math.random() * -1, 0, 1, 5));
}
spriteContext.removeSprite(this);
}
x += xa;
y += ya;
ya *= 0.95;
ya += 1;
return;
}
tick++;
if (y>=yStart)
{
y = yStart;
int xd = (int)(Math.abs(world.mario.x-x));
jumpTime++;
if (jumpTime>40 && xd>24)
{
ya = -8;
}
else
{
ya = 0;
}
}
else
{
jumpTime = 0;
}
y+=ya;
ya*=0.9;
ya+=0.1f;
xPic = ((tick/2)&1)*2+((tick/6)&1);
}
/* public void render(Graphics og, float alpha)
{
if (!visible) return;
int xPixel = (int)(xOld+(x-xOld)*alpha)-xPicO;
int yPixel = (int)(yOld+(y-yOld)*alpha)-yPicO;
int a = ((tick/3)&1)*2;
// a += ((tick/8)&1);
og.drawImage(sheet[a*2+0][6], xPixel-8, yPixel+8, 16, 32, null);
og.drawImage(sheet[a*2+1][6], xPixel+8, yPixel+8, 16, 32, null);
}*/
}

View File

@@ -0,0 +1,918 @@
package dk.itu.mario.engine.sprites;
import dk.itu.mario.engine.Art;
import dk.itu.mario.engine.DataRecorder;
import dk.itu.mario.engine.sonar.FixedSoundSource;
import dk.itu.mario.level.Level;
import dk.itu.mario.scene.LevelScene;
import dk.itu.mario.scene.Scene;
public class Mario extends Sprite
{
public static boolean large = false;
public static boolean fire = false;
public static int coins = 0;
public static int lives = 3;
public static String levelString = "none";
public static void resetStatic()
{
large = false;
fire = false;
coins = 0;
lives = 3;
levelString = "none";
}
public static final int KEY_LEFT = 0;
public static final int KEY_RIGHT = 1;
public static final int KEY_DOWN = 2;
public static final int KEY_UP = 3;
public static final int KEY_JUMP = 4;
public static final int KEY_SPEED = 5;
public static final int KEY_ENTER = 6;
private static float GROUND_INERTIA = 0.89f;
private static float AIR_INERTIA = 0.89f;
public boolean[] keys;
private float runTime;
boolean wasOnGround = false;
boolean onGround = false;
private boolean mayJump = false;
public boolean ducking = false;
public boolean running = false;
public int direction = 0;
private boolean sliding = false;
private int jumpTime = 0;
private float xJumpSpeed;
private float yJumpSpeed;
private boolean canShoot = false;
int width = 4;
int height = 24;
private LevelScene world;
public int facing;
private int powerUpTime = 0;
public int xDeathPos, yDeathPos;
public int deathTime = 0;
public int winTime = 0;
private int invulnerableTime = 0;
public Sprite carried = null;
private static Mario instance;
public Mario(LevelScene world)
{
Mario.instance = this;
this.world = world;
keys = Scene.keys;
x = 32;
y = 0;
facing = 1;
//TODO: REMOVE THESE TEST VARIABLES
// Mario.large = true;
// Mario.fire = true;
setLarge(Mario.large, Mario.fire);
}
private boolean lastLarge;
private boolean lastFire;
private boolean newLarge;
private boolean newFire;
private void blink(boolean on)
{
Mario.large = on?newLarge:lastLarge;
Mario.fire = on?newFire:lastFire;
if (large)
{
sheet = Art.mario;
if (fire)
sheet = Art.fireMario;
xPicO = 16;
yPicO = 31;
wPic = hPic = 32;
}
else
{
sheet = Art.smallMario;
xPicO = 8;
yPicO = 15;
wPic = hPic = 16;
}
calcPic();
}
void setLarge(boolean large, boolean fire)
{
if (fire) large = true;
if (!large) fire = false;
lastLarge = Mario.large;
lastFire = Mario.fire;
Mario.large = large;
Mario.fire = fire;
newLarge = Mario.large;
newFire = Mario.fire;
blink(true);
}
public void move()
{
if(deathTime == 0 && winTime == 0){
if (keys[KEY_DOWN] && large && ducking)
{
if(world.recorder != null && world.recorder.recording)
world.recorder.startDuckRecord();
}
else
{
if(world.recorder != null && world.recorder.recording && !ducking)
world.recorder.endDuckRecord();
}
}
if(deathTime == 0 && winTime == 0){
if(keys[KEY_SPEED]){
if(world.recorder!= null && world.recorder.recording){
world.recorder.startRunningRecord();
}
running = true;
}
else{
if(world.recorder!= null && world.recorder.recording){
world.recorder.endRunningRecord();
}
running = false;
}
}
if (winTime > 0)
{
winTime++;
xa = 0;
ya = 0;
return;
}
if (deathTime > 0)
{
deathTime++;
if (deathTime < 11)
{
xa = 0;
ya = 0;
}
else if (deathTime == 11)
{
ya = -15;
}
else
{
ya += 2;
}
x += xa;
y += ya;
return;
}
if (powerUpTime != 0)
{
if (powerUpTime > 0)
{
powerUpTime--;
blink(((powerUpTime / 3) & 1) == 0);
}
else
{
powerUpTime++;
blink(((-powerUpTime / 3) & 1) == 0);
}
if (powerUpTime == 0) world.paused = false;
calcPic();
return;
}
if (invulnerableTime > 0) invulnerableTime--;
visible = ((invulnerableTime / 2) & 1) == 0;
wasOnGround = onGround;
float sideWaysSpeed = keys[KEY_SPEED] ? 1.2f : 0.6f;
// float sideWaysSpeed = onGround ? 2.5f : 1.2f;
if (onGround)
{
if (keys[KEY_DOWN] && large)
{
if(world.recorder != null)
world.recorder.startDuckRecord();
ducking = true;
}
else
{
if(world.recorder != null)
world.recorder.endDuckRecord();
ducking = false;
}
if(world.recorder != null)
world.recorder.recordJumpLand();
}
if (xa > 2)
{
facing = 1;
}
if (xa < -2)
{
facing = -1;
}
if (keys[KEY_JUMP] || (jumpTime < 0 && !onGround && !sliding))
{
if (jumpTime < 0)
{
xa = xJumpSpeed;
ya = -jumpTime * yJumpSpeed;
jumpTime++;
}
else if (onGround && mayJump)
{
world.sound.play(Art.samples[Art.SAMPLE_MARIO_JUMP], this, 1, 1, 1);
xJumpSpeed = 0;
yJumpSpeed = -1.9f;
jumpTime = 7;
ya = jumpTime * yJumpSpeed;
onGround = false;
sliding = false;
if(world.recorder != null){
world.recorder.isInAir = true;
world.recorder.recordJump();
}
}
else if (sliding && mayJump)
{
world.sound.play(Art.samples[Art.SAMPLE_MARIO_JUMP], this, 1, 1, 1);
xJumpSpeed = -facing * 6.0f;
yJumpSpeed = -2.0f;
jumpTime = -6;
xa = xJumpSpeed;
ya = -jumpTime * yJumpSpeed;
onGround = false;
sliding = false;
facing = -facing;
}
else if (jumpTime > 0)
{
xa += xJumpSpeed;
ya = jumpTime * yJumpSpeed;
jumpTime--;
}
}
else
{
jumpTime = 0;
}
if(world.mario.xa > 0){
if(direction != 1){
direction = 1;
if(world.recorder != null){
// world.recorder.switchRecord();
world.recorder.startRightMoveRecord();
}
}
}
else if(world.mario.xa < 0){
if(direction != -1){
direction = -1;
if(world.recorder != null){
// world.recorder.switchRecord();
world.recorder.startLeftMoveRecord();
}
}
}
else{
//was moving right
if(direction == 1 && world.recorder!= null){
world.recorder.endRightMoveRecord();
}
//was moving left
else if(direction == -1 && world.recorder!= null){
world.recorder.endLeftMoveRecord();
}
direction = 0;
}
if (keys[KEY_LEFT] && !ducking)
{
if (facing == 1) sliding = false;
xa -= sideWaysSpeed;
if (jumpTime >= 0) facing = -1;
}
if (keys[KEY_RIGHT] && !ducking)
{
if (facing == -1) sliding = false;
xa += sideWaysSpeed;
if (jumpTime >= 0) facing = 1;
}
if ((!keys[KEY_LEFT] && !keys[KEY_RIGHT]) || ducking || ya < 0 || onGround)
{
sliding = false;
}
if (keys[KEY_SPEED] && canShoot && Mario.fire && world.fireballsOnScreen<2)
{
world.sound.play(Art.samples[Art.SAMPLE_MARIO_FIREBALL], this, 1, 1, 1);
world.addSprite(new Fireball(world, x+facing*6, y-20, facing));
}
canShoot = !keys[KEY_SPEED];
mayJump = (onGround || sliding) && !keys[KEY_JUMP];
xFlipPic = facing == -1;
runTime += (Math.abs(xa)) + 5;
if (Math.abs(xa) < 0.5f)
{
runTime = 0;
xa = 0;
}
calcPic();
if (sliding)
{
for (int i = 0; i < 1; i++)
{
world.addSprite(new Sparkle((int) (x + Math.random() * 4 - 2) + facing * 8, (int) (y + Math.random() * 4) - 24, (float) (Math.random() * 2 - 1), (float) Math.random() * 1, 0, 1, 5));
}
ya *= 0.5f;
}
onGround = false;
move(xa, 0);
move(0, ya);
if (y > world.level.getHeight() * 16 + 16)
{
dieJump();
}
if (x < 0)
{
x = 0;
xa = 0;
}
// if(x > world.level.xExit * 16 && ! world.level.flipped || x < world.level.xExit * 16 && world.level.flipped )
if(x > world.level.getxExit() * 16 )
{
win();
}
if (x > world.level.getWidth() * 16)
{
x = world.level.getWidth() * 16;
xa = 0;
}
ya *= 0.85f;
if (onGround)
{
xa *= GROUND_INERTIA;
}
else
{
xa *= AIR_INERTIA;
}
if (!onGround)
{
ya += 3;
}
if (carried != null)
{
carried.x = x + facing * 8;
carried.y = y - 2;
if (!keys[KEY_SPEED])
{
carried.release(this);
carried = null;
if(world.recorder != null){
world.recorder.shellUnleashedRecord();
}
}
}
}
private void calcPic()
{
int runFrame = 0;
if (large)
{
runFrame = ((int) (runTime / 20)) % 4;
if (runFrame == 3) runFrame = 1;
if (carried == null && Math.abs(xa) > 10) runFrame += 3;
if (carried != null) runFrame += 10;
if (!onGround)
{
if (carried != null) runFrame = 12;
else if (Math.abs(xa) > 10) runFrame = 7;
else runFrame = 6;
}
}
else
{
runFrame = ((int) (runTime / 20)) % 2;
if (carried == null && Math.abs(xa) > 10) runFrame += 2;
if (carried != null) runFrame += 8;
if (!onGround)
{
if (carried != null) runFrame = 9;
else if (Math.abs(xa) > 10) runFrame = 5;
else runFrame = 4;
}
}
if (onGround && ((facing == -1 && xa > 0) || (facing == 1 && xa < 0)))
{
if (xa > 1 || xa < -1) runFrame = large ? 9 : 7;
if (xa > 3 || xa < -3)
{
for (int i = 0; i < 3; i++)
{
world.addSprite(new Sparkle((int) (x + Math.random() * 8 - 4), (int) (y + Math.random() * 4), (float) (Math.random() * 2 - 1), (float) Math.random() * -1, 0, 1, 5));
}
}
}
if (large)
{
if (ducking) runFrame = 14;
height = ducking ? 12 : 24;
}
else
{
height = 12;
}
xPic = runFrame;
}
private boolean move(float xa, float ya)
{
while (xa > 8)
{
if (!move(8, 0)) return false;
xa -= 8;
}
while (xa < -8)
{
if (!move(-8, 0)) return false;
xa += 8;
}
while (ya > 8)
{
if (!move(0, 8)) return false;
ya -= 8;
}
while (ya < -8)
{
if (!move(0, -8)) return false;
ya += 8;
}
boolean collide = false;
if (ya > 0)
{
if (isBlocking(x + xa - width, y + ya, xa, 0)) collide = true;
else if (isBlocking(x + xa + width, y + ya, xa, 0)) collide = true;
else if (isBlocking(x + xa - width, y + ya + 1, xa, ya)) collide = true;
else if (isBlocking(x + xa + width, y + ya + 1, xa, ya)) collide = true;
}
if (ya < 0)
{
if (isBlocking(x + xa, y + ya - height, xa, ya)) collide = true;
else if (collide || isBlocking(x + xa - width, y + ya - height, xa, ya)) collide = true;
else if (collide || isBlocking(x + xa + width, y + ya - height, xa, ya)) collide = true;
}
if (xa > 0)
{
sliding = true;
if (isBlocking(x + xa + width, y + ya - height, xa, ya)) collide = true;
else sliding = false;
if (isBlocking(x + xa + width, y + ya - height / 2, xa, ya)) collide = true;
else sliding = false;
if (isBlocking(x + xa + width, y + ya, xa, ya)) collide = true;
else sliding = false;
}
if (xa < 0)
{
sliding = true;
if (isBlocking(x + xa - width, y + ya - height, xa, ya)) collide = true;
else sliding = false;
if (isBlocking(x + xa - width, y + ya - height / 2, xa, ya)) collide = true;
else sliding = false;
if (isBlocking(x + xa - width, y + ya, xa, ya)) collide = true;
else sliding = false;
}
if (collide)
{
if (xa < 0)
{
x = (int) ((x - width) / 16) * 16 + width;
this.xa = 0;
}
if (xa > 0)
{
x = (int) ((x + width) / 16 + 1) * 16 - width - 1;
this.xa = 0;
}
if (ya < 0)
{
y = (int) ((y - height) / 16) * 16 + height;
jumpTime = 0;
this.ya = 0;
}
if (ya > 0)
{
y = (int) ((y - 1) / 16 + 1) * 16 - 1;
onGround = true;
}
return false;
}
else
{
x += xa;
y += ya;
return true;
}
}
private boolean isBlocking(float _x, float _y, float xa, float ya)
{
//translate into block mode (since blocks are 16x16)
int x = (int) (_x / 16);
int y = (int) (_y / 16);
if (x==(int)(this.x/16) && y==(int)(this.y/16))
return false;
boolean blocking = world.level.isBlocking(x, y, xa, ya);
byte block = world.level.getBlock(x, y);
if (((Level.TILE_BEHAVIORS[block & 0xff]) & Level.BIT_PICKUPABLE) > 0)
{
if(world.recorder != null)
world.recorder.recordCoin();
Mario.getCoin();
world.sound.play(Art.samples[Art.SAMPLE_GET_COIN], new FixedSoundSource(x * 16 + 8, y * 16 + 8), 1, 1, 1);
world.level.setBlock(x, y, (byte) 0);
for (int xx = 0; xx < 2; xx++)
for (int yy = 0; yy < 2; yy++)
world.addSprite(new Sparkle(x * 16 + xx * 8 + (int) (Math.random() * 8), y * 16 + yy * 8 + (int) (Math.random() * 8), 0, 0, 0, 2, 5));
}
if (blocking && ya < 0)
{
world.bump(x, y, large);
}
return blocking;
}
public void stomp(Enemy enemy)
{
if (deathTime > 0 || world.paused) return;
float targetY = enemy.y - enemy.height / 2;
move(0, targetY - y);
world.sound.play(Art.samples[Art.SAMPLE_MARIO_KICK], this, 1, 1, 1);
xJumpSpeed = 0;
yJumpSpeed = -1.9f;
jumpTime = 8;
ya = jumpTime * yJumpSpeed;
onGround = false;
sliding = false;
invulnerableTime = 1;
if(world.recorder!=null)
world.recorder.killStompRecord(enemy);
}
public void stomp(Shell shell)
{
if (deathTime > 0 || world.paused) return;
if (keys[KEY_SPEED] && shell.facing == 0)
{
carried = shell;
shell.carried = true;
}
else
{
float targetY = shell.y - shell.height / 2;
move(0, targetY - y);
world.sound.play(Art.samples[Art.SAMPLE_MARIO_KICK], this, 1, 1, 1);
xJumpSpeed = 0;
yJumpSpeed = -1.9f;
jumpTime = 8;
ya = jumpTime * yJumpSpeed;
onGround = false;
sliding = false;
invulnerableTime = 1;
if(shell.xa == 0 && world.recorder!= null){
world.recorder.shellUnleashedRecord();
}
}
}
public void getHurt(Sprite sprite)
{
if (deathTime > 0 || world.paused) return;
if (invulnerableTime > 0) return;
if (large)
{
world.paused = true;
powerUpTime = -3 * 6;
world.sound.play(Art.samples[Art.SAMPLE_MARIO_POWER_DOWN], this, 1, 1, 1);
if (fire)
{
world.mario.setLarge(true, false);
if(world.recorder != null){
world.recorder.endFireRecord();
world.recorder.startLargeRecord();
}
}
else
{
world.mario.setLarge(false, false);
if(world.recorder != null){
world.recorder.endLargeRecord();
world.recorder.startLittleRecord();
}
}
invulnerableTime = 32;
}
else
{
dieSprite(sprite);
}
}
private void win()
{
xDeathPos = (int) x;
yDeathPos = (int) y;
world.paused = true;
winTime = 1;
Art.stopMusic();
world.sound.play(Art.samples[Art.SAMPLE_LEVEL_EXIT], this, 1, 1, 1);
}
public void dieSprite(Sprite sprite){
die();
if(world.recorder != null){
world.recorder.dieRecord(sprite);
}
}
public void dieTime(){
die();
if(world.recorder!=null){
world.recorder.dieTimeRecord();
}
}
public void dieJump(){
die();
if(world.recorder!=null){
world.recorder.dieJumpRecord();
}
}
public void die()
{
xDeathPos = (int) x;
yDeathPos = (int) y;
world.paused = true;
deathTime = 1;
Art.stopMusic();
world.sound.play(Art.samples[Art.SAMPLE_MARIO_DEATH], this, 1, 1, 1);
if(world.recorder != null){
if(running)
world.recorder.endRunningRecord();
if(large && !fire){
world.recorder.endLargeRecord();
}
if(fire){
world.recorder.endFireRecord();
}
if(!large && !fire)
world.recorder.endLittleRecord();
if(ducking)
world.recorder.endDuckRecord();
world.recorder.endTime();
world.recorder.recordJumpLand();
}
large = false;
fire = false;
}
public void getFlower()
{
if (deathTime > 0 || world.paused) return;
if (!fire)
{
world.paused = true;
powerUpTime = 3 * 6;
world.sound.play(Art.samples[Art.SAMPLE_MARIO_POWER_UP], this, 1, 1, 1);
world.mario.setLarge(true, true);
if(world.recorder != null){
if(large){
world.recorder.endLargeRecord();
}
else{
world.recorder.endLittleRecord();
}
world.recorder.startFireRecord();
}
}
else
{
Mario.getCoin();
world.sound.play(Art.samples[Art.SAMPLE_GET_COIN], this, 1, 1, 1);
}
}
public void getMushroom()
{
if (deathTime > 0 || world.paused) return;
if (!large)
{
world.paused = true;
powerUpTime = 3 * 6;
world.sound.play(Art.samples[Art.SAMPLE_MARIO_POWER_UP], this, 1, 1, 1);
world.mario.setLarge(true, false);
if(world.recorder != null){
world.recorder.endLittleRecord();
world.recorder.startLargeRecord();
}
}
else
{
Mario.getCoin();
world.sound.play(Art.samples[Art.SAMPLE_GET_COIN], this, 1, 1, 1);
}
}
public void kick(Shell shell)
{
if (deathTime > 0 || world.paused) return;
if (keys[KEY_SPEED])
{
carried = shell;
shell.carried = true;
}
else
{
world.sound.play(Art.samples[Art.SAMPLE_MARIO_KICK], this, 1, 1, 1);
invulnerableTime = 1;
if(world.recorder!=null)
world.recorder.shellUnleashedRecord();
}
}
public void stomp(BulletBill bill)
{
if (deathTime > 0 || world.paused) return;
float targetY = bill.y - bill.height / 2;
move(0, targetY - y);
world.sound.play(Art.samples[Art.SAMPLE_MARIO_KICK], this, 1, 1, 1);
xJumpSpeed = 0;
yJumpSpeed = -1.9f;
jumpTime = 8;
ya = jumpTime * yJumpSpeed;
onGround = false;
sliding = false;
invulnerableTime = 1;
if(world.recorder!=null)
world.recorder.killStompRecord(bill);
}
public byte getKeyMask()
{
int mask = 0;
for (int i = 0; i < 7; i++)
{
if (keys[i]) mask |= (1 << i);
}
return (byte) mask;
}
public void setKeys(byte mask)
{
for (int i = 0; i < 7; i++)
{
keys[i] = (mask & (1 << i)) > 0;
}
}
public static void get1Up()
{
instance.world.sound.play(Art.samples[Art.SAMPLE_MARIO_1UP], instance, 1, 1, 1);
lives++;
if (lives==99)
{
lives = 99;
}
}
public static void getCoin()
{
coins++;
if (coins==100)
{
coins = 0;
get1Up();
}
}
}

View File

@@ -0,0 +1,223 @@
package dk.itu.mario.engine.sprites;
import dk.itu.mario.engine.Art;
import dk.itu.mario.scene.LevelScene;
public class Mushroom extends Sprite
{
private static float GROUND_INERTIA = 0.89f;
private static float AIR_INERTIA = 0.89f;
private float runTime;
private boolean onGround = false;
private boolean mayJump = false;
private int jumpTime = 0;
private float xJumpSpeed;
private float yJumpSpeed;
private int width = 4;
int height = 24;
private LevelScene world;
public int facing;
public boolean avoidCliffs = false;
private int life;
public Mushroom(LevelScene world, int x, int y)
{
sheet = Art.items;
this.x = x;
this.y = y;
this.world = world;
xPicO = 8;
yPicO = 15;
yPic = 0;
height = 12;
facing = 1;
wPic = hPic = 16;
life = 0;
}
public void collideCheck()
{
float xMarioD = world.mario.x - x;
float yMarioD = world.mario.y - y;
float w = 16;
if (xMarioD > -16 && xMarioD < 16)
{
if (yMarioD > -height && yMarioD < world.mario.height)
{
world.mario.getMushroom();
spriteContext.removeSprite(this);
}
}
}
public void move()
{
if (life<9)
{
layer = 0;
y--;
life++;
return;
}
float sideWaysSpeed = 1.75f;
layer = 1;
// float sideWaysSpeed = onGround ? 2.5f : 1.2f;
if (xa > 2)
{
facing = 1;
}
if (xa < -2)
{
facing = -1;
}
xa = facing * sideWaysSpeed;
mayJump = (onGround);
xFlipPic = facing == -1;
runTime += (Math.abs(xa)) + 5;
if (!move(xa, 0)) facing = -facing;
onGround = false;
move(0, ya);
ya *= 0.85f;
if (onGround)
{
xa *= GROUND_INERTIA;
}
else
{
xa *= AIR_INERTIA;
}
if (!onGround)
{
ya += 2;
}
}
private boolean move(float xa, float ya)
{
while (xa > 8)
{
if (!move(8, 0)) return false;
xa -= 8;
}
while (xa < -8)
{
if (!move(-8, 0)) return false;
xa += 8;
}
while (ya > 8)
{
if (!move(0, 8)) return false;
ya -= 8;
}
while (ya < -8)
{
if (!move(0, -8)) return false;
ya += 8;
}
boolean collide = false;
if (ya > 0)
{
if (isBlocking(x + xa - width, y + ya, xa, 0)) collide = true;
else if (isBlocking(x + xa + width, y + ya, xa, 0)) collide = true;
else if (isBlocking(x + xa - width, y + ya + 1, xa, ya)) collide = true;
else if (isBlocking(x + xa + width, y + ya + 1, xa, ya)) collide = true;
}
if (ya < 0)
{
if (isBlocking(x + xa, y + ya - height, xa, ya)) collide = true;
else if (collide || isBlocking(x + xa - width, y + ya - height, xa, ya)) collide = true;
else if (collide || isBlocking(x + xa + width, y + ya - height, xa, ya)) collide = true;
}
if (xa > 0)
{
if (isBlocking(x + xa + width, y + ya - height, xa, ya)) collide = true;
if (isBlocking(x + xa + width, y + ya - height / 2, xa, ya)) collide = true;
if (isBlocking(x + xa + width, y + ya, xa, ya)) collide = true;
if (avoidCliffs && onGround && !world.level.isBlocking((int) ((x + xa + width) / 16), (int) ((y) / 16 + 1), xa, 1)) collide = true;
}
if (xa < 0)
{
if (isBlocking(x + xa - width, y + ya - height, xa, ya)) collide = true;
if (isBlocking(x + xa - width, y + ya - height / 2, xa, ya)) collide = true;
if (isBlocking(x + xa - width, y + ya, xa, ya)) collide = true;
if (avoidCliffs && onGround && !world.level.isBlocking((int) ((x + xa - width) / 16), (int) ((y) / 16 + 1), xa, 1)) collide = true;
}
if (collide)
{
if (xa < 0)
{
x = (int) ((x - width) / 16) * 16 + width;
this.xa = 0;
}
if (xa > 0)
{
x = (int) ((x + width) / 16 + 1) * 16 - width - 1;
this.xa = 0;
}
if (ya < 0)
{
y = (int) ((y - height) / 16) * 16 + height;
jumpTime = 0;
this.ya = 0;
}
if (ya > 0)
{
y = (int) (y / 16 + 1) * 16 - 1;
onGround = true;
}
return false;
}
else
{
x += xa;
y += ya;
return true;
}
}
private boolean isBlocking(float _x, float _y, float xa, float ya)
{
int x = (int) (_x / 16);
int y = (int) (_y / 16);
if (x == (int) (this.x / 16) && y == (int) (this.y / 16)) return false;
boolean blocking = world.level.isBlocking(x, y, xa, ya);
byte block = world.level.getBlock(x, y);
return blocking;
}
public void bumpCheck(int xTile, int yTile)
{
if (x + width > xTile * 16 && x - width < xTile * 16 + 16 && yTile==(int)((y-1)/16))
{
facing = -world.mario.facing;
ya = -10;
}
}
}

View File

@@ -0,0 +1,40 @@
package dk.itu.mario.engine.sprites;
import dk.itu.mario.engine.Art;
public class Particle extends Sprite
{
public int life;
public Particle(int x, int y, float xa, float ya)
{
this(x, y, xa, ya, (int)(Math.random()*2), 0);
}
public Particle(int x, int y, float xa, float ya, int xPic, int yPic)
{
sheet = Art.particles;
this.x = x;
this.y = y;
this.xa = xa;
this.ya = ya;
this.xPic = xPic;
this.yPic = yPic;
this.xPicO = 4;
this.yPicO = 4;
wPic = 8;
hPic = 8;
life = 10;
}
public void move()
{
if (life--<0) Sprite.spriteContext.removeSprite(this);
x+=xa;
y+=ya;
ya*=0.95f;
ya+=3;
}
}

View File

@@ -0,0 +1,370 @@
package dk.itu.mario.engine.sprites;
import dk.itu.mario.engine.Art;
import dk.itu.mario.scene.LevelScene;
public class Shell extends Sprite
{
private static float GROUND_INERTIA = 0.89f;
private static float AIR_INERTIA = 0.89f;
private float runTime;
private boolean onGround = false;
private int width = 4;
int height = 24;
private LevelScene world;
public int facing;
public boolean avoidCliffs = false;
public int anim;
public boolean dead = false;
private int deadTime = 0;
public boolean carried;
public Shell(LevelScene world, float x, float y, int type)
{
sheet = Art.enemies;
this.x = x;
this.y = y;
this.world = world;
xPicO = 8;
yPicO = 31;
yPic = type;
height = 12;
facing = 0;
wPic = 16;
xPic = 4;
ya = -5;
}
public boolean fireballCollideCheck(Fireball fireball)
{
if (deadTime != 0) return false;
float xD = fireball.x - x;
float yD = fireball.y - y;
if (xD > -16 && xD < 16)
{
if (yD > -height && yD < fireball.height)
{
if (facing!=0) return true;
world.sound.play(Art.samples[Art.SAMPLE_MARIO_KICK], this, 1, 1, 1);
xa = fireball.facing * 2;
ya = -5;
if (spriteTemplate != null) spriteTemplate.isDead = true;
deadTime = 100;
hPic = -hPic;
yPicO = -yPicO + 16;
return true;
}
}
return false;
}
public void collideCheck()
{
if (carried || dead || deadTime>0) return;
float xMarioD = world.mario.x - x;
float yMarioD = world.mario.y - y;
float w = 16;
if (xMarioD > -16 && xMarioD < 16)
{
if (yMarioD > -height && yMarioD < world.mario.height)
{
if (world.mario.ya > 0 && yMarioD <= 0 && (!world.mario.onGround || !world.mario.wasOnGround))
{
world.mario.stomp(this);
if (facing != 0)
{
xa = 0;
facing = 0;
}
else
{
facing = world.mario.facing;
}
}
else
{
if (facing != 0)
{
world.mario.getHurt(this);
}
else
{
world.mario.kick(this);
facing = world.mario.facing;
}
}
}
}
}
public void move()
{
if (y > world.level.getHeight() * 16 + 16 && deadTime == 0)
{
die();
spriteContext.removeSprite(this);
return;
}
if (carried)
{
world.checkShellCollide(this);
return;
}
if (deadTime > 0)
{
deadTime--;
if (deadTime == 0)
{
deadTime = 1;
for (int i = 0; i < 8; i++)
{
world.addSprite(new Sparkle((int) (x + Math.random() * 16 - 8) + 4, (int) (y - Math.random() * 8) + 4, (float) (Math.random() * 2 - 1), (float) Math.random() * -1, 0, 1, 5));
}
spriteContext.removeSprite(this);
}
x += xa;
y += ya;
ya *= 0.95;
ya += 1;
return;
}
if (facing != 0) anim++;
float sideWaysSpeed = 11f;
// float sideWaysSpeed = onGround ? 2.5f : 1.2f;
if (xa > 2)
{
facing = 1;
}
if (xa < -2)
{
facing = -1;
}
xa = facing * sideWaysSpeed;
if (facing != 0)
{
world.checkShellCollide(this);
}
xFlipPic = facing == -1;
runTime += (Math.abs(xa)) + 5;
xPic = (anim / 2) % 4 + 3;
if (!move(xa, 0))
{
world.sound.play(Art.samples[Art.SAMPLE_SHELL_BUMP], this, 1, 1, 1);
facing = -facing;
}
onGround = false;
move(0, ya);
ya *= 0.85f;
if (onGround)
{
xa *= GROUND_INERTIA;
}
else
{
xa *= AIR_INERTIA;
}
if (!onGround)
{
ya += 2;
}
}
private boolean move(float xa, float ya)
{
while (xa > 8)
{
if (!move(8, 0)) return false;
xa -= 8;
}
while (xa < -8)
{
if (!move(-8, 0)) return false;
xa += 8;
}
while (ya > 8)
{
if (!move(0, 8)) return false;
ya -= 8;
}
while (ya < -8)
{
if (!move(0, -8)) return false;
ya += 8;
}
boolean collide = false;
if (ya > 0)
{
if (isBlocking(x + xa - width, y + ya, xa, 0)) collide = true;
else if (isBlocking(x + xa + width, y + ya, xa, 0)) collide = true;
else if (isBlocking(x + xa - width, y + ya + 1, xa, ya)) collide = true;
else if (isBlocking(x + xa + width, y + ya + 1, xa, ya)) collide = true;
}
if (ya < 0)
{
if (isBlocking(x + xa, y + ya - height, xa, ya)) collide = true;
else if (collide || isBlocking(x + xa - width, y + ya - height, xa, ya)) collide = true;
else if (collide || isBlocking(x + xa + width, y + ya - height, xa, ya)) collide = true;
}
if (xa > 0)
{
if (isBlocking(x + xa + width, y + ya - height, xa, ya)) collide = true;
if (isBlocking(x + xa + width, y + ya - height / 2, xa, ya)) collide = true;
if (isBlocking(x + xa + width, y + ya, xa, ya)) collide = true;
if (avoidCliffs && onGround && !world.level.isBlocking((int) ((x + xa + width) / 16), (int) ((y) / 16 + 1), xa, 1)) collide = true;
}
if (xa < 0)
{
if (isBlocking(x + xa - width, y + ya - height, xa, ya)) collide = true;
if (isBlocking(x + xa - width, y + ya - height / 2, xa, ya)) collide = true;
if (isBlocking(x + xa - width, y + ya, xa, ya)) collide = true;
if (avoidCliffs && onGround && !world.level.isBlocking((int) ((x + xa - width) / 16), (int) ((y) / 16 + 1), xa, 1)) collide = true;
}
if (collide)
{
if (xa < 0)
{
x = (int) ((x - width) / 16) * 16 + width;
this.xa = 0;
}
if (xa > 0)
{
x = (int) ((x + width) / 16 + 1) * 16 - width - 1;
this.xa = 0;
}
if (ya < 0)
{
y = (int) ((y - height) / 16) * 16 + height;
this.ya = 0;
}
if (ya > 0)
{
y = (int) (y / 16 + 1) * 16 - 1;
onGround = true;
}
return false;
}
else
{
x += xa;
y += ya;
return true;
}
}
private boolean isBlocking(float _x, float _y, float xa, float ya)
{
int x = (int) (_x / 16);
int y = (int) (_y / 16);
if (x == (int) (this.x / 16) && y == (int) (this.y / 16)) return false;
boolean blocking = world.level.isBlocking(x, y, xa, ya);
byte block = world.level.getBlock(x, y);
if (blocking && ya == 0 && xa!=0)
{
world.bump(x, y, true);
}
return blocking;
}
public void bumpCheck(int xTile, int yTile)
{
if (x + width > xTile * 16 && x - width < xTile * 16 + 16 && yTile == (int) ((y - 1) / 16))
{
facing = -world.mario.facing;
ya = -10;
}
}
public void die()
{
dead = true;
carried = false;
xa = -facing * 2;
ya = -5;
deadTime = 100;
if(world.recorder != null)
world.recorder.killRecord(this);
}
public boolean shellCollideCheck(Shell shell)
{
if (deadTime != 0) return false;
float xD = shell.x - x;
float yD = shell.y - y;
if (xD > -16 && xD < 16)
{
if (yD > -height && yD < shell.height)
{
world.sound.play(Art.samples[Art.SAMPLE_MARIO_KICK], this, 1, 1, 1);
if (world.mario.carried == shell || world.mario.carried == this)
{
world.mario.carried = null;
}
die();
shell.die();
return true;
}
}
return false;
}
public void release(Mario mario)
{
carried = false;
facing = mario.facing;
x += facing * 8;
}
}

View File

@@ -0,0 +1,46 @@
package dk.itu.mario.engine.sprites;
import dk.itu.mario.engine.Art;
public class Sparkle extends Sprite
{
public int life;
public int xPicStart;
public Sparkle(int x, int y, float xa, float ya)
{
this(x, y, xa, ya, (int)(Math.random()*2), 0, 5);
}
public Sparkle(int x, int y, float xa, float ya, int xPic, int yPic, int timeSpan)
{
sheet = Art.particles;
this.x = x;
this.y = y;
this.xa = xa;
this.ya = ya;
this.xPic = xPic;
xPicStart = xPic;
this.yPic = yPic;
this.xPicO = 4;
this.yPicO = 4;
wPic = 8;
hPic = 8;
life = 10+(int)(Math.random()*timeSpan);
}
public void move()
{
if (life>10)
xPic = 7;
else
xPic = xPicStart+(10-life)*4/10;
if (life--<0) Sprite.spriteContext.removeSprite(this);
x+=xa;
y+=ya;
}
}

View File

@@ -0,0 +1,117 @@
package dk.itu.mario.engine.sprites;
import java.awt.Graphics;
import java.awt.Image;
import dk.itu.mario.engine.sonar.SoundSource;
public class Sprite implements SoundSource
{
public static SpriteContext spriteContext;
public float xOld, yOld, x, y, xa, ya;
public int xPic, yPic;
public int wPic = 32;
public int hPic = 32;
public int xPicO, yPicO;
public boolean xFlipPic = false;
public boolean yFlipPic = false;
public Image[][] sheet;
public boolean visible = true;
public int layer = 1;
public SpriteTemplate spriteTemplate;
public void move()
{
x+=xa;
y+=ya;
}
public void render(Graphics og, float alpha)
{
if (!visible) return;
int xPixel = (int)(xOld+(x-xOld)*alpha)-xPicO;
int yPixel = (int)(yOld+(y-yOld)*alpha)-yPicO;
og.drawImage(sheet[xPic][yPic], xPixel+(xFlipPic?wPic:0), yPixel+(yFlipPic?hPic:0), xFlipPic?-wPic:wPic, yFlipPic?-hPic:hPic, null);
}
/* private void blit(Graphics og, Image bitmap, int x0, int y0, int x1, int y1, int w, int h)
{
if (!xFlipPic)
{
if (!yFlipPic)
{
og.drawImage(bitmap, x0, y0, x0+w, y0+h, x1, y1, x1+w, y1+h, null);
}
else
{
og.drawImage(bitmap, x0, y0, x0+w, y0+h, x1, y1+h, x1+w, y1, null);
}
}
else
{
if (!yFlipPic)
{
og.drawImage(bitmap, x0, y0, x0+w, y0+h, x1+w, y1, x1, y1+h, null);
}
else
{
og.drawImage(bitmap, x0, y0, x0+w, y0+h, x1+w, y1+h, x1, y1, null);
}
}
}*/
public final void tick()
{
xOld = x;
yOld = y;
move();
}
public final void tickNoMove()
{
xOld = x;
yOld = y;
}
public float getX(float alpha)
{
return (xOld+(x-xOld)*alpha)-xPicO;
}
public float getY(float alpha)
{
return (yOld+(y-yOld)*alpha)-yPicO;
}
public void collideCheck()
{
}
public void bumpCheck(int xTile, int yTile)
{
}
public boolean shellCollideCheck(Shell shell)
{
return false;
}
public void release(Mario mario)
{
}
public boolean fireballCollideCheck(Fireball fireball)
{
return false;
}
}

View File

@@ -0,0 +1,18 @@
package dk.itu.mario.engine.sprites;
/**
* <p>Title: </p>
*
* <p>Description: </p>
*
* <p>Copyright: Copyright (c) 2010</p>
*
* <p>Company: </p>
*
* @author not attributable
* @version 1.0
*/
public interface SpriteContext {
public void addSprite(Sprite sprite);
public void removeSprite(Sprite sprite);
}

View File

@@ -0,0 +1,60 @@
package dk.itu.mario.engine.sprites;
import dk.itu.mario.scene.LevelScene;
public class SpriteTemplate
{
public static final int RED_TURTLE = 0;
public static final int GREEN_TURTLE = 1;
public static final int GOOMPA = 2;
public static final int ARMORED_TURTLE = 3;
public static final int JUMP_FLOWER = 4;
public static final int CANNON_BALL = 5;
public static final int CHOMP_FLOWER = 6;
public static int enemiesSpawned = 0;
public static int enemiesMax = 1000;
public boolean hasSpawned = false;
public int lastVisibleTick = -1;
public Sprite sprite;
public boolean isDead = false;
private boolean winged;
public int type;
public int direction = 1;
public SpriteTemplate(int type, boolean winged)
{
this.type = type;
this.winged = winged;
}
public void spawn(LevelScene world, int x, int y, int dir)
{
if (isDead || enemiesSpawned >= enemiesMax) return;
if (type==Enemy.ENEMY_FLOWER)
{
sprite = new FlowerEnemy(world, x*16+15, y*16+24);
}
else
{
sprite = new Enemy(world, x*16+8, y*16+15, dir, type, winged);
}
//correct for flipping
if(direction == -1){
sprite.x -= 14;
}
sprite.spriteTemplate = this;
world.addSprite(sprite);
if(!hasSpawned)
enemiesSpawned++;
hasSpawned = true;
}
}