package com.zeroqualitygames.spaceinvaders;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import com.zeroqualitygames.spaceinvaders.entity.Alien;
import com.zeroqualitygames.spaceinvaders.entity.Entity;
import com.zeroqualitygames.spaceinvaders.entity.Missile;
import com.zeroqualitygames.spaceinvaders.entity.Player;
import com.zeroqualitygames.spaceinvaders.menu.GameOver;
import com.zeroqualitygames.spaceinvaders.menu.LevelTransitionMenu;
import com.zeroqualitygames.spaceinvaders.menu.Menu;
import com.zeroqualitygames.spaceinvaders.resources.Sound;
public class Game extends Canvas implements Runnable {
public static Sound shoot = new Sound("shoot.wav");
public static Sound destroy = new Sound("invaderkilled.wav");
private static final long serialVersionUID = 1L;
public static final int WIDTH = 500;
public static final int HEIGHT = 500;
private Thread gameThread;
public boolean running = false;
private BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
private Graphics2D g = (Graphics2D) image.getGraphics();
public static final int ALIEN = 2;
public static final int PLAYER = 1;
public static int SCORE = 0;
public static int level = 0;
public static boolean GAMEOVER = false;
private ArrayList<Entity> entities = new ArrayList<Entity>();
private InputManager input = new InputManager(this);
public Menu menu = new Menu();
private Player player = new Player(input);
private long previousShootTime = 0;
public boolean reverse = false;
private int sleepTime = 5;
private int FPS, ticks;
public Game() {
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setFocusable(true);
menu = null;
reset();
}
public void setMenu(Menu menu) {
this.menu = menu;
if (menu != null)
menu.init(this, input);
}
public void reset() {
entities.removeAll(entities);
level++;
addEntity(player);
for (int x = 0; x < 11; x++) {
for (int y = 0; y < 5; y++){
addEntity(new Alien(50 + x * 35, y * 35, System.currentTimeMillis(), level));
}
}
}
public void restart() {
SCORE = 0;
reset();
}
public void addEntity(Entity e) {
entities.add(e);
e.init(this);
}
public void removeEntity(Entity e) {
entities.remove(e);
}
public ArrayList<Entity> getEntities() {
return entities;
}
@Override
public void run() {
long startTime = System.currentTimeMillis();
while(running) {
ticks++;
update();
render();
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (System.currentTimeMillis() - startTime > 1000) {
FPS = ticks;
ticks = 0;
startTime = System.currentTimeMillis();
}
}
}
private void update() {
if (menu != null) {
menu.tick();
}
else {
for (int i = 0; i < entities.size(); i++) {
Entity e = entities.get(i);
if (e.x + e.width > Game.WIDTH || e.x < 0) {
reverse = true;
}
}
if (reverse) {
for (int i = 0; i < entities.size(); i++) {
Entity e = entities.get(i);
if (e instanceof Alien)
((Alien) e).reverse();
}
reverse = false;
}
for (int i = 0; i < entities.size(); i++) {
Entity e = entities.get(i);
e.tick();
if (reverse && e instanceof Alien) {
((Alien) e).reverse();
}
if (e.removed)
removeEntity(e);
else {
if (e.y < 0 - e.height) {
removeEntity(e);
}
}
}
if (input.shoot.pressed && System.currentTimeMillis() - previousShootTime > 500) {
previousShootTime = System.currentTimeMillis();
entities.add(new Missile( (int) (player.x + player.width/2)));
Game.shoot.play();
}
if (checkWin()) {
SCORE += 10;
setMenu(new LevelTransitionMenu());
reset();
}
if (GAMEOVER) {
setMenu(new GameOver());
}
}
}
private void render() {
BufferStrategy strategy = getBufferStrategy();
if (strategy == null) {
createBufferStrategy(3);
requestFocus();
return;
}
paintComponent(getGraphics2D());
Graphics g = strategy.getDrawGraphics();
g.fillRect(0, 0, getWidth(), getHeight());
int x = (getWidth() - getHeight())/2;
g.drawImage(image, x, 0, getHeight(), getHeight(), this);
g.dispose();
strategy.show();
}
private void paintComponent(Graphics2D g) {
g.setColor(Color.WHITE);
g.fillRect(0, 0, WIDTH, HEIGHT);
g.setColor(Color.BLACK);
if (menu != null) {
menu.render(g);
}
if (!(menu instanceof GameOver)) {
for (Entity e: entities) {
e.render(g);
}
}
g.setColor(Color.WHITE);
g.fillRect(2, 25, 60, 30);
g.setColor(Color.BLACK);
g.drawRect(2, 25, 60, 30);
g.setFont(new Font("Arial", Font.PLAIN, 12));
g.drawString("FPS: " + FPS, 5, 37);
g.drawString("LEVEL: " + level, 5, 52);
g.drawRect(0, 0, WIDTH - 1, HEIGHT - 1);
}
public boolean checkWin() {
for (Entity e : entities) {
if (e instanceof Alien)
return false;
}
return true;
}
public Graphics2D getGraphics2D() {
return g;
}
public void start() {
if (!running && gameThread == null) {
running = true;
gameThread = new Thread(this);
gameThread.start();
}
}
public void stop() {
if (running && gameThread != null) {
running = !running;
}
}
}