Camera.java
package com.vikingz.campustycoon.UI;
import java.util.List;
import com.vikingz.campustycoon.Game.Buildings.Building;
import com.vikingz.campustycoon.Game.Maps.Map;
import com.vikingz.campustycoon.Game.Tiles.Lake;
import com.vikingz.campustycoon.Game.Tiles.Tile;
import com.vikingz.campustycoon.UI.Components.MapBuilding;
import com.vikingz.campustycoon.UI.Components.MapTile;
import com.vikingz.campustycoon.UI.Systems.BuildingDisplay;
import com.vikingz.campustycoon.UI.Systems.MapDisplay;
import com.vikingz.campustycoon.Util.Drawer;
import com.vikingz.campustycoon.Util.GameUtils;
import com.vikingz.campustycoon.Util.MapUtils;
import com.vikingz.campustycoon.Util.ScreenUtils;
import com.vikingz.campustycoon.Util.Types.Coordinate;
/**
* This class is used to create a camera.
* Controls zooming, movement etc.
*/
public class Camera {
public static Map map; // The game map
public static int gridX, gridY; // Current grid coordinates of the mouse
public static int x = 0, y = 0; // Current coordinates of the camera
public static int width = Window.defaultWidth, height = Window.defaultHeight;
public static float zoom = 1;
private static final float MinZoom = 0.375f, MaxZoom = 2.75f;
private static final int ZoomSpeed = 8; // Lower = faster
private static Coordinate lastMousePos = new Coordinate();
private static Coordinate lastClickPos = null;
private static boolean placing;
private static String placementType;
private static Building hoverDisplay;
/**
* Updates the camera.
*/
public static void update() {
printCameraInfo();
updateDrawTiles();
updateDrawBuildings();
drawCursor();
}
/**
* Calculates which Grid coordinate the mouse is over
* @param X
* @return
*/
private static float getGridX(int X) {
float GridX = zoom * (X - x) / (Tile.SpriteSize);
return GridX;
}
private static float getGridY(int Y) {
float GridY = zoom * (Window.height - Y - y) / (Tile.SpriteSize);
return GridY;
}
public static void drawCursor() {
// Game not started yet
if (ScreenUtils.currentScreen != ScreenUtils.gameplayScreen) {
return;
}
// Game not initialised yet
if (map == null) {
return;
}
// If placing is false and was false last check too
if (placing == false && placing == map.placing) {
return;
}
// If placing was just turned off
if (placing == true && placing != map.placing) {
placing = false;
Drawer.remove(hoverDisplay.drawInfo);
return;
}
// If the hover icon just changed
if (map != null && hoverDisplay != null &&
placing == true && map.placementType != placementType) {
Drawer.remove(hoverDisplay.drawInfo);
hoverDisplay = MapUtils.getBuilding(map.placementType);
hoverDisplay.drawInfo.setImage(
GameUtils.getHoverImagePath(hoverDisplay.drawInfo.sprite.getImagePath()));
Drawer.add(BuildingDisplay.Layer + 1, hoverDisplay.drawInfo);
placementType = map.placementType;
}
// If placing mode was just turned on
else if (placing != map.placing) {
placing = true;
hoverDisplay = MapUtils.getBuilding(map.placementType);
hoverDisplay.drawInfo.setImage(
GameUtils.getHoverImagePath(hoverDisplay.drawInfo.sprite.getImagePath()));
Drawer.add(BuildingDisplay.Layer + 1, hoverDisplay.drawInfo);
}
hoverDisplay.setPosition(new Coordinate(gridX, gridY));
updateCursor();
}
/**
* Checks which tile the mouse is over
* @param X
* @param Y
*/
public static void checkMouseOverTile(int X, int Y) {
lastMousePos = new Coordinate(X, Y);
gridX = (int)Math.floor((double)getGridX(X));
gridY = (int)Math.floor((double)getGridY(Y));
//System.out.println("X: " + X + ", Y: " + Y);
//System.out.println("Grid X: " + gridX + ", Grid Y: " + gridY);
}
public static Tile getMouseOverTile() {
return map.grid.get(map.grid.size()-Camera.gridY-1).get(Camera.gridX);
}
/**
* Gets the tile from the grid coordinates
* @param X
* @param Y
* @return
*/
public static Tile getTileFromCoords(int X, int Y){
try {
int gridWidth = X;
int gridHeight = Y;
return map.grid.get(map.grid.size() - gridHeight - 1).get(gridWidth);
}
catch (Exception e){
return new Lake();
}
}
/**
* Zooms the camera
* @param scrollAmount
*/
public static void scroll(float scrollAmount) {
float oldZoom = zoom;
zoom += scrollAmount / ZoomSpeed;
zoom = Math.min(MaxZoom, Math.max(MinZoom, zoom));
float sign = Math.signum(zoom - oldZoom);
x = Math.round(x * (oldZoom / zoom) + (sign * 64f) / zoom); // 64f makes sense as it is the tile sprite width
y = Math.round(y * (oldZoom / zoom) + (sign * 36f) / zoom); // 36f does not make any sense at all (but it works)
checkMouseOverTile(lastMousePos.x, lastMousePos.y);
drawCursor();
update();
}
private static void placeBuilding() {
if (ScreenUtils.currentScreen == ScreenUtils.gameplayScreen) {
map.placeBuilding(new Coordinate(gridX, gridY));
update();
}
}
public static void lift(int X, int Y, int button) {
// TODO: Add a time based check to this too
// Checks that the mouse has barely moved since clicking
if (lastClickPos != null &&
lastClickPos.distance(new Coordinate(X, Y)) < 5) { // 5 is an extremely arbitrary number
placeBuilding();
}
}
public static void click(int X, int Y, int button) {
lastMousePos = new Coordinate(X, Y);
lastClickPos = lastMousePos;
}
public static void drag(int mouseX, int mouseY) {
x += mouseX - lastMousePos.x;
y -= mouseY - lastMousePos.y;
lastMousePos = new Coordinate(mouseX, mouseY);
update();
}
private static List<MapTile> popDrawTiles() {
List<MapTile> components = Drawer.popLayer(MapDisplay.Layer, new MapTile());
return components;
}
private static void updateDrawTiles() {
List<MapTile> tiles = popDrawTiles();
for (MapTile tile : tiles) {
tile.setOffset(x, y);
tile.setScale(1f / zoom);
tile.applyZoomOffset();
Drawer.add(MapDisplay.Layer, tile);
}
}
private static void updateDrawBuildings() {
List<MapBuilding> buildings = Drawer.popLayer(BuildingDisplay.Layer, new MapBuilding());
for (MapBuilding building : buildings) {
building.setOffset(x, y);
building.setScale(1f / zoom);
building.applyZoomOffset();
Drawer.add(BuildingDisplay.Layer, building);
}
}
private static void updateCursor() {
if (hoverDisplay == null) {
return;
}
hoverDisplay.drawInfo.setOffset(x, y);
hoverDisplay.drawInfo.setScale(1f / zoom);
hoverDisplay.drawInfo.applyZoomOffset();
//System.out.println(hoverDisplay.drawInfo.scale);
//System.out.println(hoverDisplay.drawInfo.baseWidth);
}
// For debug purposes
private static void printCameraInfo() {
//System.out.println("X: " + x + ", Y: " + y +
// "\nWidth: " + width + ", Height: " + height +
// "\nZoom: " + zoom);
}
}