Merge remote-tracking branch 'aran/master'

This commit is contained in:
Sagi Dayan 2016-03-20 23:29:44 +02:00
commit 8b3b837862
23 changed files with 171 additions and 103 deletions

View file

@ -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();
@ -47,10 +51,12 @@ public abstract class AnimatedSprite extends Sprite {
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;

View file

@ -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) {

View file

@ -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);

View file

@ -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;
}

View file

@ -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) {

View file

@ -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 {

View file

@ -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();

View file

@ -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;
}

View file

@ -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,24 +76,21 @@ 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);

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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();
//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));
}

View file

@ -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()){

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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{

View file

@ -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;

View file

@ -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;

View file

@ -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...");