From c3c683533334cca04c356d3b11ac213d80d5ca38 Mon Sep 17 00:00:00 2001 From: Aran Zaiger Date: Sun, 20 Mar 2016 23:21:31 +0200 Subject: [PATCH] added documentation --- .../dayan/Games/Elements/AnimatedSprite.java | 17 +++- .../sagi/dayan/Games/Elements/Background.java | 2 +- src/com/sagi/dayan/Games/Elements/Blast.java | 4 + .../sagi/dayan/Games/Elements/EnemyShip.java | 7 +- .../dayan/Games/Elements/MenuBoxSprite.java | 2 +- .../sagi/dayan/Games/Elements/Missile.java | 2 +- src/com/sagi/dayan/Games/Elements/Player.java | 12 ++- src/com/sagi/dayan/Games/Elements/Wave.java | 25 +++-- .../sagi/dayan/Games/Engine/GameEngine.java | 47 +++++----- .../sagi/dayan/Games/Stage/BlitzStage.java | 4 +- .../sagi/dayan/Games/Stage/FifthStage.java | 4 +- .../sagi/dayan/Games/Stage/FirstStage.java | 4 +- .../sagi/dayan/Games/Stage/FourthStage.java | 4 +- src/com/sagi/dayan/Games/Stage/Level.java | 93 ++++++++++++------- .../sagi/dayan/Games/Stage/MainMenuScene.java | 4 +- src/com/sagi/dayan/Games/Stage/Scene.java | 18 ++-- .../sagi/dayan/Games/Stage/SecondStage.java | 4 +- .../dayan/Games/Stage/SettingsMenuScene.java | 3 +- .../sagi/dayan/Games/Stage/SixthStage.java | 4 +- src/com/sagi/dayan/Games/Stage/Stage.java | 2 +- .../sagi/dayan/Games/Stage/ThirdStage.java | 4 +- .../sagi/dayan/Games/Utils/WaveConfig.java | 2 +- .../sagi/dayan/Games/Utils/WaveConfigs.java | 6 +- 23 files changed, 171 insertions(+), 103 deletions(-) diff --git a/src/com/sagi/dayan/Games/Elements/AnimatedSprite.java b/src/com/sagi/dayan/Games/Elements/AnimatedSprite.java index ecc5e09..c1ba44c 100644 --- a/src/com/sagi/dayan/Games/Elements/AnimatedSprite.java +++ b/src/com/sagi/dayan/Games/Elements/AnimatedSprite.java @@ -10,7 +10,7 @@ import javax.imageio.ImageIO; import javax.swing.JPanel; /** - * Created by sagi on 2/10/16. + * AnimatedSprite represents a sprite with animated img */ public abstract class AnimatedSprite extends Sprite { protected Vector animations; @@ -20,6 +20,7 @@ public abstract class AnimatedSprite extends Sprite { public AnimatedSprite(int x, int y, int w, int h, int acc, String imgName, double angle, int sWidth, int sHeight, int numOfFirstFrames) { super(x, y, w, h, acc, imgName, angle, sWidth, sHeight); animations = new Vector<>(); + //start first animation of set of animations initFirstAnimation(imgName, numOfFirstFrames); currentAnimation = 0; @@ -27,6 +28,7 @@ public abstract class AnimatedSprite extends Sprite { protected abstract void initFirstAnimation(String spriteSheet, int numOfFirstFrames); + //draw each time the correct image of the animation @Override public void drawSprite(Graphics g, JPanel p) { if(animations.size() == 0) @@ -35,6 +37,8 @@ public abstract class AnimatedSprite extends Sprite { g2d.rotate(Math.toRadians(angle), locX + (bImage.getWidth() / 2), locY + (bImage.getHeight() / 2)); g.drawImage(animations.get(currentAnimation).getCurrentFrame(), locX, locY, p); g2d.rotate(-1 * Math.toRadians(angle), locX + (bImage.getWidth() / 2), locY + (bImage.getHeight() / 2)); + + //fix img if it goes beyond screen borders if(screenLoop) { drawScreenLoopFix(g, p); outOfScreeFix(); @@ -46,11 +50,13 @@ public abstract class AnimatedSprite extends Sprite { bImage = animations.get(currentAnimation).getCurrentFrame(); super.drawScreenLoopFix(g,p); } - + + //gets current used frame from animation public int getFrameNum(){ return animations.get(currentAnimation).getFrameIndex(); } + //decide which animation to play. go back to start if finished public void setCurrentAnimation(int animation){ if(animation < 0){ throw new IllegalArgumentException("Animation index cant be negative"); @@ -66,6 +72,7 @@ public abstract class AnimatedSprite extends Sprite { } + //a class to represent an animation in SpriteAnimation protected class Animation { private int totalLoopTime; @@ -100,13 +107,18 @@ public abstract class AnimatedSprite extends Sprite { } + + //returns current played frame index public int getFrameIndex() { return currentFrame;} + + //add more frames if animation changed private void addFrame(BufferedImage image, double frameLength) { frames.add(new AnimationFrame(image, totalLoopTime,frameLength)); totalLoopTime += frameLength; } + //returns current played frame public BufferedImage getCurrentFrame() { long now = System.currentTimeMillis(); long delta = now - startingTime; @@ -121,6 +133,7 @@ public abstract class AnimatedSprite extends Sprite { return frames.get(currentFrame).getFrame(); } + //represents a single frame from animation protected class AnimationFrame { private double startTime, endTime; private BufferedImage frame; diff --git a/src/com/sagi/dayan/Games/Elements/Background.java b/src/com/sagi/dayan/Games/Elements/Background.java index 42a0411..ffa6ee9 100644 --- a/src/com/sagi/dayan/Games/Elements/Background.java +++ b/src/com/sagi/dayan/Games/Elements/Background.java @@ -1,7 +1,7 @@ package com.sagi.dayan.Games.Elements; /** - * Created by sagi on 2/20/16. + * Represents background for the game */ public class Background extends Sprite { public Background(int x, int y, int w, int h, int acc, String imgName, double angle, int sWidth, int sHeight) { diff --git a/src/com/sagi/dayan/Games/Elements/Blast.java b/src/com/sagi/dayan/Games/Elements/Blast.java index fe4a90e..f22ecb1 100644 --- a/src/com/sagi/dayan/Games/Elements/Blast.java +++ b/src/com/sagi/dayan/Games/Elements/Blast.java @@ -2,6 +2,9 @@ package com.sagi.dayan.Games.Elements; import com.sagi.dayan.Games.Elements.AnimatedSprite.Animation; +/* + represents a blast when player ship explodes + */ public class Blast extends AnimatedSprite { protected boolean isDone; @@ -18,6 +21,7 @@ public class Blast extends AnimatedSprite { animations.add(new Animation("explosion.png", 16, 500)); } + //set done when finished iterating on all frames @Override public void update() { System.out.println("curr: "+currentAnimation+", total: "+numOfFirstFrames); diff --git a/src/com/sagi/dayan/Games/Elements/EnemyShip.java b/src/com/sagi/dayan/Games/Elements/EnemyShip.java index 5fd2450..2d12727 100644 --- a/src/com/sagi/dayan/Games/Elements/EnemyShip.java +++ b/src/com/sagi/dayan/Games/Elements/EnemyShip.java @@ -4,7 +4,7 @@ package com.sagi.dayan.Games.Elements; import com.sagi.dayan.Games.Utils.Utils; /** - * Created by sagi on 2/20/16. + * represents an enemy ship */ public class EnemyShip extends AnimatedSprite { protected int currentStep; @@ -15,6 +15,7 @@ public class EnemyShip extends AnimatedSprite { protected int hitsToDestroy; protected boolean isDone; protected long startExploded; + public EnemyShip(int x, int y, int w, int h, int acc, String imgName, double angle, int sWidth, int sHeight,double fireDelay, double stepDelay, Wave wave, int[] moveVector,int numOfFirstFrames, int hitsToDestroy) { super(x, y, w, h, acc, imgName, angle, sWidth, sHeight, numOfFirstFrames); this.fireDelay = fireDelay; @@ -28,6 +29,7 @@ public class EnemyShip extends AnimatedSprite { } + //add enemy ship and blast animation @Override protected void initFirstAnimation(String spriteSheet, int numOfFirstFrames) { if(imageName == "L1-ES2.png"){ @@ -58,6 +60,7 @@ public class EnemyShip extends AnimatedSprite { locX += acceleration * Math.cos(Math.toRadians(moveVector[currentStep])); locY -= acceleration * -1* Math.sin(Math.toRadians(moveVector[currentStep])); } + //when enemy gets hit- lower life and set explosion sound if dead public void gotHit() { hitsToDestroy--; if(hitsToDestroy == 0){ @@ -66,8 +69,8 @@ public class EnemyShip extends AnimatedSprite { currentAnimation++; Utils.playSound("enemy_exp.wav"); } - System.out.println("GOT HIT " + hitsToDestroy); } + public boolean isDead() { return hitsToDestroy <= 0; } diff --git a/src/com/sagi/dayan/Games/Elements/MenuBoxSprite.java b/src/com/sagi/dayan/Games/Elements/MenuBoxSprite.java index df2f75c..f8d4ed5 100644 --- a/src/com/sagi/dayan/Games/Elements/MenuBoxSprite.java +++ b/src/com/sagi/dayan/Games/Elements/MenuBoxSprite.java @@ -1,7 +1,7 @@ package com.sagi.dayan.Games.Elements; /** - * Created by sagi on 2/24/16. + * Animation for box in main menu */ public class MenuBoxSprite extends AnimatedSprite { public MenuBoxSprite(int x, int y, int w, int h, int acc, String imgName, double angle, int sWidth, int sHeight, int numOfFirstFrames) { diff --git a/src/com/sagi/dayan/Games/Elements/Missile.java b/src/com/sagi/dayan/Games/Elements/Missile.java index c161d96..366012c 100644 --- a/src/com/sagi/dayan/Games/Elements/Missile.java +++ b/src/com/sagi/dayan/Games/Elements/Missile.java @@ -1,7 +1,7 @@ package com.sagi.dayan.Games.Elements; /** - * Created by sagi on 2/20/16. + * represents a missile of enemy/player ship */ public class Missile extends AnimatedSprite { diff --git a/src/com/sagi/dayan/Games/Elements/Player.java b/src/com/sagi/dayan/Games/Elements/Player.java index 3c4d0d9..34b4595 100644 --- a/src/com/sagi/dayan/Games/Elements/Player.java +++ b/src/com/sagi/dayan/Games/Elements/Player.java @@ -5,7 +5,7 @@ import java.awt.Graphics; import javax.swing.JPanel; /** - * Created by sagi on 2/20/16. + * Represents a player ship */ public class Player extends AnimatedSprite { private final int NORMAL_ANIMATION = 0, RIGHT_ANIMATION = 1, LEFT_ANIMATION = 2, PADDING_BOTTOM = 35, MORTAL_DELAY = 3; @@ -46,6 +46,7 @@ public class Player extends AnimatedSprite { isGameOver = gameOver; } + //when player revived - reset it to default position public void resetPlayer(){ locX = startX; locY = startY; @@ -68,6 +69,7 @@ public class Player extends AnimatedSprite { return isMortal; } + //besides position update, updated whether ship can fire or not @Override public void update() { long now = System.currentTimeMillis(); @@ -90,17 +92,14 @@ public class Player extends AnimatedSprite { locY = pHeight - animations.get(currentAnimation).getCurrentFrame().getHeight() - PADDING_BOTTOM; } - if(isGameOver){ - //System.exit(1); - } } + //set horizontal and vertical direction public void sethDirection(int direction) { this.hDirection = direction; } - public void setvDirection(int direction) { this.vDirection = direction; if(direction != NORMAL_ANIMATION){ @@ -127,10 +126,13 @@ public class Player extends AnimatedSprite { this.fireDelay = fireDelay; } + //update time since last fired public void updateFireTime(){ lastFired = System.currentTimeMillis(); } + + //if player was dead dont draw (creates blinking effect) @Override public void drawSprite(Graphics g, JPanel p){ long now = System.currentTimeMillis(); diff --git a/src/com/sagi/dayan/Games/Elements/Wave.java b/src/com/sagi/dayan/Games/Elements/Wave.java index 3729e96..eb32fd3 100644 --- a/src/com/sagi/dayan/Games/Elements/Wave.java +++ b/src/com/sagi/dayan/Games/Elements/Wave.java @@ -11,19 +11,20 @@ import com.sagi.dayan.Games.Stage.Level; import com.sagi.dayan.Games.Utils.Utils; /** - * Created by sagi on 3/11/16. + * represents a single wave of enemy ships. + * this class will manage a wave of enemies, create them when needed & create missiles when needed. + * timing of creating and shooting is done using system time. */ public class Wave { - protected Level level; - protected int enemyMaxAmount, currentAmount, acc, startX, startY; + protected Level level; //used to ask for a misslie to be created + protected int enemyMaxAmount, currentAmount, hitsToDestroy, acc, startX, startY; protected double stepDelay,fireDelay, launchDelay; protected int[] moveVector; protected Vector enemies; protected Vector bullets; protected long lastLaunchTime; protected String imageName; - protected int hitsToDestroy; protected Random r; protected boolean isShipOfTypeOne; @@ -44,24 +45,30 @@ public class Wave { this.lastLaunchTime = System.currentTimeMillis(); this.hitsToDestroy = hitsToDestroy; this.r = new Random(); + + //decides which ship img to use int odds = r.nextInt(100); isShipOfTypeOne = (odds > 60) ? true : false; } + public void update(){ long now = System.currentTimeMillis(); Vector enemiesToRemove = new Vector<>(); + + // Create (RANDOM) new enemy if enough time passed since last launch (launchDelay) if(now - lastLaunchTime >= launchDelay * 1000 && currentAmount <= enemyMaxAmount){ - // Create (RANDOM) new enemy + //choose img if(isShipOfTypeOne){ enemies.add(new EnemyShip(startX, startY, level.getStageHeight(), level.getStageHeight(), acc, imageName, 0, 15, 15, fireDelay, stepDelay, this, moveVector, 8, hitsToDestroy)); }else{ enemies.add(new EnemyShip(startX, startY, level.getStageHeight(), level.getStageHeight(), acc, "L1-ES2.png", 0, 15, 15, fireDelay, stepDelay, this, moveVector, 2, hitsToDestroy)); } Utils.playSound("enemy_enter.wav"); - lastLaunchTime = now; + lastLaunchTime = now; //save new time currentAmount++; } + //update enemies & missiles, and remove the ones who are dead\OOS for (int i = 0; i < enemies.size() ; i++){ enemies.get(i).update(); if (enemies.get(i).isDone() || enemies.get(i).isOutOfScreen()) { @@ -76,6 +83,7 @@ public class Wave { } + //render missiles and enemy ships public void render(Graphics g, JPanel p){ for (int i = 0; i < bullets.size() ; i++){ bullets.get(i).drawSprite(g, p); @@ -85,6 +93,7 @@ public class Wave { } } + //if enemy is not dead create a new missile public void fireFromEnemy(EnemyShip e){ if(!e.isDead()) { level.enemyFire(e.getCenterX(), (int) (e.getLocY() + e.getsHeight()), -(e.getAcceleration() + 2)); @@ -92,13 +101,17 @@ public class Wave { } } + //returns all enemys in wave public Vector getEnemies() { return enemies; } + //used when an enemy gets hit to remove life public void enemyHit(EnemyShip es) { es.gotHit(); } + + //returns true if all enemy ships launched and died or OOS public boolean isWaveOver() { return enemies.size() == 0 && currentAmount >= enemyMaxAmount; } diff --git a/src/com/sagi/dayan/Games/Engine/GameEngine.java b/src/com/sagi/dayan/Games/Engine/GameEngine.java index ac87c09..9d02ddb 100644 --- a/src/com/sagi/dayan/Games/Engine/GameEngine.java +++ b/src/com/sagi/dayan/Games/Engine/GameEngine.java @@ -23,10 +23,14 @@ import com.sagi.dayan.Games.Utils.Utils; import com.sagi.dayan.Games.Utils.WaveConfigs; +/** + * this class is the game engine + * it updates and renders the current scene (i.e. start menu, stages etc.) + */ public class GameEngine { - private final int CREDIT_TIME = 10; - public boolean gameOn , gameOver, isFirstGame; + private final int CREDIT_TIME = 10, FULL_HEALTH = 100; //timeout for credits + public boolean gameOn , gameOver, isFirstGame; //flags to determine game state private JFrame frame; private int pWidth, pHeight, numOfPlayers; //panel dimensions private Random r; @@ -34,13 +38,14 @@ public class GameEngine { private Scene scene; private int p1CreditTime, p2CreditTime, creditTickTime = 1; public static final int PLAYER_WIDTH = 120, PLAYER_HEIGHT = 120; - public static final int UP=0,RIGHT=1,DOWN=2, LEFT=3, FIRE=4, USE_CREDIT=5; - public int p1HighScore, p2HighScore; + //player 1 & 2 controls + public static final int UP=0,RIGHT=1,DOWN=2, LEFT=3, FIRE=4, USE_CREDIT=5; private int[] p1Controlles = {KeyEvent.VK_UP, KeyEvent.VK_RIGHT, KeyEvent.VK_DOWN, KeyEvent.VK_LEFT, KeyEvent.VK_K, KeyEvent.VK_J}; private int[] p2Controlles = {KeyEvent.VK_W, KeyEvent.VK_D, KeyEvent.VK_S, KeyEvent.VK_A, KeyEvent.VK_Q, KeyEvent.VK_Z}; private int p1Lives, p2Lives, p1Health, p2Health, credits, p1Score, p2Score; + public int p1HighScore, p2HighScore; private long lastP1CreditTick, lastP2CreditTick; @@ -49,6 +54,8 @@ public class GameEngine { private WaveConfigs waveConfigs; private int currentLevel; + + public GameEngine(int width, int height, Stage stage){ p1HighScore = p2HighScore = 0; this.isFirstGame = true; @@ -69,23 +76,20 @@ public class GameEngine { gameFont = null; } this.waveConfigs = new WaveConfigs(); - startNewGame(); + startNewGame(); //initialize a new game } + //reset player health to full health private void resetPlayerHealth(int i){ if (i==0){ - p1Health = 100; + p1Health = FULL_HEALTH; } else{ - p2Health = 100; + p2Health = FULL_HEALTH; } } - - - - /** * initialize and reset vars and timers to "new game" configuration. @@ -121,8 +125,6 @@ public class GameEngine { } - - /** * returns gameOver flag * @return @@ -133,11 +135,8 @@ public class GameEngine { } - - - /** - * Update all sprites, including collision handling. + * Update all scenes */ public void update(){ long now = System.currentTimeMillis(); @@ -160,14 +159,15 @@ public class GameEngine { return scene.getSceneImage(); } + //initializes a new game public void startGame(int numOfPlayers){ this.numOfPlayers = numOfPlayers; startNewGame(); changeLevel(); } + //move to next level (scene) and attach listeners public void changeLevel(){ - System.out.println("current level: "+currentLevel); currentLevel++; stage.removeMouseListener(scene); stage.removeKeyListener(scene); @@ -199,7 +199,7 @@ public class GameEngine { stage.addMouseListener(scene); } - + //load controls menu public void goToSettings() { stage.removeMouseListener(scene); stage.removeKeyListener(scene); @@ -251,10 +251,10 @@ public class GameEngine { credits--; } + //when a player uses a credit - reset health, lives and consume credit public void revivePlayer(int i) { useCredit(); - if(i==0){ p1Health=100; p1Lives =3; @@ -266,7 +266,7 @@ public class GameEngine { } - + //add score to the correct player public void setScore(int i, int score) { if (i == 0) { @@ -275,6 +275,10 @@ public class GameEngine { p2Score += score; } } + + + // if a player gets hit - consume health + //if health is 0 - consume life public void setPlayerHealth(int i, int strike) { if (i == 0) { p1Health += strike; @@ -301,6 +305,7 @@ public class GameEngine { } } + //go to main menu public void goToMenu(){ stage.removeMouseListener(scene); stage.removeKeyListener(scene); diff --git a/src/com/sagi/dayan/Games/Stage/BlitzStage.java b/src/com/sagi/dayan/Games/Stage/BlitzStage.java index 4dc6c7b..4aa7aa0 100644 --- a/src/com/sagi/dayan/Games/Stage/BlitzStage.java +++ b/src/com/sagi/dayan/Games/Stage/BlitzStage.java @@ -6,7 +6,8 @@ import com.sagi.dayan.Games.Utils.WaveConfig; import com.sagi.dayan.Games.Utils.WaveConfigs; /** - * Created by sagi on 3/19/16. + * Holds specific stage data + * like: number of waves, wave types, num of enemies in each wave, launch delay etc. */ public class BlitzStage extends Level{ @@ -20,7 +21,6 @@ public class BlitzStage extends Level{ @Override protected void launchWave(long now) { lastWaveTime = now; - System.out.println("New Wave!! " + currentWave + ", Time: " + now); WaveConfig wc; int numOfEnemies = 5, numOfHits = 1; double launchDelay = 0.5, fireDelay = 5; diff --git a/src/com/sagi/dayan/Games/Stage/FifthStage.java b/src/com/sagi/dayan/Games/Stage/FifthStage.java index 53d005e..a382e68 100644 --- a/src/com/sagi/dayan/Games/Stage/FifthStage.java +++ b/src/com/sagi/dayan/Games/Stage/FifthStage.java @@ -6,7 +6,8 @@ import com.sagi.dayan.Games.Utils.WaveConfig; import com.sagi.dayan.Games.Utils.WaveConfigs; /** - * Created by sagi on 3/19/16. + * Holds specific stage data + * like: number of waves, wave types, num of enemies in each wave, launch delay etc. */ public class FifthStage extends Level{ @@ -20,7 +21,6 @@ public class FifthStage extends Level{ @Override protected void launchWave(long now) { lastWaveTime = now; - System.out.println("New Wave!! " + currentWave + ", Time: " + now); WaveConfig wc; int numOfEnemies = 5, numOfHits = 1; double launchDelay = 0.5, fireDelay = 5; diff --git a/src/com/sagi/dayan/Games/Stage/FirstStage.java b/src/com/sagi/dayan/Games/Stage/FirstStage.java index d946d29..5b765f9 100644 --- a/src/com/sagi/dayan/Games/Stage/FirstStage.java +++ b/src/com/sagi/dayan/Games/Stage/FirstStage.java @@ -6,7 +6,8 @@ import com.sagi.dayan.Games.Utils.WaveConfig; import com.sagi.dayan.Games.Utils.WaveConfigs; /** - * Created by sagi on 3/19/16. + * Holds specific stage data + * like: number of waves, wave types, num of enemies in each wave, launch delay etc. */ public class FirstStage extends Level{ @@ -20,7 +21,6 @@ public class FirstStage extends Level{ @Override protected void launchWave(long now) { lastWaveTime = now; - System.out.println("New Wave!! " + currentWave + ", Time: " + now); WaveConfig wc; int numOfEnemies = 5, numOfHits = 1; double launchDelay = 0.5, fireDelay = 5; diff --git a/src/com/sagi/dayan/Games/Stage/FourthStage.java b/src/com/sagi/dayan/Games/Stage/FourthStage.java index 1ffb7fc..9d035b5 100644 --- a/src/com/sagi/dayan/Games/Stage/FourthStage.java +++ b/src/com/sagi/dayan/Games/Stage/FourthStage.java @@ -6,7 +6,8 @@ import com.sagi.dayan.Games.Utils.WaveConfig; import com.sagi.dayan.Games.Utils.WaveConfigs; /** - * Created by sagi on 3/19/16. + * Holds specific stage data + * like: number of waves, wave types, num of enemies in each wave, launch delay etc. */ public class FourthStage extends Level{ @@ -20,7 +21,6 @@ public class FourthStage extends Level{ @Override protected void launchWave(long now) { lastWaveTime = now; - System.out.println("New Wave!! " + currentWave + ", Time: " + now); WaveConfig wc; int numOfEnemies = 5, numOfHits = 1; double launchDelay = 0.5, fireDelay = 5; diff --git a/src/com/sagi/dayan/Games/Stage/Level.java b/src/com/sagi/dayan/Games/Stage/Level.java index 012b61a..3f31abb 100644 --- a/src/com/sagi/dayan/Games/Stage/Level.java +++ b/src/com/sagi/dayan/Games/Stage/Level.java @@ -25,38 +25,40 @@ import com.sagi.dayan.Games.Engine.GameEngine; import com.sagi.dayan.Games.Utils.Utils; /** - * Created by sagi on 2/20/16. + * This class holds all the logic for all the stages. + * stages themselfs contain only specific stage data. */ public abstract class Level extends Scene { protected final double PRESS_START_PULE = 0.3; - protected boolean toDrawStart; + protected boolean toDrawStart, isStarted; + protected int p1Speed = 10,currentWave, startingAnimationIndex, numOfPlayers, numOfWaves; + + // used to save all players, missiles, enemy waves and blasts protected Vector players; - protected int p1Speed = 10; protected Vector p1Missiles, p2Missiles, enemyMissiles; - protected Background bg; - protected int[] waveDelay; - protected int currentWave; - protected int[] yAxisStartingAnimation; - protected int startingAnimationIndex; - protected boolean isStarted; protected Vector waves; protected Vector blasts; - protected int numOfPlayers; + protected Background bg; + protected int[] yAxisStartingAnimation, waveDelay; + + protected Map keys; protected String title; protected JLabel stageTitle; protected long lastWaveTime, lastPulseTime; - protected int numOfWaves; public Level(int width, int height, int numOfPlayers, GameEngine engine, String stageTitle, int[] waveDelay){ super(width, height, engine); + //initialize vectors players = new Vector<>(); p1Missiles = new Vector<>(); p2Missiles = new Vector<>(); - blasts = new Vector(); + blasts = new Vector<>(); enemyMissiles = new Vector<>(); + + //save additional information this.waveDelay = waveDelay; this.lastWaveTime = System.currentTimeMillis(); this.currentWave = 0; @@ -70,6 +72,8 @@ public abstract class Level extends Scene { this.title = stageTitle; this.stageTitle = new JLabel(this.title); + + //create requierd amount of players if(numOfPlayers == 1) { players.add(new Player((width / 2) + (GameEngine.PLAYER_WIDTH / 2), yAxisStartingAnimation[startingAnimationIndex], width, height, p1Speed, "emptyImage.png", 0, GameEngine.PLAYER_WIDTH, GameEngine.PLAYER_HEIGHT, "P1",6)); @@ -81,12 +85,14 @@ public abstract class Level extends Scene { } + //initialize keys setupKeys(); Utils.playSound("jetSound.wav"); lastPulseTime = System.currentTimeMillis(); toDrawStart = true; } + //initialize player 1 & 2 keys private void setupKeys() { int[] p1 = engine.getP1Controlles(); for(int i = 0 ; i < p1.length ; i++){ @@ -104,15 +110,18 @@ public abstract class Level extends Scene { public void update() { bg.update(); movePlayers(); - Vector wavesToRemove = new Vector<>(); + + //vectors to hold objects that needs to be removed + Vector wavesToRemove = new Vector<>(); Vector blastTRM = new Vector<>(); + //check if enough time has passed and a new wave needs to be launched long now = System.currentTimeMillis(); - // if(currentWave < waveDelay.length && now - lastWaveTime >= waveDelay[currentWave] * 1000){ if(currentWave < numOfWaves && now - lastWaveTime >= waveDelay[currentWave] * 1000){ launchWave(now); } + //if still in new game start animation - advance animation if(startingAnimationIndex < 3 && !isStarted){ if(startingAnimationIndex == 0){ startingAnimationIndex++; @@ -133,7 +142,10 @@ public abstract class Level extends Scene { startingAnimationIndex++; } } - }else{ + } + //if finished game start animation - update players, missiles, enemy waves + //if waves are done - remove them + else{ isStarted = true; for(int i = 0 ; i < players.size() ; i++){ players.get(i).update(); @@ -152,40 +164,43 @@ public abstract class Level extends Scene { for(int i = 0 ; i < waves.size() ; i++){ waves.get(i).update(); if(waves.get(i).isWaveOver()) { - System.out.println("in remove"); wavesToRemove.add(waves.get(i)); } } waves.removeAll(wavesToRemove); + //check and set high score if(engine.getP1Score() > engine.getP1HighScore()) engine.setP1HighScore(engine.getP1Score()); if(engine.getP2Score() > engine.getP2HighScore()) engine.setP2HighScore(engine.getP2Score()); } + + //check all collisions checkCollision(); engine.setGameOver(isGameOver()); + + //if all waves are done switch stage if(currentWave >= numOfWaves && waves.size()==0) { - System.out.println("Done"); engine.changeLevel(); } + //remove finished blasts and update existing for(int i =0; i 0){ @@ -376,10 +391,13 @@ public abstract class Level extends Scene { } } } + + //render all waves for(int i = 0 ; i < waves.size() ; i++){ waves.get(i).render(g,p); } + //render all blasts for(int i =0; i p1MTR, p2MTR, eMTR; eMTR = new Vector<>(); p1MTR = new Vector<>(); @@ -456,12 +478,12 @@ public abstract class Level extends Scene { //player vs. enemy missile for (int j = 0; j < enemyMissiles.size(); j++) { if(CollisionUtil.collidesWith(players.get(i),enemyMissiles.get(j))){ + if ((i==0 && engine.getP1Health()==10) ||(i==1 && engine.getP2Health()==10)) { + blasts.add(new Blast((int) players.get(i).getLocX(), (int) players.get(i).getLocY(), "explosion.png", 15)); + } playerHit(i); if(playerIsAlive(i)) { eMTR.add(enemyMissiles.get(j)); - }else{ - blasts.add(new Blast((int)players.get(i).getLocX(),(int)players.get(i).getLocY(),"explosion.png",15)); - Utils.playSound("player_exp.wav"); } } } @@ -472,18 +494,19 @@ public abstract class Level extends Scene { for (int k = 0; k < waves.get(j).getEnemies().size(); k++) { if (CollisionUtil.collidesWith(waves.get(j).getEnemies().get(k), players.get(i))) { if(!waves.get(j).getEnemies().get(k).isDead()){ + if ((i==0 && engine.getP1Health()==10) || (i==1 && engine.getP2Health()==10)) { + blasts.add(new Blast((int) players.get(i).getLocX(), (int) players.get(i).getLocY(), "explosion.png", 15)); + } playerHit(i); } if(playerIsAlive(i)) { waves.get(j).enemyHit(waves.get(j).getEnemies().get(k)); - }else{ - blasts.add(new Blast((int)players.get(i).getLocX(),(int)players.get(i).getLocY(),"explosion.png",15)); - } } } } + //check for each player seperatly for score //player 1 missile vs. enemy if(i == 0){ for(int m = 0 ; m < p1Missiles.size() ; m++){ @@ -502,7 +525,7 @@ public abstract class Level extends Scene { } - //player 1 missile vs. enemy + //player 2 missile vs. enemy else { for(int m = 0 ; m < p2Missiles.size() ; m++){ for (int j = 0; j < waves.size(); j++) { @@ -522,14 +545,14 @@ public abstract class Level extends Scene { } - - + //remove all objects that needs to be removed p1Missiles.removeAll(p1MTR); p2Missiles.removeAll(p2MTR); enemyMissiles.removeAll(eMTR); } + //checks if player is alive protected boolean playerIsAlive(int i){ if(i == 0){ return !(engine.getP1Lives() <= 0); @@ -538,6 +561,7 @@ public abstract class Level extends Scene { } } + //reduce player health and play hit audio protected void playerHit(int i){ if(players.get(i).isMortal()){ Utils.playSound((i == 0) ? "player_1_hit.wav" : "player_2_hit.wav"); @@ -554,6 +578,7 @@ public abstract class Level extends Scene { } } + //create a new enemy missile public void enemyFire(int x, int y, int acc) { enemyMissiles.add(new Missile(x, y,getStageWidth(),getStageHeight(), acc,"E1-Fire.png", 15)); } diff --git a/src/com/sagi/dayan/Games/Stage/MainMenuScene.java b/src/com/sagi/dayan/Games/Stage/MainMenuScene.java index 3c2b0a6..87aa7c1 100644 --- a/src/com/sagi/dayan/Games/Stage/MainMenuScene.java +++ b/src/com/sagi/dayan/Games/Stage/MainMenuScene.java @@ -17,7 +17,7 @@ import com.sagi.dayan.Games.Engine.GameEngine; import com.sagi.dayan.Games.Utils.Utils; /** - * Created by sagi on 2/24/16. + * represent the main menu scene. */ public class MainMenuScene extends Scene { @@ -48,6 +48,7 @@ public class MainMenuScene extends Scene { } + //render all objects and players high scores @Override public void render(JPanel p) { sceneImage = new BufferedImage(this.stageWidth, this.stageHeight, Image.SCALE_FAST); @@ -80,6 +81,7 @@ public class MainMenuScene extends Scene { } + //key listener for moving and selecting option in the main menu @Override public void keyPressed(KeyEvent keyEvent) { switch (keyEvent.getKeyCode()){ diff --git a/src/com/sagi/dayan/Games/Stage/Scene.java b/src/com/sagi/dayan/Games/Stage/Scene.java index 4bae4dd..f711ba6 100644 --- a/src/com/sagi/dayan/Games/Stage/Scene.java +++ b/src/com/sagi/dayan/Games/Stage/Scene.java @@ -1,7 +1,7 @@ package com.sagi.dayan.Games.Stage; /** - * Created by sagi on 2/8/16. + * Represents a Scene in the game (i.e. main menu, stage etc.) */ import java.awt.event.KeyListener; @@ -14,14 +14,6 @@ import com.sagi.dayan.Games.Engine.GameEngine; public abstract class Scene extends MouseAdapter implements KeyListener{ - public int getStageWidth() { - return stageWidth; - } - - public int getStageHeight() { - return stageHeight; - } - protected int stageWidth, stageHeight; protected BufferedImage sceneImage; protected GameEngine engine; @@ -32,6 +24,14 @@ public abstract class Scene extends MouseAdapter implements KeyListener{ this.engine = engine; } + //get dimentions + public int getStageWidth() { + return stageWidth; + } + public int getStageHeight() { + return stageHeight; + } + public abstract void update (); public abstract void render(JPanel p); diff --git a/src/com/sagi/dayan/Games/Stage/SecondStage.java b/src/com/sagi/dayan/Games/Stage/SecondStage.java index 178d904..3130220 100644 --- a/src/com/sagi/dayan/Games/Stage/SecondStage.java +++ b/src/com/sagi/dayan/Games/Stage/SecondStage.java @@ -6,7 +6,8 @@ import com.sagi.dayan.Games.Utils.WaveConfig; import com.sagi.dayan.Games.Utils.WaveConfigs; /** - * Created by sagi on 3/19/16. + * Holds specific stage data + * like: number of waves, wave types, num of enemies in each wave, launch delay etc. */ public class SecondStage extends Level{ @@ -20,7 +21,6 @@ public class SecondStage extends Level{ @Override protected void launchWave(long now) { lastWaveTime = now; - System.out.println("New Wave!! " + currentWave + ", Time: " + now); WaveConfig wc; int numOfEnemies = 5, numOfHits = 1; double launchDelay = 0.5, fireDelay = 5; diff --git a/src/com/sagi/dayan/Games/Stage/SettingsMenuScene.java b/src/com/sagi/dayan/Games/Stage/SettingsMenuScene.java index 923aede..c9e985c 100644 --- a/src/com/sagi/dayan/Games/Stage/SettingsMenuScene.java +++ b/src/com/sagi/dayan/Games/Stage/SettingsMenuScene.java @@ -15,7 +15,8 @@ import com.sagi.dayan.Games.Utils.Utils; //import sun.audio.AudioStream; /** - * Created by sagi on 2/27/16. + * Settings menu - currently controls menu. + * not possible to change keys yet */ public class SettingsMenuScene extends Scene { private BufferedImage background; diff --git a/src/com/sagi/dayan/Games/Stage/SixthStage.java b/src/com/sagi/dayan/Games/Stage/SixthStage.java index dad4664..3edab0d 100644 --- a/src/com/sagi/dayan/Games/Stage/SixthStage.java +++ b/src/com/sagi/dayan/Games/Stage/SixthStage.java @@ -6,7 +6,8 @@ import com.sagi.dayan.Games.Utils.WaveConfig; import com.sagi.dayan.Games.Utils.WaveConfigs; /** - * Created by sagi on 3/19/16. + * Holds specific stage data + * like: number of waves, wave types, num of enemies in each wave, launch delay etc. */ public class SixthStage extends Level{ @@ -20,7 +21,6 @@ public class SixthStage extends Level{ @Override protected void launchWave(long now) { lastWaveTime = now; - System.out.println("New Wave!! " + currentWave + ", Time: " + now); WaveConfig wc; int numOfEnemies = 5, numOfHits = 1; double launchDelay = 0.5, fireDelay = 5; diff --git a/src/com/sagi/dayan/Games/Stage/Stage.java b/src/com/sagi/dayan/Games/Stage/Stage.java index 14cfa11..8c08379 100644 --- a/src/com/sagi/dayan/Games/Stage/Stage.java +++ b/src/com/sagi/dayan/Games/Stage/Stage.java @@ -8,7 +8,7 @@ import javax.swing.JPanel; import com.sagi.dayan.Games.Engine.GameEngine; /** - * Created by sagi on 2/8/16. + * represtent a specific game stage */ public class Stage extends JPanel implements Runnable{ diff --git a/src/com/sagi/dayan/Games/Stage/ThirdStage.java b/src/com/sagi/dayan/Games/Stage/ThirdStage.java index 46fc271..1e835b1 100644 --- a/src/com/sagi/dayan/Games/Stage/ThirdStage.java +++ b/src/com/sagi/dayan/Games/Stage/ThirdStage.java @@ -6,7 +6,8 @@ import com.sagi.dayan.Games.Utils.WaveConfig; import com.sagi.dayan.Games.Utils.WaveConfigs; /** - * Created by sagi on 3/19/16. + * Holds specific stage data + * like: number of waves, wave types, num of enemies in each wave, launch delay etc. */ public class ThirdStage extends Level{ @@ -20,7 +21,6 @@ public class ThirdStage extends Level{ @Override protected void launchWave(long now) { lastWaveTime = now; - System.out.println("New Wave!! " + currentWave + ", Time: " + now); WaveConfig wc; int numOfEnemies = 5, numOfHits = 1; double launchDelay = 0.5, fireDelay = 5; diff --git a/src/com/sagi/dayan/Games/Utils/WaveConfig.java b/src/com/sagi/dayan/Games/Utils/WaveConfig.java index fb1ac76..4ef0f05 100644 --- a/src/com/sagi/dayan/Games/Utils/WaveConfig.java +++ b/src/com/sagi/dayan/Games/Utils/WaveConfig.java @@ -1,7 +1,7 @@ package com.sagi.dayan.Games.Utils; /** - * Created by sagi on 3/18/16. + * this class configures the structure of a wave */ public class WaveConfig { protected int[] moveVector; diff --git a/src/com/sagi/dayan/Games/Utils/WaveConfigs.java b/src/com/sagi/dayan/Games/Utils/WaveConfigs.java index 43b4d5d..9605929 100644 --- a/src/com/sagi/dayan/Games/Utils/WaveConfigs.java +++ b/src/com/sagi/dayan/Games/Utils/WaveConfigs.java @@ -3,11 +3,10 @@ package com.sagi.dayan.Games.Utils; import java.util.Vector; /** - * Created by sagi on 3/18/16. + * this class configs settings and movement vector for different kinds of waves */ public class WaveConfigs { - public static final int DEMO = 0;//, UPPER_MIDDLE_LEFT=0, UPPER_MIDDLE_RIGHT=1; - //public static final int UPPER_LEFT = 2, UPPER_RIGHT=3; + public static final int DEMO = 0; Vector configs; public WaveConfigs(){ @@ -40,6 +39,7 @@ public class WaveConfigs { } + //return requested wave configuration public WaveConfig getWaveConfig(int config){ if (config < 0 || configs.size() <= config) throw new IllegalArgumentException("no such config...");