250 lines
5.3 KiB
Java
250 lines
5.3 KiB
Java
package Engine;
|
|
|
|
import Sprites.*;
|
|
|
|
import javax.swing.*;
|
|
import java.applet.Applet;
|
|
import java.applet.AudioClip;
|
|
import java.awt.*;
|
|
import java.awt.event.*;
|
|
import java.awt.image.BufferedImage;
|
|
import java.net.URL;
|
|
import java.util.Random;
|
|
import java.util.Vector;
|
|
|
|
/**
|
|
* Created by sagi on 12/18/15.
|
|
*/
|
|
|
|
|
|
|
|
public class GameEngine extends MouseAdapter {
|
|
private final int PIPE_ACC = 10, PIPE_WIDTH = 90;
|
|
public boolean gameOn , gameOver, isFirstGame, canScore;
|
|
private Bird bird;
|
|
private Vector<Sprite> pipes; //will save all laser shots and asteroids which are currently on the screen.
|
|
private int pWidth, pHeight; //panel dimensions
|
|
private Timer pipeTimer;
|
|
private Random r;
|
|
private int score;
|
|
private BufferedImage sceneImage;
|
|
|
|
private Vector<SideScollerBackground> backgrounds;
|
|
private Vector<AudioClip> successSounds;
|
|
|
|
private AudioClip themeAudioClip;
|
|
private final URL themeURL= getClass().getResource("/Sounds/theme.wav");
|
|
|
|
public GameEngine(int width, int height){
|
|
|
|
|
|
//initialize variables and load audio\image files.
|
|
this.canScore = true;
|
|
this.isFirstGame = true;
|
|
this.gameOver = true;
|
|
this.pWidth = width;
|
|
this.pHeight = height;
|
|
try {
|
|
themeAudioClip = Applet.newAudioClip(themeURL);
|
|
}catch (Exception e){
|
|
themeAudioClip = null;
|
|
}
|
|
|
|
if(themeAudioClip != null)
|
|
themeAudioClip.loop();
|
|
r = new Random();
|
|
sceneImage = new BufferedImage(width, height, Image.SCALE_SMOOTH);
|
|
loadSuccessSounds();
|
|
startNewGame();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* initialize and reset vars and timers to "new game" configuration.
|
|
*/
|
|
private void startNewGame(){
|
|
this.gameOn = true;
|
|
pipeTimer = new Timer(2000, new PipeTimerListener());
|
|
backgrounds = new Vector<>();
|
|
initBackgrounds();
|
|
initGame();
|
|
}
|
|
|
|
/**
|
|
* Setup all actors in the game to a new game - reset timer
|
|
*/
|
|
private void initGame(){
|
|
pipes = new Vector<>();
|
|
|
|
this.bird = new Bird(100, this.pWidth, this.pHeight, 45);
|
|
this.score = 0;
|
|
gameOn = true;
|
|
pipeTimer.start();
|
|
|
|
|
|
}
|
|
|
|
private void loadSuccessSounds(){
|
|
successSounds = new Vector<>();
|
|
for (int i = 1 ; i < 5 ; i++){
|
|
successSounds.add(Applet.newAudioClip(getClass().getResource("/Sounds/pass"+i+".wav")));
|
|
}
|
|
}
|
|
|
|
private void initBackgrounds(){
|
|
backgrounds.add(new SideScollerBackground(pWidth, pHeight, 2, "skyLine.png", pWidth, pHeight));
|
|
backgrounds.add(new SideScollerBackground(pWidth, pHeight, 5, "trees.png", pWidth + 50, pHeight));
|
|
backgrounds.add(new SideScollerBackground(pWidth, pHeight, 10, "ground.png", pWidth, 45));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* returns score
|
|
* @return
|
|
* int
|
|
*/
|
|
public int getScore(){
|
|
return score;
|
|
}
|
|
|
|
/**
|
|
* returns gameOver flag
|
|
* @return
|
|
* boolean
|
|
*/
|
|
public boolean isGameOver(){
|
|
return this.gameOver;
|
|
}
|
|
|
|
|
|
/**
|
|
* Create a new Pipe on a random position.
|
|
*/
|
|
private void createPipe(){
|
|
int pipeLoc = (r.nextInt(pHeight-40)+40) * -1;
|
|
pipes.add(new Pipe(pipeLoc, pWidth, pHeight, PIPE_ACC, PIPE_WIDTH, pHeight * 2));
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Update all sprites, including collision handling.
|
|
*/
|
|
public void update(){
|
|
if(!gameOver) {
|
|
bird.update();
|
|
for(int i=0; i<pipes.size(); i++){
|
|
pipes.elementAt(i).update();
|
|
}
|
|
|
|
for(int i = 0 ; i < backgrounds.size() ; i++){
|
|
backgrounds.elementAt(i).update();
|
|
}
|
|
collisionHandler();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Checks if a collision has occurred.
|
|
* in case of missile hitting an asteroid - they are both removed.
|
|
* in case of asteroid hitting the ship - round over.
|
|
*/
|
|
private void collisionHandler() {
|
|
|
|
//Ikaros - dont fly too high, dont fly to low.
|
|
if (bird.getLocY() >= pHeight - ( bird.getSWidth() + backgrounds.lastElement().getsHeight())|| bird.getLocY() <= 0) {
|
|
pipeTimer.stop();
|
|
gameOver = true;
|
|
}
|
|
|
|
//pipe out of screen
|
|
if (!pipes.isEmpty() && pipes.elementAt(0).getLocX() + PIPE_WIDTH < 0) {
|
|
canScore = true;
|
|
pipes.remove(0);
|
|
}
|
|
|
|
|
|
//pipe vs. bird
|
|
if (!pipes.isEmpty() && CollisionUtil.collidesWith(bird, pipes.elementAt(0))){
|
|
gameOver = true;
|
|
pipeTimer.stop();
|
|
}
|
|
|
|
if(canScore && !pipes.isEmpty() && bird.getLocX() >= pipes.elementAt(0).getLocX() + pipes.elementAt(0).getSWidth()) {
|
|
score++;
|
|
canScore = false;
|
|
successSounds.elementAt(r.nextInt(4)).play();
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* render buffered image.
|
|
* @param panel
|
|
* JPanel
|
|
*/
|
|
public void render(JPanel panel){
|
|
sceneImage = new BufferedImage(this.pWidth, this.pHeight, Image.SCALE_FAST); // Empty Scene
|
|
renderScene(sceneImage.getGraphics(), panel); // Paint new Scene
|
|
}
|
|
|
|
|
|
/**
|
|
* Draws all sprites
|
|
* @param g
|
|
* Graphics
|
|
* @param panel
|
|
* Jpanel
|
|
*/
|
|
public void renderScene(Graphics g, JPanel panel){
|
|
backgrounds.elementAt(0).drawSprite(g, panel);
|
|
backgrounds.elementAt(1).drawSprite(g, panel);
|
|
bird.drawSprite(g, panel);
|
|
for(int i=0; i<pipes.size(); i++){
|
|
pipes.elementAt(i).drawSprite(g, panel);
|
|
}
|
|
backgrounds.elementAt(2).drawSprite(g, panel);
|
|
|
|
|
|
}
|
|
|
|
/**
|
|
* creates an new asteroid each 5 seconds *
|
|
*/
|
|
private class PipeTimerListener implements ActionListener{
|
|
@Override
|
|
public void actionPerformed(ActionEvent actionEvent) {
|
|
createPipe();
|
|
}
|
|
}
|
|
|
|
public void mouseClicked(MouseEvent e){
|
|
if(gameOver){
|
|
// gameOn = true;
|
|
this.isFirstGame = false;
|
|
gameOver = false;
|
|
initGame();
|
|
} else {
|
|
bird.jump();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* returns sceneImage
|
|
* @return
|
|
* BufferedImage
|
|
*/
|
|
public BufferedImage getScene(){
|
|
return this.sceneImage;
|
|
}
|
|
|
|
|
|
}
|