package ch.booyakasha.engine;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.image.BufferStrategy;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JPanel;

import ch.booyakasha.engine.GameKeyInputHandler.GameKeyInformation;

/**
 * Game logic, including game loop
 */
public class Game extends Canvas implements IGame {
	/**
	 * Cached instance of the current configuration
	 */
	private Configuration config;
	private BufferStrategy strategy;
	private boolean gameRunning = true;
	private ArrayList<Entity> entities = new ArrayList<Entity>();
	private Entity player;
	private GameKeyInputHandler gameKeyInputHandler;
	
	//private MouseInput mouseInput;
	
	/** True if game logic needs to be applied this loop, normally as a result of a game event */
	private boolean logicRequiredThisLoop = false;
	
	/**
	 * Construct our game and set it running.
	 */
	public Game() {
		config = Configuration.getCurrent();
		
		// TODO: Switch to AWT components, mixing SWING and AWT was not a good idea
		JFrame container = new JFrame("Booyakasha");
		
		JPanel panel = (JPanel)container.getContentPane();
		panel.setPreferredSize(new Dimension(config.screenWidth, config.screenHeight));
		//panel.setLayout(null);
		
		setSize(config.screenWidth, config.screenHeight);
		panel.add(this);
		
		/*
		mouseInput = new MouseInput();
		addMouseListener(mouseInput);
		addMouseMotionListener(mouseInput);
		*/
		
		// Tell AWT not to bother repainting our canvas since we're going to do that our self in accelerated mode
		setIgnoreRepaint(true);
		
		container.pack();
		container.setResizable(false);
		container.setVisible(true);
		
		container.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		// Add key input handler
		gameKeyInputHandler = new GameKeyInputHandler();
		addKeyListener(gameKeyInputHandler);
				
		requestFocus();

		// Create the buffering strategy which will allow AWT to manage our accelerated graphics
		createBufferStrategy(2);
		strategy = getBufferStrategy();
		
		startGame();
	}
	
	/**
	 * Starts a new game
	 */
	private void startGame() {
		entities.clear();
		initEntities();
	}
	
	private void initEntities() {
		// Create the player object
		player = new AliGEntity(this, "/sprites/alig.gif", 370, 550);
		entities.add(player);
		
		// Create enemies
		for(int row = 0; row < 5; row++) {
			for(int x = 0; x < 12; x++) {
				Entity enemy = new EnemyEntity(this, "/sprites/enemy.gif", 100 + (x * 50), 50 + row * 36);
				entities.add(enemy);
			}
		}
	}
	
	/**
	 * Notification from a game entity that the logic of the game should be run
	 */
	public void updateLogic() {
		logicRequiredThisLoop = true;
	}

	
	/**
	 * Main game loop
	 */
	public void gameLoop() {
		long lastLoopTime = System.currentTimeMillis();
		
		// Keep looping round until the game ends
		while(gameRunning) {
			long delta = System.currentTimeMillis() - lastLoopTime;
			lastLoopTime = System.currentTimeMillis();
			
			// Get hold of a graphics context for the accelerated 
			// surface and blank it out
			Graphics2D g = (Graphics2D)strategy.getDrawGraphics();
			g.setColor(Color.GRAY);
			g.fillRect(0, 0, 800, 600);
			g.setColor(new Color(139, 69, 19));
			g.fillRect(0, 0, 50, 600);
			g.fillRect(750, 0, 800, 600);
			
			// Let entities move
			for(int i = 0; i < entities.size(); i++) {
				Entity entity = entities.get(i);
				entity.move(delta);
			}
			
			// Draw all entities
			for(int i = 0; i < entities.size(); i++) {
				Entity entity = entities.get(i);
				entity.draw(g);
			}

			if(logicRequiredThisLoop) {
				for (int i=0;i<entities.size();i++) {
					Entity entity = entities.get(i);
					entity.doLogic();
				}
				
				logicRequiredThisLoop = false;
			}
			
			// Draw mouse
			/*
			Point p = mouseInput.getCurrent();
			if(p != null) {
				g.setColor(Color.GREEN);
				g.drawOval(p.x - 20, p.y - 20, 40, 40);
				g.drawRect(p.x - 5, p.y - 5, 10, 10);
			}
			*/
			
			g.dispose();
			strategy.show();
			
			GameKeyInformation keyInfo = gameKeyInputHandler.getKeyInformation();
			double playerVelocity = 0;
			if(keyInfo.isLeftPressed() && !keyInfo.isRightPressed()) {
				// Set left velocity
				playerVelocity = -config.playerVelocity;
			}
			else if(!keyInfo.isLeftPressed() && keyInfo.isRightPressed()) {
				// Set right velocity
				playerVelocity = config.playerVelocity;
			}
			player.setHorizontalMovement(playerVelocity);
			
			// Pause for 10ms --> 100 fps
			try { Thread.sleep(10); } catch (Exception e) {}
		}
	}
	

	public static void main(String argv[]) {
		Configuration.setCurrent(new Configuration());
		
		Game game = new Game();
		game.gameLoop();
	}
}

@@ -3044,34 +3044,23 @@
 Get 
-hold of a 
 graphic
-s
  context
  for
@@ -3059,60 +3059,8 @@
 text
- for the accelerated %0A%09%09%09// surface and blank it out
 %0A%09%09%09
@@ -3114,16 +3114,34 @@
 hics();%0A
+%09%09%09// Draw street%0A
 %09%09%09g.set
@@ -3150,18 +3150,32 @@
 lor(
+new 
 Color
-.GRAY
+(168, 168, 168)
 );%0A%09
@@ -3200,24 +3200,59 @@
  800, 600);%0A
+%09%09%09// Draw buildings on both sides%0A
 %09%09%09g.setColo

Update Game.java