|
|
@@ -2,16 +2,21 @@ package controller;
|
|
|
|
|
|
import controller.entity.EntityController;
|
|
|
import controller.entity.VillagerController;
|
|
|
+import controller.factories.EntityFactory;
|
|
|
+import controller.factories.InteractiveTileFactory;
|
|
|
import controller.tiles.interactive.*;
|
|
|
import controller.tiles.interactive.upgradeable.*;
|
|
|
import model.GameModel;
|
|
|
import model.GameSaver;
|
|
|
import model.entity.EntityModel;
|
|
|
+import model.entity.EntityType;
|
|
|
import model.items.Item;
|
|
|
import model.items.ITEM_NAME;
|
|
|
import model.tiles.InteractiveTileModel;
|
|
|
+import model.tiles.InteractiveTileType;
|
|
|
import util.GAMESTATE;
|
|
|
import view.GamePanel;
|
|
|
+import view.tile.interactive.InteractiveTileView;
|
|
|
|
|
|
import java.io.Serializable;
|
|
|
import java.util.ArrayList;
|
|
|
@@ -28,6 +33,9 @@ public class GameController implements Runnable, Serializable {
|
|
|
private transient GamePanel view;
|
|
|
public transient ArrayList<EntityController> entityControllers;
|
|
|
public transient ArrayList<InteractiveTileController> interactiveTileControllers;
|
|
|
+ private transient InteractiveTileController draggingTile;
|
|
|
+ private transient int residualShiftX, residualShiftY;
|
|
|
+
|
|
|
|
|
|
public GameController() {
|
|
|
this.keyHandler = new KeyHandler(this);
|
|
|
@@ -42,27 +50,27 @@ public class GameController implements Runnable, Serializable {
|
|
|
}
|
|
|
|
|
|
private void setupInteractiveTiles() {
|
|
|
- LighthouseController lighthouse = new LighthouseController(this, setupInteractiveTileModel(20, 20));
|
|
|
+ LighthouseController lighthouse = new LighthouseController(this, setupInteractiveTileModel(20, 20, InteractiveTileType.LIGHTHOUSE));
|
|
|
addInteractiveTile(lighthouse);
|
|
|
|
|
|
- MineController mineController = new MineController(this, setupInteractiveTileModel(25,20));
|
|
|
+ MineController mineController = new MineController(this, setupInteractiveTileModel(25,20, InteractiveTileType.MINE));
|
|
|
addInteractiveTile(mineController);
|
|
|
|
|
|
- BarracksController barracksController = new BarracksController(this, setupInteractiveTileModel(26, 20));
|
|
|
+ BarracksController barracksController = new BarracksController(this, setupInteractiveTileModel(26, 20, InteractiveTileType.BARRACKS));
|
|
|
addInteractiveTile(barracksController);
|
|
|
|
|
|
- IronMineController ironMineController = new IronMineController(this, setupInteractiveTileModel(27, 20));
|
|
|
+ IronMineController ironMineController = new IronMineController(this, setupInteractiveTileModel(27, 20, InteractiveTileType.IRON_MINE));
|
|
|
addInteractiveTile(ironMineController);
|
|
|
|
|
|
- AnimalEnclosureController animal = new AnimalEnclosureController(this, setupInteractiveTileModel(28, 20));
|
|
|
+ AnimalEnclosureController animal = new AnimalEnclosureController(this, setupInteractiveTileModel(28, 20, InteractiveTileType.ANIMAL_ENCLOSURE));
|
|
|
addInteractiveTile(animal);
|
|
|
|
|
|
- SawmillController sawmillController = new SawmillController(this, setupInteractiveTileModel(29, 20));
|
|
|
+ SawmillController sawmillController = new SawmillController(this, setupInteractiveTileModel(29, 20, InteractiveTileType.SAWMILL));
|
|
|
addInteractiveTile(sawmillController);
|
|
|
}
|
|
|
|
|
|
private void setupEntities(){
|
|
|
- VillagerController villager = new VillagerController(this, setupEntityModel(22,20));
|
|
|
+ VillagerController villager = new VillagerController(this, setupEntityModel(22,20, EntityType.VILLAGER));
|
|
|
addEntity(villager);
|
|
|
}
|
|
|
|
|
|
@@ -74,14 +82,14 @@ public class GameController implements Runnable, Serializable {
|
|
|
interactiveTileControllers.add(controller);
|
|
|
}
|
|
|
|
|
|
- private EntityModel setupEntityModel(int worldX, int worldY) {
|
|
|
- EntityModel model = new EntityModel(worldX, worldY, getView().tileSize, getView().tileSize);
|
|
|
+ private EntityModel setupEntityModel(int worldX, int worldY, EntityType type) {
|
|
|
+ EntityModel model = new EntityModel(worldX, worldY, getView().tileSize, getView().tileSize, type);
|
|
|
gameModel.addEntityModel(model);
|
|
|
return model;
|
|
|
}
|
|
|
|
|
|
- public InteractiveTileModel setupInteractiveTileModel(int worldGridX, int worldGridY){
|
|
|
- InteractiveTileModel model = new InteractiveTileModel(worldGridX, worldGridY);
|
|
|
+ public InteractiveTileModel setupInteractiveTileModel(int worldGridX, int worldGridY, InteractiveTileType type){
|
|
|
+ InteractiveTileModel model = new InteractiveTileModel(worldGridX, worldGridY, type);
|
|
|
gameModel.addInteractiveTileModel(model);
|
|
|
return model;
|
|
|
}
|
|
|
@@ -151,6 +159,7 @@ public class GameController implements Runnable, Serializable {
|
|
|
}
|
|
|
|
|
|
private void moveEntities() {
|
|
|
+ if(entityControllers == null) return;
|
|
|
for(EntityController entityController : entityControllers){
|
|
|
entityController.convertRepaintSpeedToMovementLogic();
|
|
|
}
|
|
|
@@ -196,12 +205,6 @@ public class GameController implements Runnable, Serializable {
|
|
|
return keyHandler;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- public void loadInteractiveTiles() {
|
|
|
- interactiveTileControllers = new ArrayList<>();
|
|
|
- setupInteractiveTiles();
|
|
|
- }
|
|
|
-
|
|
|
public void loadWorld(){
|
|
|
if(view == null) this.view = new GamePanel(this);
|
|
|
view.loadMap(worldPath);
|
|
|
@@ -209,4 +212,140 @@ public class GameController implements Runnable, Serializable {
|
|
|
public void generateNewWorld() {
|
|
|
view.generateNewWorld();
|
|
|
}
|
|
|
+
|
|
|
+ public void handleTileShift(int dx, int dy) {
|
|
|
+ if (draggingTile == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // Accumulate residual pixel movement:
|
|
|
+ residualShiftX += dx;
|
|
|
+ residualShiftY += dy;
|
|
|
+
|
|
|
+ int tileSize = getView().tileSize;
|
|
|
+
|
|
|
+ // Compute whole-tile shifts:
|
|
|
+ int gridShiftX = residualShiftX / tileSize;
|
|
|
+ int gridShiftY = residualShiftY / tileSize;
|
|
|
+
|
|
|
+ if (gridShiftX == 0 && gridShiftY == 0) {
|
|
|
+ return; // not enough movement yet
|
|
|
+ }
|
|
|
+
|
|
|
+ // Subtract the used pixels, keep leftover:
|
|
|
+ residualShiftX -= gridShiftX * tileSize;
|
|
|
+ residualShiftY -= gridShiftY * tileSize;
|
|
|
+
|
|
|
+ // Now shift the stored tile model:
|
|
|
+ InteractiveTileModel model = draggingTile.getModel();
|
|
|
+ int oldX = model.getWorldGridX();
|
|
|
+ int oldY = model.getWorldGridY();
|
|
|
+ int newX = oldX + gridShiftX;
|
|
|
+ int newY = oldY + gridShiftY;
|
|
|
+
|
|
|
+ // OPTIONAL: check bounds/collisions before applying:
|
|
|
+ if (!isValidPosition(newX, newY)) {
|
|
|
+ // If invalid, you may want to revert residuals or clamp:
|
|
|
+ // e.g., undo the part of residual that caused invalid shift:
|
|
|
+ // residualShiftX += gridShiftX * tileSize;
|
|
|
+ // residualShiftY += gridShiftY * tileSize;
|
|
|
+ //System.out.printf("Cannot shift tile to (%d,%d): out of bounds or collision%n", newX, newY);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ model.setWorldGridX(newX);
|
|
|
+ model.setWorldGridY(newY);
|
|
|
+ //System.out.printf("Tile shifted from (%d, %d) to (%d, %d)%n", oldX, oldY, newX, newY);
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean isValidPosition(int newX, int newY) {
|
|
|
+ if (draggingTile == null) return false;
|
|
|
+
|
|
|
+ InteractiveTileModel model = draggingTile.getModel();
|
|
|
+ InteractiveTileView view = draggingTile.getView();
|
|
|
+
|
|
|
+ int width = view.getScaleX(); // how many tiles wide
|
|
|
+ int height = view.getScaleY(); // how many tiles high
|
|
|
+
|
|
|
+ // Check if tile stays within world bounds
|
|
|
+ if (newX < 0 || newY < 0 ||
|
|
|
+ newX + width > GamePanel.maxWorldCol ||
|
|
|
+ newY + height > GamePanel.maxWorldRow) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Check each tile the dragged tile would occupy
|
|
|
+ for (int x = newX; x < newX + width; x++) {
|
|
|
+ for (int y = newY; y < newY + height; y++) {
|
|
|
+ InteractiveTileController occupyingTile = getTileAt(x, y);
|
|
|
+ if (occupyingTile != null && occupyingTile != draggingTile) {
|
|
|
+ return false; // collision
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Hilfsmethoden, um von Screen-Koordinaten in Weltkoordinaten umzurechnen
|
|
|
+ public int screenToWorldX(int screenX) {
|
|
|
+ return (int)((getView().camera.worldX + screenX - getView().camera.screenX) / getView().tileSize);
|
|
|
+ }
|
|
|
+
|
|
|
+ public int screenToWorldY(int screenY) {
|
|
|
+ return (int)((getView().camera.worldY + screenY - getView().camera.screenY) / getView().tileSize);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Methode, um das Tile unter der aktuellen Weltposition zu bekommen
|
|
|
+ public InteractiveTileController getTileAt(int worldX, int worldY) {
|
|
|
+ for (InteractiveTileController tile : interactiveTileControllers) {
|
|
|
+ InteractiveTileModel model = tile.getModel();
|
|
|
+
|
|
|
+ if ( (worldX >= model.getWorldGridX()
|
|
|
+ && worldX < model.getWorldGridX() + tile.getView().getScaleX()
|
|
|
+ && worldY >= model.getWorldGridY()
|
|
|
+ && worldY < model.getWorldGridY() + tile.getView().getScaleY())
|
|
|
+ || (worldX == model.getWorldGridX() && worldY == model.getWorldGridY())) {
|
|
|
+ return tile;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setDraggingTile(InteractiveTileController tileAt) {
|
|
|
+ draggingTile = tileAt;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void resetResidualShift() {
|
|
|
+ residualShiftX = 0;
|
|
|
+ residualShiftY = 0;
|
|
|
+ }
|
|
|
+ private void loadInteractiveTilesFromSave() {
|
|
|
+ interactiveTileControllers = new ArrayList<>();
|
|
|
+ for (InteractiveTileModel model : gameModel.getInteractiveTileModels()) {
|
|
|
+ InteractiveTileController controller = InteractiveTileFactory.createTile(this, model);
|
|
|
+ if (controller != null) {
|
|
|
+ addInteractiveTile(controller);
|
|
|
+ } else {
|
|
|
+ System.err.println("Unknown tile type: " + model.getTileType());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void loadEntitiesFromSave() {
|
|
|
+ entityControllers = new ArrayList<>();
|
|
|
+ for (EntityModel model : gameModel.getEntityModels()) {
|
|
|
+ EntityController controller = EntityFactory.createEntity(this, model);
|
|
|
+ if (controller != null) {
|
|
|
+ addEntity(controller);
|
|
|
+ } else {
|
|
|
+ System.err.println("Unknown entity type: " + model.getEntityType());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void loadGame() {
|
|
|
+ loadInteractiveTilesFromSave();
|
|
|
+ loadEntitiesFromSave();
|
|
|
+ }
|
|
|
+
|
|
|
}
|