package display_pkg;
import controller_pkg.KeyboardHandler;
import controller_pkg.Menu;
import def_classes.Dimensions;
import def_classes.Point;
import def_classes.Box;
import model_pkg.*;
import javax.swing.*;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Color;
import java.awt.image.BufferStrategy;
import java.awt.event.*;
import java.awt.Canvas;
import java.awt.BorderLayout;
/**
* The game display class handles the drawings of the game and the game window.
* @author Marcus Johansson
*
*/
public class GameDisplay implements Display {
private int screenWidth;
private int screenHeight;
private JFrame frame;
private JPanel panel;
private DrawArea screen;
private Model gameWorld;
private View gameView;
// A DrawArea represents the area in the window where the game will be drawed
private class DrawArea extends Canvas {
private Graphics currentGraphics;
private BufferStrategy bufferStrategy;
// The constructor sets the bounds of the canvas
public DrawArea() {
setBounds(0, 0, screenWidth, screenHeight);
}
// Make the canvas use double buffering for faster image blitting
public void setDoubleBuffer() {
// Create a double buffer system for effective drawing
createBufferStrategy(2);
bufferStrategy = getBufferStrategy();
currentGraphics = bufferStrategy.getDrawGraphics();
}
// Should be called before every game redraw
// Clears the current used surface
public void initNewRedraw() {
currentGraphics.clearRect(0, 0, screenWidth, screenHeight);
}
//public void update() init...redraw
// Blits an image onto the back surface
public void drawImage(int x, int y, Image img) {
currentGraphics.drawImage(img, x, y, this);
}
public void drawRect(Box b) {
currentGraphics.setColor(Color.BLACK);
currentGraphics.fillRect(b.getLeft(), b.getTop(), b.getWidth(), b.getHeight());
}
// Swaps the buffers and resets the graphics object
public void redrawArea() {
bufferStrategy.show(); // swaps the surface buffers
currentGraphics = bufferStrategy.getDrawGraphics();
}
}
/**
* Setup a new GameDisplay and connect it to a model
* @param world the model to which the display should be connected
*/
public GameDisplay(Model world) {
gameWorld = world;
gameView = gameWorld.getView();
frame = new JFrame("Cloud Climber");
screenWidth = world.getView().getWidth();
screenHeight = world.getView().getHeight();
frame.setSize(screenWidth+8, screenHeight+30);
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
screen = new DrawArea();
frame.add(screen);
frame.setVisible(true);
screen.setDoubleBuffer();
}
/**
* This will draw all objects inside the view.
* Will eventually end up in drawSprite(), see GameDisplay.
*
*/
public void redrawGame() {
screen.initNewRedraw();
gameWorld.drawWorld(this);
screen.redrawArea();
}
/**
* Redraws the menu on the screen
* @param menu the menu
*/
public void redrawMenu(Menu menu) {
screen.initNewRedraw();
menu.drawMenu(this);
screen.redrawArea();
}
/**
* Draws a background on the current back surface
* @param bg a background object
*/
public void drawBackground(Background bg) {
int h = bg.getDimensions().getHeight();
int w = bg.getDimensions().getWidth();
for (int r = -gameView.getTop(); r <= screenHeight; r += h) {
for (int c = -gameView.getLeft(); c <= screenWidth; c += w) {
screen.drawImage(c, r, bg.getImage());
}
}
}
/**
* Draws a sprite onto the screen if it lies within the current view
* @param worldCoordinates the world coordinates of the sprite
* @param graphic the sprite
*/
public void drawSprite(Point worldCoordinates, GfxState graphic) {
//if (worldCoordinates.) {
int dx = worldCoordinates.getIntX() - gameView.getLeft();
int dy = worldCoordinates.getIntY() - gameView.getTop();
screen.drawImage(dx, dy, graphic.getImage());
//}
}
/**
* Draws a rectangle on the screen
* @param b the rectangle
*/
public void drawRect(Box b) {
b.moveX(-gameView.getLeft());
b.moveY(-gameView.getTop());
screen.drawRect(b);
}
/**
* Draws a background at 0, 0 on the screen.
* @param bg the background
*/
public void drawMenuBackground(Background bg) {
screen.drawImage(0, 0, bg.getImage());
}
/**
* Draws a menu item on the screen
* @param p the position of the item
* @param gfx the GfxState object holding the item
*/
public void drawMenuItem(Point p, GfxState gfx) {
screen.drawImage(p.getIntX(), p.getIntY(), gfx.getImage());
}
/**
* Returns the current view of the display
*/
public Box getCurrentView() {
return new Box();
}
/**
* Sets the keyboard listener for the current window
* @param keyHandle a keyboard listener
*/
public void setKeyboardListener(KeyboardHandler keyHandle) {
frame.addKeyListener(keyHandle);
}
/**
* Disposes off all JComponents to avoid memory leaks
*/
public void disposeResources() {
frame.dispose();
}
@Override
public Dimensions getScreenDimensions() {
return new Dimensions(screenWidth, screenHeight);
}
}