package it.marteEngine.game.starcleaner; import it.marteEngine.ResourceManager; import it.marteEngine.entity.Entity; import it.marteEngine.entity.PhysicsEntity; import org.newdawn.slick.GameContainer; import org.newdawn.slick.Input; import org.newdawn.slick.SlickException; import org.newdawn.slick.Sound; import org.newdawn.slick.geom.Vector2f; /** * this class only works with a fixed frame rate of 60. All calculations are * based on that assumption. It's okay for this little sample game * * @author Thomas * */ public class Angel extends PhysicsEntity { public static final String ANGEL = "angel"; // constants for the commands public static final String CMD_LEFT = "left"; public static final String CMD_RIGHT = "right"; public static final String CMD_JUMP = "jump"; public int moveSpeed = 1; public int jumpSpeed = 8; public boolean faceRight = true; public boolean onGround = false; // did we jump or just fell off some solid? public boolean didJump = false; // are we walljumping? (0 = no, 1 = left, 2 = right) public int wallJumping = 0; // can we double jump? (false = no, true = yes) public boolean doubleJump = false; public boolean dead = false; private Light myLight = null; public static String[] enemies = { Spikes.SPIKES, Crow.CROW }; private Sound jumpSnd, hitSnd, pickupstarSnd, allPickedUpSnd; private int frame = 0; private int frameTimer = 0; private int frameInterval = 100; // switch frame every 100 ms if walking public Angel(float x, float y, Light light) { super(x, y); depth = 10; this.name = ANGEL; this.addType(Entity.PLAYER); sheet = ResourceManager.getSpriteSheet(ANGEL); currentImage = sheet.getSprite(0, 0); myLight = light; width = 40; height = 40; // set different speeds and such gravity = 0.4f; maxSpeed = new Vector2f(4, 8); Globals.originalPlayerMaxSpeed = new Vector2f(maxSpeed); friction = new Vector2f(0.5f, 0.5f); // set hitbox setHitBox(6, 2, 24, 38); defineCommands(); // set sounds // bumpSnd = ResourceManager.getSound("bump"); jumpSnd = ResourceManager.getSound("jump"); hitSnd = ResourceManager.getSound("hit"); pickupstarSnd = ResourceManager.getSound("pickupstar"); allPickedUpSnd = ResourceManager.getSound("allpickedup"); } private void defineCommands() { define(CMD_JUMP, Input.KEY_X, Input.KEY_W, Input.KEY_UP); define(CMD_LEFT, Input.KEY_LEFT, Input.KEY_A); define(CMD_RIGHT, Input.KEY_RIGHT, Input.KEY_D); } public void update(GameContainer container, int delta) throws SlickException { // are we on the ground? onGround = false; if (collide(SOLID, x, y + 1) != null) { onGround = true; wallJumping = 0; doubleJump = true; didJump = false; } // set acceleration to nothing acceleration.x = 0; // increase acceeration, if we're not going too fast if (check(CMD_LEFT) && speed.x > -maxSpeed.x) { acceleration.x = -moveSpeed; faceRight = false; } if (check(CMD_RIGHT) && speed.x < maxSpeed.x) { acceleration.x = moveSpeed; faceRight = true; } // friction (apply if we're not moving, or if our speed.x is larger than // maxspeed) if ((!check(CMD_LEFT) && !check(CMD_RIGHT)) || Math.abs(speed.x) > maxSpeed.x) { friction(true, false); } // jump if (pressed(CMD_JUMP)) { boolean jumped = false; // normal jump if (onGround) { speed.y = -jumpSpeed; jumped = true; didJump = true; jumpSnd.play(); } // wall jump if ((collide(SOLID, x - 1, y) != null) && !jumped && wallJumping != 3) { speed.y = -jumpSpeed; // jump up speed.x = maxSpeed.x * 2; // move right fast wallJumping = 2; // and set wall jump direction jumped = true; // so we don't "use up" or double jump jumpSnd.play(); } // same as above if ((collide(SOLID, x + 1, y) != null) && !jumped && wallJumping != 3) { speed.y = -jumpSpeed; speed.x = -maxSpeed.x * 2; wallJumping = 1; jumped = true; jumpSnd.play(); } // set double jump to false if (!onGround && !jumped && didJump && doubleJump) { speed.y = -jumpSpeed; doubleJump = false; // set walljumping to 0 so we can move back in any direction // again // incase we were wall jumping prior to this double jump. // if you don't want to allow walljumping after a double jump, // set this to 3. wallJumping = 0; } } // if we ARE walljumping, make sure we can't go back if (wallJumping > 0) { if (wallJumping == 2 && speed.x < 0) { speed.x = 0; } if (wallJumping == 1 && speed.x > 0) { speed.x = 0; } } // set the gravity gravity(delta); // make sure we're not going too fast vertically // the reason we don't stop the player from moving too fast left/right // is because // that would (partially) destroy the walljumping. Instead, we just make // sure the player, // using the arrow keys, can't go faster than the max speed, and if we // are going faster // than the max speed, descrease it with friction slowly. maxspeed(false, true); // variable jumping (tripple gravity) if (speed.y < 0 && !check(CMD_JUMP)) { gravity(delta); gravity(delta); } // set the sprites according to if we're on the ground, and if we are // moving or not if (onGround) { if (speed.x != 0) { // update frametimer frameTimer -= delta; while (frameTimer < 0) { frame++; frameTimer += frameInterval; if (frame > 1) // just two frames for angel's walk animation frame = 0; } } if (speed.x < 0) { currentImage = sheet.getSprite(frame, 0).getFlippedCopy(true, false); // sprPlayer.play("walkLeft"); } if (speed.x > 0) { currentImage = sheet.getSprite(frame, 0); // sprPlayer.play("walkRight"); } if (speed.x == 0) { if (faceRight) currentImage = sheet.getSprite(0, 0); else currentImage = sheet.getSprite(0, 0).getFlippedCopy(true, false); // if (direction) { sprPlayer.play("standRight"); } else { // sprPlayer.play("standLeft"); } } } else { if (faceRight) currentImage = sheet.getSprite(2, 0); else currentImage = sheet.getSprite(2, 0) .getFlippedCopy(true, false); // if (direction) { sprPlayer.play("jumpRight"); } else { // sprPlayer.play("jumpLeft"); } // are we sliding on a wall? // if (collide(solid, x - 1, y)) { sprPlayer.play("slideRight"); } // if (collide(solid, x + 1, y)) { sprPlayer.play("slideLeft"); } } // set the motion. We set this later so it stops all movement if we // should be stopped motion(true, true); // update our light to our position if (previousx != x || previousy != y) myLight.setLocation(x + StarCleaner.TILESIZE / 2, y + StarCleaner.TILESIZE / 2); // did we collect a star? Entity star = collide(Star.STAR_TYPE, x, y); if (star != null) pickupstarSnd.play(); Entity sunOrMoon = collide(Sun.SUN_AND_MOON, x, y); // did we collide with a spike or a crow? if (collide(enemies, x, y) != null) { hitSnd.play(); Globals.playerDead = true; } if (sunOrMoon != null && this.world.getNrOfEntities(Star.STAR_TYPE) == 0) { Globals.levelDone = true; if (!allPickedUpSnd.playing()) allPickedUpSnd.play(); } previousx = x; previousy = y; } public void leftWorldBoundaries() { // the player unfortunately left the screen - so we retry Globals.playerDead = true; } public void animEnd() { } }