|
|
@@ -4,6 +4,7 @@ import controller.entity.EntityController;
|
|
|
import controller.entity.VillagerController;
|
|
|
import controller.factories.EntityFactory;
|
|
|
import controller.factories.InteractiveTileFactory;
|
|
|
+import controller.input.KeyHandler;
|
|
|
import controller.tiles.interactive.*;
|
|
|
import controller.tiles.interactive.upgradeable.*;
|
|
|
import model.GameModel;
|
|
|
@@ -19,6 +20,7 @@ import util.GAMESTATE;
|
|
|
import view.GamePanel;
|
|
|
import view.tile.interactive.InteractiveTileView;
|
|
|
|
|
|
+import java.awt.*;
|
|
|
import java.io.Serializable;
|
|
|
import java.util.ArrayList;
|
|
|
|
|
|
@@ -40,7 +42,7 @@ public class GameController implements Runnable, Serializable {
|
|
|
public transient ArrayList<InteractiveTileController> interactiveTileControllers;
|
|
|
private transient InteractiveTileController draggingTile;
|
|
|
private transient int residualShiftX, residualShiftY;
|
|
|
- private boolean gameActive;
|
|
|
+ private transient boolean gameActive;
|
|
|
|
|
|
/**
|
|
|
* Constructs a GameController, sets up model, view, input, inventory, entities, and interactive tiles.
|
|
|
@@ -383,73 +385,92 @@ public class GameController implements Runnable, Serializable {
|
|
|
getView().generateNewWorld();
|
|
|
}
|
|
|
|
|
|
+ private int originalGridX, originalGridY;
|
|
|
+
|
|
|
/**
|
|
|
- * Handles dragging shifts in screen coordinates, converting to world-grid movement.
|
|
|
- *
|
|
|
- * @param dx pixel shift in x
|
|
|
- * @param dy pixel shift in y
|
|
|
+ * Called from GameMouseListener.mousePressed when starting a drag on right-click.
|
|
|
*/
|
|
|
- public void handleTileShift(int dx, int dy) {
|
|
|
- if (draggingTile == null) {
|
|
|
- return;
|
|
|
+ public void setDraggingTile(InteractiveTileController tile) {
|
|
|
+ draggingTile = tile;
|
|
|
+ if (draggingTile != null) {
|
|
|
+ InteractiveTileModel model = draggingTile.getModel();
|
|
|
+ originalGridX = model.getWorldGridX();
|
|
|
+ originalGridY = model.getWorldGridY();
|
|
|
+ // Optionally, ensure view's screen coords are set initially
|
|
|
+ InteractiveTileView view = draggingTile.getView();
|
|
|
+ int sx = worldColToScreenX(originalGridX);
|
|
|
+ int sy = worldRowToScreenY(originalGridY);
|
|
|
+ view.setScreenCoordinates(sx, sy);
|
|
|
}
|
|
|
- accumulateResidualShift(dx, dy);
|
|
|
- applyGridShiftIfNeeded();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Accumulates residual pixel shifts before converting to grid movement.
|
|
|
- *
|
|
|
- * @param dx pixel delta x
|
|
|
- * @param dy pixel delta y
|
|
|
+ * Called from GameMouseListener.mousePressed to clear any residual state.
|
|
|
+ * Retained for compatibility; residual shifting no longer used for mouse drag.
|
|
|
*/
|
|
|
- private void accumulateResidualShift(int dx, int dy) {
|
|
|
- residualShiftX += dx;
|
|
|
- residualShiftY += dy;
|
|
|
+ public void resetResidualShift() {
|
|
|
+ // No-op or clear any previous state related to grid-shift dragging
|
|
|
+ // Previously, residualShiftX/Y were used; now smooth drag uses pixel offsets via handleTileShift
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Checks if enough residual has accumulated to shift by whole tiles, and applies if valid.
|
|
|
+ * Entry point for dragging movement: called from GameMouseListener.mouseDragged when right mouse button.
|
|
|
+ * dx, dy are screen pixel deltas.
|
|
|
*/
|
|
|
- private void applyGridShiftIfNeeded() {
|
|
|
- int tileSize = getView().tileSize;
|
|
|
- int gridShiftX = residualShiftX / tileSize;
|
|
|
- int gridShiftY = residualShiftY / tileSize;
|
|
|
- if (gridShiftX == 0 && gridShiftY == 0) {
|
|
|
+ public void handleTileShift(int dx, int dy) {
|
|
|
+ if (draggingTile == null) {
|
|
|
return;
|
|
|
}
|
|
|
- // Remove used pixels
|
|
|
- residualShiftX -= gridShiftX * tileSize;
|
|
|
- residualShiftY -= gridShiftY * tileSize;
|
|
|
-
|
|
|
- attemptTilePositionShift(gridShiftX, gridShiftY);
|
|
|
+ // Smooth pixel-based move: update view's screen coordinates by delta
|
|
|
+ InteractiveTileView view = draggingTile.getView();
|
|
|
+ view.setScreenCoordinates(view.getScreenX() + dx, view.getScreenY() + dy);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Attempts to shift the dragging tile model by given grid offsets. Reverts residuals if invalid.
|
|
|
- *
|
|
|
- * @param gridShiftX number of tiles to shift in x
|
|
|
- * @param gridShiftY number of tiles to shift in y
|
|
|
+ * Called from GameMouseListener.mouseReleased when ending a drag.
|
|
|
+ * Snaps the tile to grid, validates position, reverts if invalid.
|
|
|
*/
|
|
|
- private void attemptTilePositionShift(int gridShiftX, int gridShiftY) {
|
|
|
- InteractiveTileModel model = draggingTile.getModel();
|
|
|
- int oldX = model.getWorldGridX();
|
|
|
- int oldY = model.getWorldGridY();
|
|
|
- int newX = oldX + gridShiftX;
|
|
|
- int newY = oldY + gridShiftY;
|
|
|
-
|
|
|
- if (!isValidPosition(newX, newY)) {
|
|
|
- // Revert residual since shift is invalid
|
|
|
- int tileSize = getView().tileSize;
|
|
|
- residualShiftX += gridShiftX * tileSize;
|
|
|
- residualShiftY += gridShiftY * tileSize;
|
|
|
+ public void handleTileRelease(int mouseX, int mouseY) {
|
|
|
+ if (draggingTile == null) {
|
|
|
return;
|
|
|
}
|
|
|
+ InteractiveTileView view = draggingTile.getView();
|
|
|
+ InteractiveTileModel model = draggingTile.getModel();
|
|
|
|
|
|
- model.setWorldGridX(newX);
|
|
|
- model.setWorldGridY(newY);
|
|
|
- }
|
|
|
+ GamePanel gp = getView();
|
|
|
+ int tileSize = gp.tileSize;
|
|
|
+ int widthTiles = view.getScaleX();
|
|
|
+ int heightTiles = view.getScaleY();
|
|
|
+
|
|
|
+ // Compute the screen coordinates of the tile's top-left
|
|
|
+ int dropScreenX = view.getScreenX();
|
|
|
+ int dropScreenY = view.getScreenY();
|
|
|
+ // Compute the center pixel position of the tile
|
|
|
+ int centerScreenX = dropScreenX + (widthTiles * tileSize) / 2;
|
|
|
+ int centerScreenY = dropScreenY + (heightTiles * tileSize) / 2;
|
|
|
+ // Convert center to world grid coordinate (floor)
|
|
|
+ int centerGridX = screenToWorldX(centerScreenX);
|
|
|
+ int centerGridY = screenToWorldY(centerScreenY);
|
|
|
+ // Compute top-left grid position so that tile center aligns to centerGrid
|
|
|
+ int targetGridX = centerGridX - (widthTiles / 2);
|
|
|
+ int targetGridY = centerGridY - (heightTiles / 2);
|
|
|
+
|
|
|
+ if (isValidPosition(targetGridX, targetGridY)) {
|
|
|
+ model.setWorldGridX(targetGridX);
|
|
|
+ model.setWorldGridY(targetGridY);
|
|
|
+ } else {
|
|
|
+ // Revert to original grid position
|
|
|
+ model.setWorldGridX(originalGridX);
|
|
|
+ model.setWorldGridY(originalGridY);
|
|
|
+ }
|
|
|
+ // After updating model, reset view’s screen coords to the snapped grid position
|
|
|
+ int snappedScreenX = worldColToScreenX(model.getWorldGridX());
|
|
|
+ int snappedScreenY = worldRowToScreenY(model.getWorldGridY());
|
|
|
+ view.setScreenCoordinates(snappedScreenX, snappedScreenY);
|
|
|
|
|
|
+ // Clear dragging state
|
|
|
+ draggingTile = null;
|
|
|
+ }
|
|
|
/**
|
|
|
* Checks if draggingTile can be placed at new grid coordinates without out-of-bounds or collision.
|
|
|
*
|
|
|
@@ -483,29 +504,6 @@ public class GameController implements Runnable, Serializable {
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
-
|
|
|
- /**
|
|
|
- * Converts a screen X coordinate to world grid X.
|
|
|
- *
|
|
|
- * @param screenX screen X in pixels
|
|
|
- * @return world grid X coordinate
|
|
|
- */
|
|
|
- public int screenToWorldX(int screenX) {
|
|
|
- GamePanel gp = getView();
|
|
|
- return (gp.camera.worldX + screenX - gp.camera.screenX) / gp.tileSize;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Converts a screen Y coordinate to world grid Y.
|
|
|
- *
|
|
|
- * @param screenY screen Y in pixels
|
|
|
- * @return world grid Y coordinate
|
|
|
- */
|
|
|
- public int screenToWorldY(int screenY) {
|
|
|
- GamePanel gp = getView();
|
|
|
- return (gp.camera.worldY + screenY - gp.camera.screenY) / gp.tileSize;
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* Returns the InteractiveTileController at the specified grid coordinates, or null if none.
|
|
|
*
|
|
|
@@ -533,29 +531,37 @@ public class GameController implements Runnable, Serializable {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Sets the tile currently being dragged.
|
|
|
- *
|
|
|
- * @param tile the InteractiveTileController being dragged
|
|
|
- */
|
|
|
- public void setDraggingTile(InteractiveTileController tile) {
|
|
|
- this.draggingTile = tile;
|
|
|
+
|
|
|
+ // Ensure you have utility methods:
|
|
|
+ private int worldColToScreenX(int worldCol) {
|
|
|
+ GamePanel gp = getView();
|
|
|
+ return gp.camera.screenX + worldCol * gp.tileSize - gp.camera.worldX;
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Resets any accumulated residual pixel shift (e.g., when drag ends).
|
|
|
- */
|
|
|
- public void resetResidualShift() {
|
|
|
- residualShiftX = 0;
|
|
|
- residualShiftY = 0;
|
|
|
+ private int worldRowToScreenY(int worldRow) {
|
|
|
+ GamePanel gp = getView();
|
|
|
+ return gp.camera.screenY + worldRow * gp.tileSize - gp.camera.worldY;
|
|
|
+ }
|
|
|
+
|
|
|
+ // screenToWorldX/Y assumed unchanged
|
|
|
+ public int screenToWorldX(int screenX) {
|
|
|
+ GamePanel gp = getView();
|
|
|
+ return (gp.camera.worldX + screenX - gp.camera.screenX) / gp.tileSize;
|
|
|
+ }
|
|
|
+
|
|
|
+ public int screenToWorldY(int screenY) {
|
|
|
+ GamePanel gp = getView();
|
|
|
+ return (gp.camera.worldY + screenY - gp.camera.screenY) / gp.tileSize;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
/**
|
|
|
* Loads interactive tiles and entities from the saved GameModel.
|
|
|
*/
|
|
|
public void loadGame() {
|
|
|
loadInteractiveTilesFromSave();
|
|
|
loadEntitiesFromSave();
|
|
|
+ initResourceManager();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -588,6 +594,12 @@ public class GameController implements Runnable, Serializable {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ */
|
|
|
+ public boolean isTileDragged(InteractiveTileController controller){
|
|
|
+ return draggingTile == controller;
|
|
|
+ }
|
|
|
/**
|
|
|
* Initializes the Main Menu for changing worlds etc.
|
|
|
*/
|
|
|
@@ -602,5 +614,9 @@ public class GameController implements Runnable, Serializable {
|
|
|
public void addToInventory(Item collected) {
|
|
|
getModel().getInventory().addToInventory(collected);
|
|
|
}
|
|
|
+
|
|
|
+ public InteractiveTileController getDraggedTile() {
|
|
|
+ return draggingTile;
|
|
|
+ }
|
|
|
}
|
|
|
|