import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) /** * A spaceship controlled by the player -- white or black. * * @author Jannis Andrija Schnitzer, Martin Schend * @version 2011-01-21 */ public class ManuallyControlledSpaceship extends Spaceship { public static final int BASE_HP = 1000; /** * How many hitpoints a collision with another spaceship should cost. */ public static final int COLLISION = 100; /** * How many pixels the spaceship should move per turn when a movement key is pressed. */ public static final int MOVEMENT = 10; /** * If the spaceship should automatically fire whenever possible. */ protected boolean autofire; /** * Should the player be allowed to move the spaceship up and down? */ protected boolean mayMoveUpAndDown; protected class Keys { public String left = ""; public String right = ""; public String up = ""; public String down = ""; public String shoot = ""; } /** * Contains strings with the keys for all possible actions. * * @see Keys * @see #act() */ protected Keys keys; public ManuallyControlledSpaceship(int the_level) { super(the_level); /* Don't be destroyed when we hit the border. Right now, this is actually just protection from coding * errors. But who knows what the future brings? */ disappear = false; hitpoints = max_hitpoints = level * BASE_HP; setupImages(); setBlinkFile("ShipHit.png"); setMaxBlink(5); setupKeys(); autofire = false; } protected void setupImages() { if (side == InvadersWorld.WHITE) this.setImage("WhiteShip.png"); else this.setImage("BlackShip.png"); } /** * Set keys according to the side we're on. */ protected void setupKeys() { keys = new Keys(); if (side == InvadersWorld.WHITE) { keys.left = "left"; keys.right = "right"; keys.up = "up"; keys.down = "down"; keys.shoot = "space"; } else if (side == InvadersWorld.BLACK) { keys.left = "a"; keys.right = "d"; keys.up = "w"; keys.down = "s"; keys.shoot = "x"; } } public void setSide(int the_side) { side = the_side; setupImages(); setupKeys(); } public int getSide() { return side; } public void setMayMoveUpAndDown(boolean may) { mayMoveUpAndDown = may; } public boolean getMayMoveUpAndDown() { return mayMoveUpAndDown; } /** * Do quantum object duties, then check what the player wants the spaceship to do. */ public void act() { super.act(); if (Greenfoot.isKeyDown(keys.left)) moveLeft(); else if (Greenfoot.isKeyDown(keys.right)) moveRight(); if (Greenfoot.isKeyDown(keys.up)) moveUp(); else if (Greenfoot.isKeyDown(keys.down)) moveDown(); if (autofire || Greenfoot.isKeyDown(keys.shoot)) fire(); } public void moveLeft() { setLocation(getX()-MOVEMENT, getY()); } public void moveRight() { setLocation(getX()+MOVEMENT, getY()); } public void moveUp() { if (!mayMoveUpAndDown) return; setLocation(getX(), getY()-MOVEMENT); // I hate that weird coordinate system } public void moveDown() { if (!mayMoveUpAndDown) return; setLocation(getX(), getY()+MOVEMENT); } /** * Update the health bar in InvadersWorld. * * @see InvadersWorld#setHealthBar(int side, int value) */ public void updateHealth() { InvadersWorld myWorld = (InvadersWorld) getWorld(); myWorld.setHealthBar(side, hitpoints); } public void addHitpoints(int n_hitpoints) { super.addHitpoints(n_hitpoints); updateHealth(); } public void removeHitpoints(int n_hitpoints) { super.removeHitpoints(n_hitpoints); updateHealth(); } public void setHitpoints(int n_hitpoints) { super.setHitpoints(n_hitpoints); updateHealth(); } /** * Before destruction: tell world to announce the winner (which is the other side, if this is destroyed). */ public void beforeDestruction() { int winner; InvadersWorld world = (InvadersWorld) getWorld(); if (side == InvadersWorld.WHITE) winner = InvadersWorld.BLACK; else if (side == InvadersWorld.BLACK) winner = InvadersWorld.WHITE; else winner = -1; world.gameOverNextTurn(winner); } public boolean hit(AIControlledSpaceship s) { if (s.getSide() != side) // not one of our ships removeHitpoints(COLLISION); return true; } }