diff --git a/res/images/enemies.png b/res/images/enemies.png new file mode 100644 index 0000000..787432d Binary files /dev/null and b/res/images/enemies.png differ diff --git a/res/images/wastelandbackground.png b/res/images/wastelandbackground.png new file mode 100644 index 0000000..07d6a2b Binary files /dev/null and b/res/images/wastelandbackground.png differ diff --git a/src/de/teamteamteam/spacescooter/entity/Animation.java b/src/de/teamteamteam/spacescooter/entity/Animation.java new file mode 100644 index 0000000..a412d76 --- /dev/null +++ b/src/de/teamteamteam/spacescooter/entity/Animation.java @@ -0,0 +1,69 @@ +package de.teamteamteam.spacescooter.entity; + +/** + * A very simple image slideshow animation. + * Given a list of images and an interval, it does a (fast) slideshow + * through all the images, changing them after ticks. + */ +public class Animation extends Entity { + + /** + * The list of images to display + */ + private String[] images; + + /** + * Internal counter to check whether the interval is over. + */ + private int counter; + + /** + * Interval parameter - change the image after each interval. + */ + private int interval; + + /** + * Index of the current image that is displayed. + */ + private int currentImage; + + + /** + * Default constructor. + */ + public Animation(int x, int y) { + super(x, y); + } + + + /** + * Set the list of images to display plus the interval. + */ + public void configure(String[] images, int interval) { + this.images = images; + this.interval = interval; + this.counter = 0; + this.currentImage = 0; + this.setImage(this.images[this.currentImage]); + } + + /** + * Increase the counter every tick, then check whether the interval is over. + * If the interval is over, check whether there are more images to display. + * If there is one, display the next image, else it is just over and the + * Animation removes itself. + */ + public void update() { + this.counter++; + if(this.counter % this.interval == 0) { + this.currentImage++; + if(this.currentImage == this.images.length) { + this.remove(); + } else { + this.setImage(this.images[this.currentImage]); + } + } + } + + +} diff --git a/src/de/teamteamteam/spacescooter/entity/LivingEntity.java b/src/de/teamteamteam/spacescooter/entity/LivingEntity.java index 9aed34f..b760257 100644 --- a/src/de/teamteamteam/spacescooter/entity/LivingEntity.java +++ b/src/de/teamteamteam/spacescooter/entity/LivingEntity.java @@ -4,10 +4,10 @@ import java.awt.Rectangle; import de.teamteamteam.spacescooter.datastructure.Score; import de.teamteamteam.spacescooter.entity.enemy.Enemy; -import de.teamteamteam.spacescooter.entity.explosion.Explosion; import de.teamteamteam.spacescooter.entity.shot.Shot; import de.teamteamteam.spacescooter.entity.spi.Collidable; import de.teamteamteam.spacescooter.entity.spi.Hittable; +import de.teamteamteam.spacescooter.gui.Credits; import de.teamteamteam.spacescooter.utility.GameConfig; /** @@ -65,6 +65,8 @@ public abstract class LivingEntity extends Entity implements Collidable, Hittabl public void collideWith(Collidable entity) { if(entity instanceof Shot) { Shot s = (Shot) entity; + if(this instanceof Enemy && s.getDirection() == Shot.LEFT) return; + if(this instanceof Player && s.getDirection() == Shot.RIGHT) return; this.takeDamage(s.getDamageValue()); } if(entity instanceof Player && (!(this instanceof Player))) { @@ -113,6 +115,9 @@ public abstract class LivingEntity extends Entity implements Collidable, Hittabl this.healthPoints = 0; this.shieldPoints = 0; Score.addScore(ScorePoints); + if(this instanceof Enemy){ // Add 1 credit for the shop + Credits.setCredits(Credits.getCredits() + 1); + } if(GameConfig.DEBUG) System.out.println(this + " ist gestorben. RIP"); this.die(); } @@ -122,9 +127,7 @@ public abstract class LivingEntity extends Entity implements Collidable, Hittabl * The default way the LivingEntity explodes. * Override this method for a different explosion behaviour. */ - public void explode() { - new Explosion(this.getX(), this.getY()); - } + public void explode() {} /** * The default way the LivingEntity dies. diff --git a/src/de/teamteamteam/spacescooter/entity/Player.java b/src/de/teamteamteam/spacescooter/entity/Player.java index e2e6bb0..f77c72c 100644 --- a/src/de/teamteamteam/spacescooter/entity/Player.java +++ b/src/de/teamteamteam/spacescooter/entity/Player.java @@ -18,14 +18,14 @@ public class Player extends ShootingEntity implements KeyboardListener { super(x, y); this.setImage("images/ship.png"); this.setPrimaryShotImage("images/shots/laser_blue.png"); - this.setShootDamage(5); + this.setShootDamage(PlayerStatus.ShootDamage); this.setShootDelay(20); this.setShootSpawn(50, 16); this.setShootDirection(Shot.RIGHT); this.setShootSpeed(10); this.setCollisionDamage(10); - this.setHealthPoints(100); this.setShieldPoints(100); + this.setHealthPoints(PlayerStatus.HealthPoints); this.registerOnKeyboard(Keyboard.getInstance()); } diff --git a/src/de/teamteamteam/spacescooter/entity/PlayerStatus.java b/src/de/teamteamteam/spacescooter/entity/PlayerStatus.java new file mode 100644 index 0000000..5b2dcef --- /dev/null +++ b/src/de/teamteamteam/spacescooter/entity/PlayerStatus.java @@ -0,0 +1,11 @@ +package de.teamteamteam.spacescooter.entity; + +public class PlayerStatus { + + /** + * Status values for the player + */ + + public static int ShootDamage = 5; + public static int HealthPoints = 100; +} diff --git a/src/de/teamteamteam/spacescooter/entity/enemy/EnemyThree.java b/src/de/teamteamteam/spacescooter/entity/enemy/EnemyThree.java index 22a2520..15e088f 100644 --- a/src/de/teamteamteam/spacescooter/entity/enemy/EnemyThree.java +++ b/src/de/teamteamteam/spacescooter/entity/enemy/EnemyThree.java @@ -5,6 +5,7 @@ import java.util.Random; import de.teamteamteam.spacescooter.datastructure.ConcurrentIterator; import de.teamteamteam.spacescooter.entity.Entity; import de.teamteamteam.spacescooter.entity.Player; +import de.teamteamteam.spacescooter.entity.explosion.MultiExplosion; import de.teamteamteam.spacescooter.entity.item.Items; import de.teamteamteam.spacescooter.screen.Screen; import de.teamteamteam.spacescooter.utility.GameConfig; @@ -43,6 +44,14 @@ public class EnemyThree extends Enemy{ super.die(); } + /** + * Custom MultiExplosion for this enemy. + */ + @Override + public void explode() { + new MultiExplosion(this.getX(), this.getY()); + } + @Override public void update() { super.update(); diff --git a/src/de/teamteamteam/spacescooter/entity/explosion/Explosion.java b/src/de/teamteamteam/spacescooter/entity/explosion/Explosion.java deleted file mode 100644 index 0aa619a..0000000 --- a/src/de/teamteamteam/spacescooter/entity/explosion/Explosion.java +++ /dev/null @@ -1,67 +0,0 @@ -package de.teamteamteam.spacescooter.entity.explosion; - -import java.util.Random; - -import de.teamteamteam.spacescooter.entity.Entity; - - -public class Explosion extends Entity { - - /** - * Time to 'live' in update ticks. Will be decreased with each update()-call. - */ - private int timeToLive; - - /** - * Attributes for the 'spawn more' constructor. - */ - private int count; - private int height; - private int width; - /** - * Instance of Random, so we get good random numbers. - */ - private Random random; - - /** - * Just be a single explosion. - */ - public Explosion(int x, int y) { - super(x, y); - this.setImage("images/explosions/explosion_proto.png"); - this.setPosition(x - (this.getWidth()/2), y - (this.getHeight()/2)); - Random rand = new Random(); - if (rand.nextInt(99) <= 70) { - new ExplosionOne(x, y); - } else { - new ExplosionTwo(x, y); - } - } - - /** - * Be an explosion that spawns even more explosions! :O - */ - public Explosion(int x, int y, int count, int width, int height) { - super(x, y); - System.out.println("Explosion with: " + count); - this.setImage("images/explosions/explosion_proto.png"); - this.setPosition(x, y); - this.random = new Random(); - this.count = 10; - this.width = width; - this.height = height; - this.timeToLive = 100 * this.count; //Just a random value of ticks the explosion will take to spawn more explosions. - } - - /** - * Here, a countdown is happening. Every X ticks, a new Explosion is born. - */ - public void update() { - this.timeToLive--; - if(this.timeToLive <= 0) this.remove(); - if(this.count > 0 && this.timeToLive % this.count == 0) { - new Explosion(this.getX() + (int) (this.width * this.random.nextDouble()), this.getY() + (int) (this.height * this.random.nextDouble())); - this.count--; - } - } -} diff --git a/src/de/teamteamteam/spacescooter/entity/explosion/ExplosionOne.java b/src/de/teamteamteam/spacescooter/entity/explosion/ExplosionOne.java index dc2bd60..0a21761 100644 --- a/src/de/teamteamteam/spacescooter/entity/explosion/ExplosionOne.java +++ b/src/de/teamteamteam/spacescooter/entity/explosion/ExplosionOne.java @@ -1,45 +1,21 @@ package de.teamteamteam.spacescooter.entity.explosion; -import de.teamteamteam.spacescooter.entity.Entity; +import de.teamteamteam.spacescooter.entity.Animation; -public class ExplosionOne extends Entity { +public class ExplosionOne extends Animation { - private int count = 71; - public ExplosionOne(int x, int y) { super(x, y); - this.setImage("images/explosions/explosion_proto.png"); + String[] images = { + "images/explosions/01/explosion1.png", + "images/explosions/01/explosion2.png", + "images/explosions/01/explosion3.png", + "images/explosions/01/explosion4.png", + "images/explosions/01/explosion5.png", + "images/explosions/01/explosion6.png", + "images/explosions/01/explosion7.png" + }; + this.configure(images, 10); this.setPosition(x - (this.getWidth()/2), y - (this.getHeight()/2)); } - - public void update() { - if (count >= 0) { - count--; - } else { - this.remove(); - } - switch (count) { - case 70: - this.setImage("images/explosions/01/explosion1.png"); - break; - case 60: - this.setImage("images/explosions/01/explosion2.png"); - break; - case 50: - this.setImage("images/explosions/01/explosion3.png"); - break; - case 40: - this.setImage("images/explosions/01/explosion4.png"); - break; - case 30: - this.setImage("images/explosions/01/explosion5.png"); - break; - case 20: - this.setImage("images/explosions/01/explosion6.png"); - break; - case 10: - this.setImage("images/explosions/01/explosion7.png"); - break; - } - } } diff --git a/src/de/teamteamteam/spacescooter/entity/explosion/ExplosionTwo.java b/src/de/teamteamteam/spacescooter/entity/explosion/ExplosionTwo.java index 3fa2d5b..2121a3a 100644 --- a/src/de/teamteamteam/spacescooter/entity/explosion/ExplosionTwo.java +++ b/src/de/teamteamteam/spacescooter/entity/explosion/ExplosionTwo.java @@ -1,73 +1,31 @@ package de.teamteamteam.spacescooter.entity.explosion; -import de.teamteamteam.spacescooter.entity.Entity; +import de.teamteamteam.spacescooter.entity.Animation; -public class ExplosionTwo extends Entity { +public class ExplosionTwo extends Animation { - private int count = 141; - public ExplosionTwo(int x, int y) { super(x, y); - this.setImage("images/explosions/explosion_proto.png"); + String[] images = { + "images/explosions/02/explosion2_1.png", + "images/explosions/02/explosion2_2.png", + "images/explosions/02/explosion2_3.png", + "images/explosions/02/explosion2_4.png", + "images/explosions/02/explosion2_5.png", + "images/explosions/02/explosion2_6.png", + "images/explosions/02/explosion2_7.png", + "images/explosions/02/explosion2_8.png", + "images/explosions/02/explosion2_9.png", + "images/explosions/02/explosion2_10.png", + "images/explosions/02/explosion2_11.png", + "images/explosions/02/explosion2_12.png", + "images/explosions/02/explosion2_13.png", + "images/explosions/02/explosion2_14.png", + "images/explosions/02/explosion2_15.png", + "images/explosions/02/explosion2_16.png" + }; + this.configure(images, 10); this.setPosition(x - (this.getWidth()/2), y - (this.getHeight()/2)); } - - public void update() { - if (count >= 0) { - count--; - } else { - this.remove(); - } - switch (count) { - case 150: - this.setImage("images/explosions/02/explosion2_1.png"); - break; - case 140: - this.setImage("images/explosions/02/explosion2_2.png"); - break; - case 130: - this.setImage("images/explosions/02/explosion2_3.png"); - break; - case 120: - this.setImage("images/explosions/02/explosion2_4.png"); - break; - case 110: - this.setImage("images/explosions/02/explosion2_5.png"); - break; - case 100: - this.setImage("images/explosions/02/explosion2_6.png"); - break; - case 90: - this.setImage("images/explosions/02/explosion2_7.png"); - break; - case 80: - this.setImage("images/explosions/02/explosion2_8.png"); - break; - case 70: - this.setImage("images/explosions/02/explosion2_9.png"); - break; - case 60: - this.setImage("images/explosions/02/explosion2_10.png"); - break; - case 50: - this.setImage("images/explosions/02/explosion2_11.png"); - break; - case 40: - this.setImage("images/explosions/02/explosion2_12.png"); - break; - case 30: - this.setImage("images/explosions/02/explosion2_13.png"); - break; - case 20: - this.setImage("images/explosions/02/explosion2_14.png"); - break; - case 10: - this.setImage("images/explosions/02/explosion2_15.png"); - break; - case 1: - this.setImage("images/explosions/02/explosion2_16.png"); - break; - } - } } diff --git a/src/de/teamteamteam/spacescooter/entity/explosion/MultiExplosion.java b/src/de/teamteamteam/spacescooter/entity/explosion/MultiExplosion.java new file mode 100644 index 0000000..c6a0e4f --- /dev/null +++ b/src/de/teamteamteam/spacescooter/entity/explosion/MultiExplosion.java @@ -0,0 +1,63 @@ +package de.teamteamteam.spacescooter.entity.explosion; + +import java.util.Random; + +/** + * Extends the functionality of the simple ExplosionOne to randomly + * spawn more explosions in the area. + */ +public class MultiExplosion extends ExplosionOne { + + /** + * Internal tick counter. + */ + private int counter; + + /** + * Instance of Random, so we get good random numbers. + */ + private Random random; + + /** + * Just be a single explosion. + */ + public MultiExplosion(int x, int y) { + super(x, y); + this.random = new Random(); + } + + /** + * Decide every 10 ticks whether or not to spawn a random explosion. + */ + @Override + public void update() { + if(this.counter % 10 == 0) { + if(this.random.nextBoolean()) { + this.spawnExplosion(); + } + } + this.counter++; + super.update(); + } + + /** + * Randomly spawn a new random explosion at a random location. + */ + private void spawnExplosion() { + int x_offset = this.random.nextInt(35); + if(this.random.nextBoolean()) x_offset *= -1; + int y_offset = this.random.nextInt(35); + if(this.random.nextBoolean()) y_offset *= -1; + int explosionType = this.random.nextInt(2); + switch(explosionType) { + case 0: + new ExplosionOne(this.getX() + x_offset, this.getY() + y_offset); + break; + case 1: + new ExplosionTwo(this.getX() + x_offset, this.getY() + y_offset); + break; + default: + break; + } + } +} diff --git a/src/de/teamteamteam/spacescooter/entity/shot/Shot.java b/src/de/teamteamteam/spacescooter/entity/shot/Shot.java index 49364b5..913846f 100644 --- a/src/de/teamteamteam/spacescooter/entity/shot/Shot.java +++ b/src/de/teamteamteam/spacescooter/entity/shot/Shot.java @@ -1,6 +1,8 @@ package de.teamteamteam.spacescooter.entity.shot; import de.teamteamteam.spacescooter.entity.LivingEntity; +import de.teamteamteam.spacescooter.entity.Player; +import de.teamteamteam.spacescooter.entity.enemy.Enemy; import de.teamteamteam.spacescooter.entity.spi.Collidable; import de.teamteamteam.spacescooter.utility.GameConfig; @@ -49,6 +51,14 @@ public class Shot extends LivingEntity { this.setImage(filename); this.setPosition(this.getX() - this.getImage().getWidth() / 2, this.getY() - this.getImage().getHeight() / 2); } + + /** + * Return the direction the Shot is traveling into. + * Returns Shot.LEFT or Shot.RIGHT + */ + public int getDirection() { + return this.direction; + } /** * Returns the damage this shot does to LivingEntities it hits. @@ -85,6 +95,8 @@ public class Shot extends LivingEntity { */ @Override public void collideWith(Collidable entity) { + if(this.direction == LEFT && entity instanceof Enemy) return; + if(this.direction == RIGHT && entity instanceof Player) return; super.collideWith(entity); this.explode(); this.remove(); diff --git a/src/de/teamteamteam/spacescooter/gui/Credits.java b/src/de/teamteamteam/spacescooter/gui/Credits.java new file mode 100644 index 0000000..930a580 --- /dev/null +++ b/src/de/teamteamteam/spacescooter/gui/Credits.java @@ -0,0 +1,17 @@ +package de.teamteamteam.spacescooter.gui; + +public class Credits { + /** + * Credit points for the shop + */ + private static int credits = 1000; + + public static int getCredits() { + return credits; + } + + public static void setCredits(int credits) { + Credits.credits = credits; + System.out.println(credits); + } +} diff --git a/src/de/teamteamteam/spacescooter/screen/MainMenuScreen.java b/src/de/teamteamteam/spacescooter/screen/MainMenuScreen.java index f06075f..4c56e02 100644 --- a/src/de/teamteamteam/spacescooter/screen/MainMenuScreen.java +++ b/src/de/teamteamteam/spacescooter/screen/MainMenuScreen.java @@ -101,6 +101,7 @@ public class MainMenuScreen extends Screen { this.parent.setOverlay(new GameScreen(this.parent)); break; case 1: + this.parent.setOverlay(new ShopScreen(this.parent)); break; case 2: break; diff --git a/src/de/teamteamteam/spacescooter/screen/ShopScreen.java b/src/de/teamteamteam/spacescooter/screen/ShopScreen.java new file mode 100644 index 0000000..64afe4a --- /dev/null +++ b/src/de/teamteamteam/spacescooter/screen/ShopScreen.java @@ -0,0 +1,101 @@ +package de.teamteamteam.spacescooter.screen; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.event.KeyEvent; +import java.awt.image.BufferedImage; + +import de.teamteamteam.spacescooter.control.Keyboard; +import de.teamteamteam.spacescooter.entity.Player; +import de.teamteamteam.spacescooter.entity.PlayerStatus; +import de.teamteamteam.spacescooter.gui.Button; +import de.teamteamteam.spacescooter.gui.Credits; +import de.teamteamteam.spacescooter.utility.GameConfig; +import de.teamteamteam.spacescooter.utility.Loader; + +public class ShopScreen extends Screen { + + private BufferedImage img; + private float playerMoveSpeed = 0; + private int menuPoint = 0; + private boolean keyPressed = false; + private Player player; + private int animationStatus = 0; //0 = Animation noch nicht gestartet, 1 = Animation laeuft, 2 = Animation beendet + + public ShopScreen(Screen parent) { + super(parent); + this.img = Loader.getBufferedImageByFilename("images/testbackground.png"); + new Button(GameConfig.windowWidth/2-125, 250); + new Button(GameConfig.windowWidth/2-125, 350); + new Button(GameConfig.windowWidth/2-125, 450); + player = new Player(GameConfig.windowWidth/2-170, 259); + player.setCanMove(false); + player.setCanShoot(false); + } + + @Override + protected void paint(Graphics2D g) { + g.drawImage(this.img, 0, 0, null); + this.entityPaintIterator.reset(); + while (this.entityPaintIterator.hasNext()) { + this.entityPaintIterator.next().paint(g); + } + g.setFont(new Font("Monospace", 0, 20)); + g.setColor(new Color(255, 255, 255)); + g.drawString("Credits: " + String.valueOf(Credits.getCredits()), GameConfig.windowWidth/2-30, 200); + g.setColor(new Color(0, 0, 0)); + g.drawString("Schaden", GameConfig.windowWidth/2-30, 282); + g.drawString("Leben", GameConfig.windowWidth/2-50, 382); + g.drawString("Hauptmen\u00fc", GameConfig.windowWidth/2-50, 482); + } + + @Override + protected void update() { + if(Keyboard.isKeyDown(KeyEvent.VK_DOWN) && !this.keyPressed && this.animationStatus == 0) { + this.keyPressed = true; + if(this.menuPoint<2){ + this.menuPoint++; + this.player.setPosition(this.player.getX(), 259+(this.menuPoint*100)); + } + }else if(Keyboard.isKeyDown(KeyEvent.VK_UP) && !this.keyPressed && this.animationStatus == 0) { + this.keyPressed = true; + if(this.menuPoint>0) { + this.menuPoint--; + this.player.setPosition(this.player.getX(), 259+(this.menuPoint*100)); + } + }else if(Keyboard.isKeyDown(KeyEvent.VK_ENTER) && !this.keyPressed && this.animationStatus == 0) { + this.keyPressed = true; + switch (this.menuPoint) { + case 0: + if(Credits.getCredits() >= 5){ + PlayerStatus.ShootDamage += 5; + Credits.setCredits(Credits.getCredits() - 5); + } + break; + case 1: + if(Credits.getCredits() >= 10){ + PlayerStatus.HealthPoints += 10; + Credits.setCredits(Credits.getCredits() - 10); + } + break; + case 2: + this.animationStatus = 1; + break; + } + } + if(!Keyboard.isKeyDown(KeyEvent.VK_DOWN) && !Keyboard.isKeyDown(KeyEvent.VK_UP) && !Keyboard.isKeyDown(KeyEvent.VK_ENTER)) { + this.keyPressed = false; + } + + if(this.animationStatus == 1) { + if(this.player.getX() <= GameConfig.windowWidth) { + this.player.setPosition(this.player.getX() + (int) playerMoveSpeed, this.player.getY()); + this.playerMoveSpeed += 0.1; + } else this.animationStatus = 2; + } else if(this.animationStatus == 2) { + this.parent.setOverlay(new MainMenuScreen(this.parent)); + } + } + +}