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;
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by sagi on 2/10/16.
|
* AnimatedSprite represents a sprite with animated img
|
||||||
*/
|
*/
|
||||||
public abstract class AnimatedSprite extends Sprite {
|
public abstract class AnimatedSprite extends Sprite {
|
||||||
protected Vector<Animation> animations;
|
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) {
|
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);
|
super(x, y, w, h, acc, imgName, angle, sWidth, sHeight);
|
||||||
animations = new Vector<>();
|
animations = new Vector<>();
|
||||||
|
//start first animation of set of animations
|
||||||
initFirstAnimation(imgName, numOfFirstFrames);
|
initFirstAnimation(imgName, numOfFirstFrames);
|
||||||
currentAnimation = 0;
|
currentAnimation = 0;
|
||||||
|
|
||||||
|
@ -27,6 +28,7 @@ public abstract class AnimatedSprite extends Sprite {
|
||||||
|
|
||||||
protected abstract void initFirstAnimation(String spriteSheet, int numOfFirstFrames);
|
protected abstract void initFirstAnimation(String spriteSheet, int numOfFirstFrames);
|
||||||
|
|
||||||
|
//draw each time the correct image of the animation
|
||||||
@Override
|
@Override
|
||||||
public void drawSprite(Graphics g, JPanel p) {
|
public void drawSprite(Graphics g, JPanel p) {
|
||||||
if(animations.size() == 0)
|
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));
|
g2d.rotate(Math.toRadians(angle), locX + (bImage.getWidth() / 2), locY + (bImage.getHeight() / 2));
|
||||||
g.drawImage(animations.get(currentAnimation).getCurrentFrame(), locX, locY, p);
|
g.drawImage(animations.get(currentAnimation).getCurrentFrame(), locX, locY, p);
|
||||||
g2d.rotate(-1 * Math.toRadians(angle), locX + (bImage.getWidth() / 2), locY + (bImage.getHeight() / 2));
|
g2d.rotate(-1 * Math.toRadians(angle), locX + (bImage.getWidth() / 2), locY + (bImage.getHeight() / 2));
|
||||||
|
|
||||||
|
//fix img if it goes beyond screen borders
|
||||||
if(screenLoop) {
|
if(screenLoop) {
|
||||||
drawScreenLoopFix(g, p);
|
drawScreenLoopFix(g, p);
|
||||||
outOfScreeFix();
|
outOfScreeFix();
|
||||||
|
@ -46,11 +50,13 @@ public abstract class AnimatedSprite extends Sprite {
|
||||||
bImage = animations.get(currentAnimation).getCurrentFrame();
|
bImage = animations.get(currentAnimation).getCurrentFrame();
|
||||||
super.drawScreenLoopFix(g,p);
|
super.drawScreenLoopFix(g,p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//gets current used frame from animation
|
||||||
public int getFrameNum(){
|
public int getFrameNum(){
|
||||||
return animations.get(currentAnimation).getFrameIndex();
|
return animations.get(currentAnimation).getFrameIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//decide which animation to play. go back to start if finished
|
||||||
public void setCurrentAnimation(int animation){
|
public void setCurrentAnimation(int animation){
|
||||||
if(animation < 0){
|
if(animation < 0){
|
||||||
throw new IllegalArgumentException("Animation index cant be negative");
|
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 {
|
protected class Animation {
|
||||||
|
|
||||||
private int totalLoopTime;
|
private int totalLoopTime;
|
||||||
|
@ -100,13 +107,18 @@ public abstract class AnimatedSprite extends Sprite {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//returns current played frame index
|
||||||
public int getFrameIndex() { return currentFrame;}
|
public int getFrameIndex() { return currentFrame;}
|
||||||
|
|
||||||
|
|
||||||
|
//add more frames if animation changed
|
||||||
private void addFrame(BufferedImage image, double frameLength) {
|
private void addFrame(BufferedImage image, double frameLength) {
|
||||||
frames.add(new AnimationFrame(image, totalLoopTime,frameLength));
|
frames.add(new AnimationFrame(image, totalLoopTime,frameLength));
|
||||||
totalLoopTime += frameLength;
|
totalLoopTime += frameLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//returns current played frame
|
||||||
public BufferedImage getCurrentFrame() {
|
public BufferedImage getCurrentFrame() {
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
long delta = now - startingTime;
|
long delta = now - startingTime;
|
||||||
|
@ -121,6 +133,7 @@ public abstract class AnimatedSprite extends Sprite {
|
||||||
return frames.get(currentFrame).getFrame();
|
return frames.get(currentFrame).getFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//represents a single frame from animation
|
||||||
protected class AnimationFrame {
|
protected class AnimationFrame {
|
||||||
private double startTime, endTime;
|
private double startTime, endTime;
|
||||||
private BufferedImage frame;
|
private BufferedImage frame;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.sagi.dayan.Games.Elements;
|
package com.sagi.dayan.Games.Elements;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by sagi on 2/20/16.
|
* Represents background for the game
|
||||||
*/
|
*/
|
||||||
public class Background extends Sprite {
|
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) {
|
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;
|
import com.sagi.dayan.Games.Elements.AnimatedSprite.Animation;
|
||||||
|
|
||||||
|
/*
|
||||||
|
represents a blast when player ship explodes
|
||||||
|
*/
|
||||||
public class Blast extends AnimatedSprite {
|
public class Blast extends AnimatedSprite {
|
||||||
|
|
||||||
protected boolean isDone;
|
protected boolean isDone;
|
||||||
|
@ -18,6 +21,7 @@ public class Blast extends AnimatedSprite {
|
||||||
animations.add(new Animation("explosion.png", 16, 500));
|
animations.add(new Animation("explosion.png", 16, 500));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//set done when finished iterating on all frames
|
||||||
@Override
|
@Override
|
||||||
public void update() {
|
public void update() {
|
||||||
System.out.println("curr: "+currentAnimation+", total: "+numOfFirstFrames);
|
System.out.println("curr: "+currentAnimation+", total: "+numOfFirstFrames);
|
||||||
|
|
|
@ -4,7 +4,7 @@ package com.sagi.dayan.Games.Elements;
|
||||||
import com.sagi.dayan.Games.Utils.Utils;
|
import com.sagi.dayan.Games.Utils.Utils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by sagi on 2/20/16.
|
* represents an enemy ship
|
||||||
*/
|
*/
|
||||||
public class EnemyShip extends AnimatedSprite {
|
public class EnemyShip extends AnimatedSprite {
|
||||||
protected int currentStep;
|
protected int currentStep;
|
||||||
|
@ -15,6 +15,7 @@ public class EnemyShip extends AnimatedSprite {
|
||||||
protected int hitsToDestroy;
|
protected int hitsToDestroy;
|
||||||
protected boolean isDone;
|
protected boolean isDone;
|
||||||
protected long startExploded;
|
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) {
|
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);
|
super(x, y, w, h, acc, imgName, angle, sWidth, sHeight, numOfFirstFrames);
|
||||||
this.fireDelay = fireDelay;
|
this.fireDelay = fireDelay;
|
||||||
|
@ -28,6 +29,7 @@ public class EnemyShip extends AnimatedSprite {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//add enemy ship and blast animation
|
||||||
@Override
|
@Override
|
||||||
protected void initFirstAnimation(String spriteSheet, int numOfFirstFrames) {
|
protected void initFirstAnimation(String spriteSheet, int numOfFirstFrames) {
|
||||||
if(imageName == "L1-ES2.png"){
|
if(imageName == "L1-ES2.png"){
|
||||||
|
@ -58,6 +60,7 @@ public class EnemyShip extends AnimatedSprite {
|
||||||
locX += acceleration * Math.cos(Math.toRadians(moveVector[currentStep]));
|
locX += acceleration * Math.cos(Math.toRadians(moveVector[currentStep]));
|
||||||
locY -= acceleration * -1* Math.sin(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() {
|
public void gotHit() {
|
||||||
hitsToDestroy--;
|
hitsToDestroy--;
|
||||||
if(hitsToDestroy == 0){
|
if(hitsToDestroy == 0){
|
||||||
|
@ -66,8 +69,8 @@ public class EnemyShip extends AnimatedSprite {
|
||||||
currentAnimation++;
|
currentAnimation++;
|
||||||
Utils.playSound("enemy_exp.wav");
|
Utils.playSound("enemy_exp.wav");
|
||||||
}
|
}
|
||||||
System.out.println("GOT HIT " + hitsToDestroy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDead() {
|
public boolean isDead() {
|
||||||
return hitsToDestroy <= 0;
|
return hitsToDestroy <= 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.sagi.dayan.Games.Elements;
|
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 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) {
|
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;
|
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 {
|
public class Missile extends AnimatedSprite {
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import java.awt.Graphics;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by sagi on 2/20/16.
|
* Represents a player ship
|
||||||
*/
|
*/
|
||||||
public class Player extends AnimatedSprite {
|
public class Player extends AnimatedSprite {
|
||||||
private final int NORMAL_ANIMATION = 0, RIGHT_ANIMATION = 1, LEFT_ANIMATION = 2, PADDING_BOTTOM = 35, MORTAL_DELAY = 3;
|
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;
|
isGameOver = gameOver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//when player revived - reset it to default position
|
||||||
public void resetPlayer(){
|
public void resetPlayer(){
|
||||||
locX = startX;
|
locX = startX;
|
||||||
locY = startY;
|
locY = startY;
|
||||||
|
@ -68,6 +69,7 @@ public class Player extends AnimatedSprite {
|
||||||
return isMortal;
|
return isMortal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//besides position update, updated whether ship can fire or not
|
||||||
@Override
|
@Override
|
||||||
public void update() {
|
public void update() {
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
|
@ -90,17 +92,14 @@ public class Player extends AnimatedSprite {
|
||||||
locY = pHeight - animations.get(currentAnimation).getCurrentFrame().getHeight() - PADDING_BOTTOM;
|
locY = pHeight - animations.get(currentAnimation).getCurrentFrame().getHeight() - PADDING_BOTTOM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isGameOver){
|
|
||||||
//System.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//set horizontal and vertical direction
|
||||||
public void sethDirection(int direction) {
|
public void sethDirection(int direction) {
|
||||||
this.hDirection = direction;
|
this.hDirection = direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setvDirection(int direction) {
|
public void setvDirection(int direction) {
|
||||||
this.vDirection = direction;
|
this.vDirection = direction;
|
||||||
if(direction != NORMAL_ANIMATION){
|
if(direction != NORMAL_ANIMATION){
|
||||||
|
@ -127,10 +126,13 @@ public class Player extends AnimatedSprite {
|
||||||
this.fireDelay = fireDelay;
|
this.fireDelay = fireDelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//update time since last fired
|
||||||
public void updateFireTime(){
|
public void updateFireTime(){
|
||||||
lastFired = System.currentTimeMillis();
|
lastFired = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//if player was dead dont draw (creates blinking effect)
|
||||||
@Override
|
@Override
|
||||||
public void drawSprite(Graphics g, JPanel p){
|
public void drawSprite(Graphics g, JPanel p){
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
|
|
|
@ -11,19 +11,20 @@ import com.sagi.dayan.Games.Stage.Level;
|
||||||
import com.sagi.dayan.Games.Utils.Utils;
|
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 {
|
public class Wave {
|
||||||
|
|
||||||
protected Level level;
|
protected Level level; //used to ask for a misslie to be created
|
||||||
protected int enemyMaxAmount, currentAmount, acc, startX, startY;
|
protected int enemyMaxAmount, currentAmount, hitsToDestroy, acc, startX, startY;
|
||||||
protected double stepDelay,fireDelay, launchDelay;
|
protected double stepDelay,fireDelay, launchDelay;
|
||||||
protected int[] moveVector;
|
protected int[] moveVector;
|
||||||
protected Vector<EnemyShip> enemies;
|
protected Vector<EnemyShip> enemies;
|
||||||
protected Vector<Missile> bullets;
|
protected Vector<Missile> bullets;
|
||||||
protected long lastLaunchTime;
|
protected long lastLaunchTime;
|
||||||
protected String imageName;
|
protected String imageName;
|
||||||
protected int hitsToDestroy;
|
|
||||||
protected Random r;
|
protected Random r;
|
||||||
protected boolean isShipOfTypeOne;
|
protected boolean isShipOfTypeOne;
|
||||||
|
|
||||||
|
@ -44,24 +45,30 @@ public class Wave {
|
||||||
this.lastLaunchTime = System.currentTimeMillis();
|
this.lastLaunchTime = System.currentTimeMillis();
|
||||||
this.hitsToDestroy = hitsToDestroy;
|
this.hitsToDestroy = hitsToDestroy;
|
||||||
this.r = new Random();
|
this.r = new Random();
|
||||||
|
|
||||||
|
//decides which ship img to use
|
||||||
int odds = r.nextInt(100);
|
int odds = r.nextInt(100);
|
||||||
isShipOfTypeOne = (odds > 60) ? true : false;
|
isShipOfTypeOne = (odds > 60) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void update(){
|
public void update(){
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
Vector <EnemyShip> enemiesToRemove = new Vector<>();
|
Vector <EnemyShip> enemiesToRemove = new Vector<>();
|
||||||
|
|
||||||
|
// Create (RANDOM) new enemy if enough time passed since last launch (launchDelay)
|
||||||
if(now - lastLaunchTime >= launchDelay * 1000 && currentAmount <= enemyMaxAmount){
|
if(now - lastLaunchTime >= launchDelay * 1000 && currentAmount <= enemyMaxAmount){
|
||||||
// Create (RANDOM) new enemy
|
//choose img
|
||||||
if(isShipOfTypeOne){
|
if(isShipOfTypeOne){
|
||||||
enemies.add(new EnemyShip(startX, startY, level.getStageHeight(), level.getStageHeight(), acc, imageName, 0, 15, 15, fireDelay, stepDelay, this, moveVector, 8, hitsToDestroy));
|
enemies.add(new EnemyShip(startX, startY, level.getStageHeight(), level.getStageHeight(), acc, imageName, 0, 15, 15, fireDelay, stepDelay, this, moveVector, 8, hitsToDestroy));
|
||||||
}else{
|
}else{
|
||||||
enemies.add(new EnemyShip(startX, startY, level.getStageHeight(), level.getStageHeight(), acc, "L1-ES2.png", 0, 15, 15, fireDelay, stepDelay, this, moveVector, 2, hitsToDestroy));
|
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");
|
Utils.playSound("enemy_enter.wav");
|
||||||
lastLaunchTime = now;
|
lastLaunchTime = now; //save new time
|
||||||
currentAmount++;
|
currentAmount++;
|
||||||
}
|
}
|
||||||
|
//update enemies & missiles, and remove the ones who are dead\OOS
|
||||||
for (int i = 0; i < enemies.size() ; i++){
|
for (int i = 0; i < enemies.size() ; i++){
|
||||||
enemies.get(i).update();
|
enemies.get(i).update();
|
||||||
if (enemies.get(i).isDone() || enemies.get(i).isOutOfScreen()) {
|
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){
|
public void render(Graphics g, JPanel p){
|
||||||
for (int i = 0; i < bullets.size() ; i++){
|
for (int i = 0; i < bullets.size() ; i++){
|
||||||
bullets.get(i).drawSprite(g, p);
|
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){
|
public void fireFromEnemy(EnemyShip e){
|
||||||
if(!e.isDead()) {
|
if(!e.isDead()) {
|
||||||
level.enemyFire(e.getCenterX(), (int) (e.getLocY() + e.getsHeight()), -(e.getAcceleration() + 2));
|
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() {
|
public Vector <EnemyShip> getEnemies() {
|
||||||
return enemies;
|
return enemies;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//used when an enemy gets hit to remove life
|
||||||
public void enemyHit(EnemyShip es) {
|
public void enemyHit(EnemyShip es) {
|
||||||
es.gotHit();
|
es.gotHit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//returns true if all enemy ships launched and died or OOS
|
||||||
public boolean isWaveOver() {
|
public boolean isWaveOver() {
|
||||||
return enemies.size() == 0 && currentAmount >= enemyMaxAmount;
|
return enemies.size() == 0 && currentAmount >= enemyMaxAmount;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,10 +23,14 @@ import com.sagi.dayan.Games.Utils.Utils;
|
||||||
import com.sagi.dayan.Games.Utils.WaveConfigs;
|
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 {
|
public class GameEngine {
|
||||||
private final int CREDIT_TIME = 10;
|
private final int CREDIT_TIME = 10, FULL_HEALTH = 100; //timeout for credits
|
||||||
public boolean gameOn , gameOver, isFirstGame;
|
public boolean gameOn , gameOver, isFirstGame; //flags to determine game state
|
||||||
private JFrame frame;
|
private JFrame frame;
|
||||||
private int pWidth, pHeight, numOfPlayers; //panel dimensions
|
private int pWidth, pHeight, numOfPlayers; //panel dimensions
|
||||||
private Random r;
|
private Random r;
|
||||||
|
@ -34,13 +38,14 @@ public class GameEngine {
|
||||||
private Scene scene;
|
private Scene scene;
|
||||||
private int p1CreditTime, p2CreditTime, creditTickTime = 1;
|
private int p1CreditTime, p2CreditTime, creditTickTime = 1;
|
||||||
public static final int PLAYER_WIDTH = 120, PLAYER_HEIGHT = 120;
|
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[] 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[] 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;
|
private int p1Lives, p2Lives, p1Health, p2Health, credits, p1Score, p2Score;
|
||||||
|
public int p1HighScore, p2HighScore;
|
||||||
|
|
||||||
private long lastP1CreditTick, lastP2CreditTick;
|
private long lastP1CreditTick, lastP2CreditTick;
|
||||||
|
|
||||||
|
@ -49,6 +54,8 @@ public class GameEngine {
|
||||||
private WaveConfigs waveConfigs;
|
private WaveConfigs waveConfigs;
|
||||||
private int currentLevel;
|
private int currentLevel;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public GameEngine(int width, int height, Stage stage){
|
public GameEngine(int width, int height, Stage stage){
|
||||||
p1HighScore = p2HighScore = 0;
|
p1HighScore = p2HighScore = 0;
|
||||||
this.isFirstGame = true;
|
this.isFirstGame = true;
|
||||||
|
@ -69,23 +76,20 @@ public class GameEngine {
|
||||||
gameFont = null;
|
gameFont = null;
|
||||||
}
|
}
|
||||||
this.waveConfigs = new WaveConfigs();
|
this.waveConfigs = new WaveConfigs();
|
||||||
startNewGame();
|
|
||||||
|
|
||||||
|
startNewGame(); //initialize a new game
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//reset player health to full health
|
||||||
private void resetPlayerHealth(int i){
|
private void resetPlayerHealth(int i){
|
||||||
if (i==0){
|
if (i==0){
|
||||||
p1Health = 100;
|
p1Health = FULL_HEALTH;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
p2Health = 100;
|
p2Health = FULL_HEALTH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* initialize and reset vars and timers to "new game" configuration.
|
* initialize and reset vars and timers to "new game" configuration.
|
||||||
|
@ -121,8 +125,6 @@ public class GameEngine {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns gameOver flag
|
* returns gameOver flag
|
||||||
* @return
|
* @return
|
||||||
|
@ -133,11 +135,8 @@ public class GameEngine {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update all sprites, including collision handling.
|
* Update all scenes
|
||||||
*/
|
*/
|
||||||
public void update(){
|
public void update(){
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
|
@ -160,14 +159,15 @@ public class GameEngine {
|
||||||
return scene.getSceneImage();
|
return scene.getSceneImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//initializes a new game
|
||||||
public void startGame(int numOfPlayers){
|
public void startGame(int numOfPlayers){
|
||||||
this.numOfPlayers = numOfPlayers;
|
this.numOfPlayers = numOfPlayers;
|
||||||
startNewGame();
|
startNewGame();
|
||||||
changeLevel();
|
changeLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//move to next level (scene) and attach listeners
|
||||||
public void changeLevel(){
|
public void changeLevel(){
|
||||||
System.out.println("current level: "+currentLevel);
|
|
||||||
currentLevel++;
|
currentLevel++;
|
||||||
stage.removeMouseListener(scene);
|
stage.removeMouseListener(scene);
|
||||||
stage.removeKeyListener(scene);
|
stage.removeKeyListener(scene);
|
||||||
|
@ -199,7 +199,7 @@ public class GameEngine {
|
||||||
stage.addMouseListener(scene);
|
stage.addMouseListener(scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//load controls menu
|
||||||
public void goToSettings() {
|
public void goToSettings() {
|
||||||
stage.removeMouseListener(scene);
|
stage.removeMouseListener(scene);
|
||||||
stage.removeKeyListener(scene);
|
stage.removeKeyListener(scene);
|
||||||
|
@ -251,10 +251,10 @@ public class GameEngine {
|
||||||
credits--;
|
credits--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//when a player uses a credit - reset health, lives and consume credit
|
||||||
public void revivePlayer(int i)
|
public void revivePlayer(int i)
|
||||||
{
|
{
|
||||||
useCredit();
|
useCredit();
|
||||||
|
|
||||||
if(i==0){
|
if(i==0){
|
||||||
p1Health=100;
|
p1Health=100;
|
||||||
p1Lives =3;
|
p1Lives =3;
|
||||||
|
@ -266,7 +266,7 @@ public class GameEngine {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//add score to the correct player
|
||||||
public void setScore(int i, int score)
|
public void setScore(int i, int score)
|
||||||
{
|
{
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
|
@ -275,6 +275,10 @@ public class GameEngine {
|
||||||
p2Score += score;
|
p2Score += score;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// if a player gets hit - consume health
|
||||||
|
//if health is 0 - consume life
|
||||||
public void setPlayerHealth(int i, int strike) {
|
public void setPlayerHealth(int i, int strike) {
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
p1Health += strike;
|
p1Health += strike;
|
||||||
|
@ -301,6 +305,7 @@ public class GameEngine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//go to main menu
|
||||||
public void goToMenu(){
|
public void goToMenu(){
|
||||||
stage.removeMouseListener(scene);
|
stage.removeMouseListener(scene);
|
||||||
stage.removeKeyListener(scene);
|
stage.removeKeyListener(scene);
|
||||||
|
|
|
@ -6,7 +6,8 @@ import com.sagi.dayan.Games.Utils.WaveConfig;
|
||||||
import com.sagi.dayan.Games.Utils.WaveConfigs;
|
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{
|
public class BlitzStage extends Level{
|
||||||
|
|
||||||
|
@ -20,7 +21,6 @@ public class BlitzStage extends Level{
|
||||||
@Override
|
@Override
|
||||||
protected void launchWave(long now) {
|
protected void launchWave(long now) {
|
||||||
lastWaveTime = now;
|
lastWaveTime = now;
|
||||||
System.out.println("New Wave!! " + currentWave + ", Time: " + now);
|
|
||||||
WaveConfig wc;
|
WaveConfig wc;
|
||||||
int numOfEnemies = 5, numOfHits = 1;
|
int numOfEnemies = 5, numOfHits = 1;
|
||||||
double launchDelay = 0.5, fireDelay = 5;
|
double launchDelay = 0.5, fireDelay = 5;
|
||||||
|
|
|
@ -6,7 +6,8 @@ import com.sagi.dayan.Games.Utils.WaveConfig;
|
||||||
import com.sagi.dayan.Games.Utils.WaveConfigs;
|
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{
|
public class FifthStage extends Level{
|
||||||
|
|
||||||
|
@ -20,7 +21,6 @@ public class FifthStage extends Level{
|
||||||
@Override
|
@Override
|
||||||
protected void launchWave(long now) {
|
protected void launchWave(long now) {
|
||||||
lastWaveTime = now;
|
lastWaveTime = now;
|
||||||
System.out.println("New Wave!! " + currentWave + ", Time: " + now);
|
|
||||||
WaveConfig wc;
|
WaveConfig wc;
|
||||||
int numOfEnemies = 5, numOfHits = 1;
|
int numOfEnemies = 5, numOfHits = 1;
|
||||||
double launchDelay = 0.5, fireDelay = 5;
|
double launchDelay = 0.5, fireDelay = 5;
|
||||||
|
|
|
@ -6,7 +6,8 @@ import com.sagi.dayan.Games.Utils.WaveConfig;
|
||||||
import com.sagi.dayan.Games.Utils.WaveConfigs;
|
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{
|
public class FirstStage extends Level{
|
||||||
|
|
||||||
|
@ -20,7 +21,6 @@ public class FirstStage extends Level{
|
||||||
@Override
|
@Override
|
||||||
protected void launchWave(long now) {
|
protected void launchWave(long now) {
|
||||||
lastWaveTime = now;
|
lastWaveTime = now;
|
||||||
System.out.println("New Wave!! " + currentWave + ", Time: " + now);
|
|
||||||
WaveConfig wc;
|
WaveConfig wc;
|
||||||
int numOfEnemies = 5, numOfHits = 1;
|
int numOfEnemies = 5, numOfHits = 1;
|
||||||
double launchDelay = 0.5, fireDelay = 5;
|
double launchDelay = 0.5, fireDelay = 5;
|
||||||
|
|
|
@ -6,7 +6,8 @@ import com.sagi.dayan.Games.Utils.WaveConfig;
|
||||||
import com.sagi.dayan.Games.Utils.WaveConfigs;
|
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{
|
public class FourthStage extends Level{
|
||||||
|
|
||||||
|
@ -20,7 +21,6 @@ public class FourthStage extends Level{
|
||||||
@Override
|
@Override
|
||||||
protected void launchWave(long now) {
|
protected void launchWave(long now) {
|
||||||
lastWaveTime = now;
|
lastWaveTime = now;
|
||||||
System.out.println("New Wave!! " + currentWave + ", Time: " + now);
|
|
||||||
WaveConfig wc;
|
WaveConfig wc;
|
||||||
int numOfEnemies = 5, numOfHits = 1;
|
int numOfEnemies = 5, numOfHits = 1;
|
||||||
double launchDelay = 0.5, fireDelay = 5;
|
double launchDelay = 0.5, fireDelay = 5;
|
||||||
|
|
|
@ -26,38 +26,40 @@ import com.sagi.dayan.Games.Engine.GameEngine;
|
||||||
import com.sagi.dayan.Games.Utils.Utils;
|
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 {
|
public abstract class Level extends Scene {
|
||||||
protected final double PRESS_START_PULE = 0.3;
|
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 Vector<Player> players;
|
||||||
protected int p1Speed = 10;
|
|
||||||
protected Vector<Missile> p1Missiles, p2Missiles, enemyMissiles;
|
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<Wave> waves;
|
||||||
protected Vector<Blast> blasts;
|
protected Vector<Blast> blasts;
|
||||||
protected int numOfPlayers;
|
protected Background bg;
|
||||||
|
protected int[] yAxisStartingAnimation, waveDelay;
|
||||||
|
|
||||||
|
|
||||||
protected Map<Integer, Boolean> keys;
|
protected Map<Integer, Boolean> keys;
|
||||||
protected String title;
|
protected String title;
|
||||||
protected JLabel stageTitle;
|
protected JLabel stageTitle;
|
||||||
protected long lastWaveTime, lastPulseTime;
|
protected long lastWaveTime, lastPulseTime;
|
||||||
protected int numOfWaves;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Level(int width, int height, int numOfPlayers, GameEngine engine, String stageTitle, int[] waveDelay){
|
public Level(int width, int height, int numOfPlayers, GameEngine engine, String stageTitle, int[] waveDelay){
|
||||||
super(width, height, engine);
|
super(width, height, engine);
|
||||||
|
//initialize vectors
|
||||||
players = new Vector<>();
|
players = new Vector<>();
|
||||||
p1Missiles = new Vector<>();
|
p1Missiles = new Vector<>();
|
||||||
p2Missiles = new Vector<>();
|
p2Missiles = new Vector<>();
|
||||||
blasts = new Vector<Blast>();
|
blasts = new Vector<>();
|
||||||
enemyMissiles = new Vector<>();
|
enemyMissiles = new Vector<>();
|
||||||
|
|
||||||
|
//save additional information
|
||||||
this.waveDelay = waveDelay;
|
this.waveDelay = waveDelay;
|
||||||
this.lastWaveTime = System.currentTimeMillis();
|
this.lastWaveTime = System.currentTimeMillis();
|
||||||
this.currentWave = 0;
|
this.currentWave = 0;
|
||||||
|
@ -73,6 +75,8 @@ public abstract class Level extends Scene {
|
||||||
this.title = stageTitle;
|
this.title = stageTitle;
|
||||||
this.stageTitle = new JLabel(this.title);
|
this.stageTitle = new JLabel(this.title);
|
||||||
|
|
||||||
|
|
||||||
|
//create requierd amount of players
|
||||||
if(numOfPlayers == 1) {
|
if(numOfPlayers == 1) {
|
||||||
players.add(new Player((width / 2) + (GameEngine.PLAYER_WIDTH / 2), yAxisStartingAnimation[startingAnimationIndex],
|
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));
|
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();
|
setupKeys();
|
||||||
Utils.playSound("jetSound.wav");
|
Utils.playSound("jetSound.wav");
|
||||||
lastPulseTime = System.currentTimeMillis();
|
lastPulseTime = System.currentTimeMillis();
|
||||||
toDrawStart = true;
|
toDrawStart = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//initialize player 1 & 2 keys
|
||||||
private void setupKeys() {
|
private void setupKeys() {
|
||||||
int[] p1 = engine.getP1Controlles();
|
int[] p1 = engine.getP1Controlles();
|
||||||
for(int i = 0 ; i < p1.length ; i++){
|
for(int i = 0 ; i < p1.length ; i++){
|
||||||
|
@ -107,15 +113,18 @@ public abstract class Level extends Scene {
|
||||||
public void update() {
|
public void update() {
|
||||||
bg.update();
|
bg.update();
|
||||||
movePlayers();
|
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<>();
|
Vector<Blast> blastTRM = new Vector<>();
|
||||||
|
|
||||||
|
//check if enough time has passed and a new wave needs to be launched
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
// if(currentWave < waveDelay.length && now - lastWaveTime >= waveDelay[currentWave] * 1000){
|
|
||||||
if(currentWave < numOfWaves && now - lastWaveTime >= waveDelay[currentWave] * 1000){
|
if(currentWave < numOfWaves && now - lastWaveTime >= waveDelay[currentWave] * 1000){
|
||||||
launchWave(now);
|
launchWave(now);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if still in new game start animation - advance animation
|
||||||
if(startingAnimationIndex < 3 && !isStarted){
|
if(startingAnimationIndex < 3 && !isStarted){
|
||||||
if(startingAnimationIndex == 0){
|
if(startingAnimationIndex == 0){
|
||||||
startingAnimationIndex++;
|
startingAnimationIndex++;
|
||||||
|
@ -136,7 +145,10 @@ public abstract class Level extends Scene {
|
||||||
startingAnimationIndex++;
|
startingAnimationIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
}
|
||||||
|
//if finished game start animation - update players, missiles, enemy waves
|
||||||
|
//if waves are done - remove them
|
||||||
|
else{
|
||||||
isStarted = true;
|
isStarted = true;
|
||||||
for(int i = 0 ; i < players.size() ; i++){
|
for(int i = 0 ; i < players.size() ; i++){
|
||||||
players.get(i).update();
|
players.get(i).update();
|
||||||
|
@ -155,40 +167,43 @@ public abstract class Level extends Scene {
|
||||||
for(int i = 0 ; i < waves.size() ; i++){
|
for(int i = 0 ; i < waves.size() ; i++){
|
||||||
waves.get(i).update();
|
waves.get(i).update();
|
||||||
if(waves.get(i).isWaveOver()) {
|
if(waves.get(i).isWaveOver()) {
|
||||||
System.out.println("in remove");
|
|
||||||
wavesToRemove.add(waves.get(i));
|
wavesToRemove.add(waves.get(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
waves.removeAll(wavesToRemove);
|
waves.removeAll(wavesToRemove);
|
||||||
|
|
||||||
|
//check and set high score
|
||||||
if(engine.getP1Score() > engine.getP1HighScore())
|
if(engine.getP1Score() > engine.getP1HighScore())
|
||||||
engine.setP1HighScore(engine.getP1Score());
|
engine.setP1HighScore(engine.getP1Score());
|
||||||
if(engine.getP2Score() > engine.getP2HighScore())
|
if(engine.getP2Score() > engine.getP2HighScore())
|
||||||
engine.setP2HighScore(engine.getP2Score());
|
engine.setP2HighScore(engine.getP2Score());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//check all collisions
|
||||||
checkCollision();
|
checkCollision();
|
||||||
engine.setGameOver(isGameOver());
|
engine.setGameOver(isGameOver());
|
||||||
|
|
||||||
|
//if all waves are done switch stage
|
||||||
if(currentWave >= numOfWaves && waves.size()==0)
|
if(currentWave >= numOfWaves && waves.size()==0)
|
||||||
{
|
{
|
||||||
System.out.println("Done");
|
|
||||||
engine.changeLevel();
|
engine.changeLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//remove finished blasts and update existing
|
||||||
for(int i =0; i<blasts.size();i++){
|
for(int i =0; i<blasts.size();i++){
|
||||||
if (blasts.get(i).isDone()){
|
if (blasts.get(i).isDone()){
|
||||||
System.out.println("removing blast");
|
|
||||||
blastTRM.add(blasts.get(i));
|
blastTRM.add(blasts.get(i));
|
||||||
}
|
}
|
||||||
blasts.get(i).update();
|
blasts.get(i).update();
|
||||||
}
|
}
|
||||||
|
|
||||||
blasts.removeAll(blastTRM);
|
blasts.removeAll(blastTRM);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void launchWave(long time);
|
protected abstract void launchWave(long time);
|
||||||
|
|
||||||
|
//determine if game is over according to player 1 & 2
|
||||||
private boolean isGameOver(){
|
private boolean isGameOver(){
|
||||||
if(numOfPlayers == 1) {
|
if(numOfPlayers == 1) {
|
||||||
return players.get(0).isGameOver();
|
return players.get(0).isGameOver();
|
||||||
|
@ -197,6 +212,7 @@ public abstract class Level extends Scene {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//set player 1 & 2 movement direction
|
||||||
private void movePlayers() {
|
private void movePlayers() {
|
||||||
/**
|
/**
|
||||||
* Player 1 Movement:
|
* Player 1 Movement:
|
||||||
|
@ -275,6 +291,7 @@ public abstract class Level extends Scene {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//render all sprites and elements
|
||||||
@Override
|
@Override
|
||||||
public void render(JPanel p) {
|
public void render(JPanel p) {
|
||||||
sceneImage = new BufferedImage(this.stageWidth, this.stageHeight, Image.SCALE_FAST);
|
sceneImage = new BufferedImage(this.stageWidth, this.stageHeight, Image.SCALE_FAST);
|
||||||
|
@ -284,6 +301,7 @@ public abstract class Level extends Scene {
|
||||||
Color c = g.getColor();
|
Color c = g.getColor();
|
||||||
Font f = engine.getGameFont();
|
Font f = engine.getGameFont();
|
||||||
|
|
||||||
|
//if game didn't start yet - print stage title
|
||||||
if(!isStarted){
|
if(!isStarted){
|
||||||
if(f == null) {
|
if(f == null) {
|
||||||
f = g.getFont();
|
f = g.getFont();
|
||||||
|
@ -292,7 +310,6 @@ public abstract class Level extends Scene {
|
||||||
g.setColor(Color.DARK_GRAY);
|
g.setColor(Color.DARK_GRAY);
|
||||||
g.setFont(f);
|
g.setFont(f);
|
||||||
|
|
||||||
|
|
||||||
// Get the FontMetrics
|
// Get the FontMetrics
|
||||||
FontMetrics metrics = g.getFontMetrics(f);
|
FontMetrics metrics = g.getFontMetrics(f);
|
||||||
// Determine the X coordinate for the text
|
// 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();
|
int y = ((stageHeight - metrics.getHeight()) / 2) - metrics.getAscent();
|
||||||
g.drawString(this.title, x, y);
|
g.drawString(this.title, x, y);
|
||||||
g.setColor(c);
|
g.setColor(c);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (isGameOver())
|
if (isGameOver())
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
System.in.read();
|
System.in.read();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -341,8 +355,7 @@ public abstract class Level extends Scene {
|
||||||
g.drawString("Credits: "+ engine.getCredits(), stageWidth/2, 30);
|
g.drawString("Credits: "+ engine.getCredits(), stageWidth/2, 30);
|
||||||
|
|
||||||
|
|
||||||
|
//draw all missiles
|
||||||
|
|
||||||
for(int i = 0 ; i < p1Missiles.size() ; i++){
|
for(int i = 0 ; i < p1Missiles.size() ; i++){
|
||||||
p1Missiles.get(i).drawSprite(g,p);
|
p1Missiles.get(i).drawSprite(g,p);
|
||||||
}
|
}
|
||||||
|
@ -352,6 +365,8 @@ public abstract class Level extends Scene {
|
||||||
for(int i = 0 ; i < enemyMissiles.size() ; i++){
|
for(int i = 0 ; i < enemyMissiles.size() ; i++){
|
||||||
enemyMissiles.get(i).drawSprite(g,p);
|
enemyMissiles.get(i).drawSprite(g,p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//draw player 1 & 2 details (score, health & lives)
|
||||||
for(int i = 0 ; i < players.size() ; i++){
|
for(int i = 0 ; i < players.size() ; i++){
|
||||||
if(i == 0){
|
if(i == 0){
|
||||||
if(engine.getP1Health() > 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++){
|
for(int i = 0 ; i < waves.size() ; i++){
|
||||||
waves.get(i).render(g,p);
|
waves.get(i).render(g,p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//render all blasts
|
||||||
for(int i =0; i<blasts.size();i++){
|
for(int i =0; i<blasts.size();i++){
|
||||||
blasts.get(i).drawSprite(g, p);
|
blasts.get(i).drawSprite(g, p);
|
||||||
}
|
}
|
||||||
|
@ -428,7 +446,11 @@ public abstract class Level extends Scene {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//check all possible collisions
|
||||||
public void checkCollision() {
|
public void checkCollision() {
|
||||||
|
|
||||||
|
//vectors to store objects that needs to be removed
|
||||||
Vector<Missile> p1MTR, p2MTR, eMTR;
|
Vector<Missile> p1MTR, p2MTR, eMTR;
|
||||||
eMTR = new Vector<>();
|
eMTR = new Vector<>();
|
||||||
p1MTR = new Vector<>();
|
p1MTR = new Vector<>();
|
||||||
|
@ -459,12 +481,12 @@ public abstract class Level extends Scene {
|
||||||
//player vs. enemy missile
|
//player vs. enemy missile
|
||||||
for (int j = 0; j < enemyMissiles.size(); j++) {
|
for (int j = 0; j < enemyMissiles.size(); j++) {
|
||||||
if(CollisionUtil.collidesWith(players.get(i),enemyMissiles.get(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);
|
playerHit(i);
|
||||||
if(playerIsAlive(i)) {
|
if(playerIsAlive(i)) {
|
||||||
eMTR.add(enemyMissiles.get(j));
|
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++) {
|
for (int k = 0; k < waves.get(j).getEnemies().size(); k++) {
|
||||||
if (CollisionUtil.collidesWith(waves.get(j).getEnemies().get(k), players.get(i))) {
|
if (CollisionUtil.collidesWith(waves.get(j).getEnemies().get(k), players.get(i))) {
|
||||||
if(!waves.get(j).getEnemies().get(k).isDead()){
|
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);
|
playerHit(i);
|
||||||
}
|
}
|
||||||
if(playerIsAlive(i)) {
|
if(playerIsAlive(i)) {
|
||||||
waves.get(j).enemyHit(waves.get(j).getEnemies().get(k));
|
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
|
//player 1 missile vs. enemy
|
||||||
if(i == 0){
|
if(i == 0){
|
||||||
for(int m = 0 ; m < p1Missiles.size() ; m++){
|
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 {
|
else {
|
||||||
for(int m = 0 ; m < p2Missiles.size() ; m++){
|
for(int m = 0 ; m < p2Missiles.size() ; m++){
|
||||||
for (int j = 0; j < waves.size(); j++) {
|
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);
|
p1Missiles.removeAll(p1MTR);
|
||||||
p2Missiles.removeAll(p2MTR);
|
p2Missiles.removeAll(p2MTR);
|
||||||
enemyMissiles.removeAll(eMTR);
|
enemyMissiles.removeAll(eMTR);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//checks if player is alive
|
||||||
protected boolean playerIsAlive(int i){
|
protected boolean playerIsAlive(int i){
|
||||||
if(i == 0){
|
if(i == 0){
|
||||||
return !(engine.getP1Lives() <= 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){
|
protected void playerHit(int i){
|
||||||
if(players.get(i).isMortal()){
|
if(players.get(i).isMortal()){
|
||||||
Utils.playSound((i == 0) ? "player_1_hit.wav" : "player_2_hit.wav");
|
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) {
|
public void enemyFire(int x, int y, int acc) {
|
||||||
enemyMissiles.add(new Missile(x, y,getStageWidth(),getStageHeight(), acc,"E1-Fire.png", 15));
|
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;
|
import com.sagi.dayan.Games.Utils.Utils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by sagi on 2/24/16.
|
* represent the main menu scene.
|
||||||
*/
|
*/
|
||||||
public class MainMenuScene extends Scene {
|
public class MainMenuScene extends Scene {
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@ public class MainMenuScene extends Scene {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//render all objects and players high scores
|
||||||
@Override
|
@Override
|
||||||
public void render(JPanel p) {
|
public void render(JPanel p) {
|
||||||
sceneImage = new BufferedImage(this.stageWidth, this.stageHeight, Image.SCALE_FAST);
|
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
|
@Override
|
||||||
public void keyPressed(KeyEvent keyEvent) {
|
public void keyPressed(KeyEvent keyEvent) {
|
||||||
switch (keyEvent.getKeyCode()){
|
switch (keyEvent.getKeyCode()){
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.sagi.dayan.Games.Stage;
|
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;
|
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 abstract class Scene extends MouseAdapter implements KeyListener{
|
||||||
|
|
||||||
public int getStageWidth() {
|
|
||||||
return stageWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getStageHeight() {
|
|
||||||
return stageHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected int stageWidth, stageHeight;
|
protected int stageWidth, stageHeight;
|
||||||
protected BufferedImage sceneImage;
|
protected BufferedImage sceneImage;
|
||||||
protected GameEngine engine;
|
protected GameEngine engine;
|
||||||
|
@ -32,6 +24,14 @@ public abstract class Scene extends MouseAdapter implements KeyListener{
|
||||||
this.engine = engine;
|
this.engine = engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//get dimentions
|
||||||
|
public int getStageWidth() {
|
||||||
|
return stageWidth;
|
||||||
|
}
|
||||||
|
public int getStageHeight() {
|
||||||
|
return stageHeight;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract void update ();
|
public abstract void update ();
|
||||||
|
|
||||||
public abstract void render(JPanel p);
|
public abstract void render(JPanel p);
|
||||||
|
|
|
@ -6,7 +6,8 @@ import com.sagi.dayan.Games.Utils.WaveConfig;
|
||||||
import com.sagi.dayan.Games.Utils.WaveConfigs;
|
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{
|
public class SecondStage extends Level{
|
||||||
|
|
||||||
|
@ -20,7 +21,6 @@ public class SecondStage extends Level{
|
||||||
@Override
|
@Override
|
||||||
protected void launchWave(long now) {
|
protected void launchWave(long now) {
|
||||||
lastWaveTime = now;
|
lastWaveTime = now;
|
||||||
System.out.println("New Wave!! " + currentWave + ", Time: " + now);
|
|
||||||
WaveConfig wc;
|
WaveConfig wc;
|
||||||
int numOfEnemies = 5, numOfHits = 1;
|
int numOfEnemies = 5, numOfHits = 1;
|
||||||
double launchDelay = 0.5, fireDelay = 5;
|
double launchDelay = 0.5, fireDelay = 5;
|
||||||
|
|
|
@ -15,7 +15,8 @@ import com.sagi.dayan.Games.Utils.Utils;
|
||||||
//import sun.audio.AudioStream;
|
//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 {
|
public class SettingsMenuScene extends Scene {
|
||||||
private BufferedImage background;
|
private BufferedImage background;
|
||||||
|
|
|
@ -6,7 +6,8 @@ import com.sagi.dayan.Games.Utils.WaveConfig;
|
||||||
import com.sagi.dayan.Games.Utils.WaveConfigs;
|
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{
|
public class SixthStage extends Level{
|
||||||
|
|
||||||
|
@ -20,7 +21,6 @@ public class SixthStage extends Level{
|
||||||
@Override
|
@Override
|
||||||
protected void launchWave(long now) {
|
protected void launchWave(long now) {
|
||||||
lastWaveTime = now;
|
lastWaveTime = now;
|
||||||
System.out.println("New Wave!! " + currentWave + ", Time: " + now);
|
|
||||||
WaveConfig wc;
|
WaveConfig wc;
|
||||||
int numOfEnemies = 5, numOfHits = 1;
|
int numOfEnemies = 5, numOfHits = 1;
|
||||||
double launchDelay = 0.5, fireDelay = 5;
|
double launchDelay = 0.5, fireDelay = 5;
|
||||||
|
|
|
@ -8,7 +8,7 @@ import javax.swing.JPanel;
|
||||||
import com.sagi.dayan.Games.Engine.GameEngine;
|
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{
|
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;
|
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{
|
public class ThirdStage extends Level{
|
||||||
|
|
||||||
|
@ -20,7 +21,6 @@ public class ThirdStage extends Level{
|
||||||
@Override
|
@Override
|
||||||
protected void launchWave(long now) {
|
protected void launchWave(long now) {
|
||||||
lastWaveTime = now;
|
lastWaveTime = now;
|
||||||
System.out.println("New Wave!! " + currentWave + ", Time: " + now);
|
|
||||||
WaveConfig wc;
|
WaveConfig wc;
|
||||||
int numOfEnemies = 5, numOfHits = 1;
|
int numOfEnemies = 5, numOfHits = 1;
|
||||||
double launchDelay = 0.5, fireDelay = 5;
|
double launchDelay = 0.5, fireDelay = 5;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.sagi.dayan.Games.Utils;
|
package com.sagi.dayan.Games.Utils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by sagi on 3/18/16.
|
* this class configures the structure of a wave
|
||||||
*/
|
*/
|
||||||
public class WaveConfig {
|
public class WaveConfig {
|
||||||
protected int[] moveVector;
|
protected int[] moveVector;
|
||||||
|
|
|
@ -3,11 +3,10 @@ package com.sagi.dayan.Games.Utils;
|
||||||
import java.util.Vector;
|
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 class WaveConfigs {
|
||||||
public static final int DEMO = 0;//, UPPER_MIDDLE_LEFT=0, UPPER_MIDDLE_RIGHT=1;
|
public static final int DEMO = 0;
|
||||||
//public static final int UPPER_LEFT = 2, UPPER_RIGHT=3;
|
|
||||||
Vector<WaveConfig> configs;
|
Vector<WaveConfig> configs;
|
||||||
|
|
||||||
public WaveConfigs(){
|
public WaveConfigs(){
|
||||||
|
@ -40,6 +39,7 @@ public class WaveConfigs {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//return requested wave configuration
|
||||||
public WaveConfig getWaveConfig(int config){
|
public WaveConfig getWaveConfig(int config){
|
||||||
if (config < 0 || configs.size() <= config)
|
if (config < 0 || configs.size() <= config)
|
||||||
throw new IllegalArgumentException("no such config...");
|
throw new IllegalArgumentException("no such config...");
|
||||||
|
|
Loading…
Reference in a new issue