Merge branch 'master' of https://github.com/aranzaiger/Far-Out into aran
This commit is contained in:
commit
72ba8d3ed3
23 changed files with 171 additions and 103 deletions
|
@ -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<Animation> 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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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<EnemyShip> enemies;
|
||||
protected Vector<Missile> 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 <EnemyShip> 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 <EnemyShip> 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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -26,38 +26,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<Player> players;
|
||||
protected int p1Speed = 10;
|
||||
protected Vector<Missile> p1Missiles, p2Missiles, enemyMissiles;
|
||||
protected Background bg;
|
||||
protected int[] waveDelay;
|
||||
protected int currentWave;
|
||||
protected int[] yAxisStartingAnimation;
|
||||
protected int startingAnimationIndex;
|
||||
protected boolean isStarted;
|
||||
protected Vector<Wave> waves;
|
||||
protected Vector<Blast> blasts;
|
||||
protected int numOfPlayers;
|
||||
protected Background bg;
|
||||
protected int[] yAxisStartingAnimation, waveDelay;
|
||||
|
||||
|
||||
protected Map<Integer, Boolean> 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<Blast>();
|
||||
blasts = new Vector<>();
|
||||
enemyMissiles = new Vector<>();
|
||||
|
||||
//save additional information
|
||||
this.waveDelay = waveDelay;
|
||||
this.lastWaveTime = System.currentTimeMillis();
|
||||
this.currentWave = 0;
|
||||
|
@ -73,6 +75,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));
|
||||
|
@ -84,12 +88,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++){
|
||||
|
@ -107,15 +113,18 @@ public abstract class Level extends Scene {
|
|||
public void update() {
|
||||
bg.update();
|
||||
movePlayers();
|
||||
Vector <Wave> wavesToRemove = new Vector<>();
|
||||
|
||||
//vectors to hold objects that needs to be removed
|
||||
Vector<Wave> wavesToRemove = new Vector<>();
|
||||
Vector<Blast> 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++;
|
||||
|
@ -136,7 +145,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();
|
||||
|
@ -155,40 +167,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<blasts.size();i++){
|
||||
if (blasts.get(i).isDone()){
|
||||
System.out.println("removing blast");
|
||||
blastTRM.add(blasts.get(i));
|
||||
}
|
||||
blasts.get(i).update();
|
||||
}
|
||||
|
||||
blasts.removeAll(blastTRM);
|
||||
|
||||
}
|
||||
|
||||
protected abstract void launchWave(long time);
|
||||
|
||||
//determine if game is over according to player 1 & 2
|
||||
private boolean isGameOver(){
|
||||
if(numOfPlayers == 1) {
|
||||
return players.get(0).isGameOver();
|
||||
|
@ -197,6 +212,7 @@ public abstract class Level extends Scene {
|
|||
}
|
||||
}
|
||||
|
||||
//set player 1 & 2 movement direction
|
||||
private void movePlayers() {
|
||||
/**
|
||||
* Player 1 Movement:
|
||||
|
@ -275,6 +291,7 @@ public abstract class Level extends Scene {
|
|||
}
|
||||
}
|
||||
|
||||
//render all sprites and elements
|
||||
@Override
|
||||
public void render(JPanel p) {
|
||||
sceneImage = new BufferedImage(this.stageWidth, this.stageHeight, Image.SCALE_FAST);
|
||||
|
@ -284,6 +301,7 @@ public abstract class Level extends Scene {
|
|||
Color c = g.getColor();
|
||||
Font f = engine.getGameFont();
|
||||
|
||||
//if game didn't start yet - print stage title
|
||||
if(!isStarted){
|
||||
if(f == null) {
|
||||
f = g.getFont();
|
||||
|
@ -292,7 +310,6 @@ public abstract class Level extends Scene {
|
|||
g.setColor(Color.DARK_GRAY);
|
||||
g.setFont(f);
|
||||
|
||||
|
||||
// Get the FontMetrics
|
||||
FontMetrics metrics = g.getFontMetrics(f);
|
||||
// Determine the X coordinate for the text
|
||||
|
@ -301,16 +318,13 @@ public abstract class Level extends Scene {
|
|||
int y = ((stageHeight - metrics.getHeight()) / 2) - metrics.getAscent();
|
||||
g.drawString(this.title, x, y);
|
||||
g.setColor(c);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (isGameOver())
|
||||
{
|
||||
try {
|
||||
System.in.read();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
@ -341,8 +355,7 @@ public abstract class Level extends Scene {
|
|||
g.drawString("Credits: "+ engine.getCredits(), stageWidth/2, 30);
|
||||
|
||||
|
||||
|
||||
|
||||
//draw all missiles
|
||||
for(int i = 0 ; i < p1Missiles.size() ; i++){
|
||||
p1Missiles.get(i).drawSprite(g,p);
|
||||
}
|
||||
|
@ -352,6 +365,8 @@ public abstract class Level extends Scene {
|
|||
for(int i = 0 ; i < enemyMissiles.size() ; i++){
|
||||
enemyMissiles.get(i).drawSprite(g,p);
|
||||
}
|
||||
|
||||
//draw player 1 & 2 details (score, health & lives)
|
||||
for(int i = 0 ; i < players.size() ; i++){
|
||||
if(i == 0){
|
||||
if(engine.getP1Health() > 0){
|
||||
|
@ -379,10 +394,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<blasts.size();i++){
|
||||
blasts.get(i).drawSprite(g, p);
|
||||
}
|
||||
|
@ -428,7 +446,11 @@ public abstract class Level extends Scene {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//check all possible collisions
|
||||
public void checkCollision() {
|
||||
|
||||
//vectors to store objects that needs to be removed
|
||||
Vector<Missile> p1MTR, p2MTR, eMTR;
|
||||
eMTR = new Vector<>();
|
||||
p1MTR = new Vector<>();
|
||||
|
@ -459,12 +481,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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -475,18 +497,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++){
|
||||
|
@ -505,7 +528,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++) {
|
||||
|
@ -525,14 +548,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);
|
||||
|
@ -541,6 +564,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");
|
||||
|
@ -557,6 +581,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));
|
||||
}
|
||||
|
|
|
@ -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()){
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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{
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<WaveConfig> 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...");
|
||||
|
|
Loading…
Reference in a new issue