|
|
@@ -8,6 +8,7 @@ import model.tiles.BackgroundTile;
|
|
|
import model.tiles.InteractiveTileModel;
|
|
|
import util.WorldGenerator;
|
|
|
import view.GamePanel;
|
|
|
+import view.tile.interactive.InteractiveTileView;
|
|
|
import view.util.RenderingManager;
|
|
|
|
|
|
import java.awt.*;
|
|
|
@@ -19,6 +20,8 @@ public class TileManager implements RenderingManager {
|
|
|
public Tile[] tile;
|
|
|
public int[][] mapTileNum;
|
|
|
public int mapTileOverflow = 1;
|
|
|
+ private InteractiveTileController draggingTile;
|
|
|
+ private int originalGridX, originalGridY;
|
|
|
|
|
|
public TileManager(GamePanel gp){
|
|
|
this.gamePanel = gp;
|
|
|
@@ -99,6 +102,18 @@ public class TileManager implements RenderingManager {
|
|
|
}
|
|
|
drawAllTiles(g2);
|
|
|
}
|
|
|
+ /**
|
|
|
+ * Entry point for dragging movement: called from GameMouseListener.mouseDragged when right mouse button.
|
|
|
+ * dx, dy are screen pixel deltas.
|
|
|
+ */
|
|
|
+ public void handleTileShift(int dx, int dy) {
|
|
|
+ if (draggingTile == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // Smooth pixel-based move: update view's screen coordinates by delta
|
|
|
+ InteractiveTileView view = draggingTile.getView();
|
|
|
+ view.setScreenCoordinates(view.getScreenX() + dx, view.getScreenY() + dy);
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* Drawing loop: update view coords from model for non-dragged tiles; draw all.
|
|
|
@@ -106,7 +121,7 @@ public class TileManager implements RenderingManager {
|
|
|
public void drawAllTiles(Graphics2D g2) {
|
|
|
// Optionally draw non-dragged first, then dragged to render on top
|
|
|
for (InteractiveTileController tile : gamePanel.gameController.interactiveTileControllers) {
|
|
|
- if (!gamePanel.gameController.isTileDragged(tile)) {
|
|
|
+ if (!isTileDragged(tile)) {
|
|
|
InteractiveTileModel model = tile.getModel();
|
|
|
int sx = worldColToScreenX(model.getWorldGridX());
|
|
|
int sy = worldRowToScreenY(model.getWorldGridY());
|
|
|
@@ -114,9 +129,9 @@ public class TileManager implements RenderingManager {
|
|
|
tile.drawTile(g2);
|
|
|
}
|
|
|
}
|
|
|
- if (gamePanel.gameController.getDraggedTile() != null) {
|
|
|
+ if (getDraggedTile() != null) {
|
|
|
// Draw dragged tile on top
|
|
|
- gamePanel.gameController.getDraggedTile().drawTile(g2);
|
|
|
+ getDraggedTile().drawTile(g2);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -129,6 +144,7 @@ public class TileManager implements RenderingManager {
|
|
|
double worldY = worldRow * gamePanel.tileSize; // Reactively use tileSize
|
|
|
return (int) (worldY - gamePanel.camera.worldY + gamePanel.camera.screenY);
|
|
|
}
|
|
|
+
|
|
|
public void getTileImage(){
|
|
|
try{
|
|
|
setupTile(0, "grass");
|
|
|
@@ -172,5 +188,136 @@ public class TileManager implements RenderingManager {
|
|
|
tile.resize(newTileSize);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ public void handleTileRelease(int mouseX, int mouseY) {
|
|
|
+ if (draggingTile == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ InteractiveTileView view = draggingTile.getView();
|
|
|
+ InteractiveTileModel model = draggingTile.getModel();
|
|
|
+
|
|
|
+ int tileSize = gamePanel.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.
|
|
|
+ *
|
|
|
+ * @param newX target grid X
|
|
|
+ * @param newY target grid Y
|
|
|
+ * @return true if valid position
|
|
|
+ */
|
|
|
+ private boolean isValidPosition(int newX, int newY) {
|
|
|
+ if (draggingTile == null) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ InteractiveTileModel model = draggingTile.getModel();
|
|
|
+ InteractiveTileView tileView = draggingTile.getView();
|
|
|
+ int width = tileView.getScaleX();
|
|
|
+ int height = tileView.getScaleY();
|
|
|
+
|
|
|
+ // Check world bounds
|
|
|
+ if (newX < 0 || newY < 0
|
|
|
+ || newX + width > GamePanel.maxWorldCol
|
|
|
+ || newY + height > GamePanel.maxWorldRow) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ // Check collisions
|
|
|
+ for (int x = newX; x < newX + width; x++) {
|
|
|
+ for (int y = newY; y < newY + height; y++) {
|
|
|
+ InteractiveTileController other = getTileAt(x, y);
|
|
|
+ if (other != null && other != draggingTile) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * Returns the InteractiveTileController at the specified grid coordinates, or null if none.
|
|
|
+ *
|
|
|
+ * @param worldX grid X coordinate
|
|
|
+ * @param worldY grid Y coordinate
|
|
|
+ * @return the tile controller at that position, or null
|
|
|
+ */
|
|
|
+ public InteractiveTileController getTileAt(int worldX, int worldY) {
|
|
|
+ if (gamePanel.gameController.interactiveTileControllers == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ for (InteractiveTileController tile : gamePanel.gameController.interactiveTileControllers) {
|
|
|
+ InteractiveTileModel model = tile.getModel();
|
|
|
+ int tileX = model.getWorldGridX();
|
|
|
+ int tileY = model.getWorldGridY();
|
|
|
+ int width = tile.getView().getScaleX();
|
|
|
+ int height = tile.getView().getScaleY();
|
|
|
+
|
|
|
+ boolean withinX = (worldX >= tileX && worldX < tileX + width);
|
|
|
+ boolean withinY = (worldY >= tileY && worldY < tileY + height);
|
|
|
+ if (withinX && withinY) {
|
|
|
+ return tile;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // screenToWorldX/Y assumed unchanged
|
|
|
+ public int screenToWorldX(int screenX) {
|
|
|
+ return (gamePanel.camera.worldX + screenX - gamePanel.camera.screenX) / gamePanel.tileSize;
|
|
|
+ }
|
|
|
+
|
|
|
+ public int screenToWorldY(int screenY) {
|
|
|
+ return (gamePanel.camera.worldY + screenY - gamePanel.camera.screenY) / gamePanel.tileSize;
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ */
|
|
|
+ public boolean isTileDragged(InteractiveTileController controller){
|
|
|
+ return draggingTile == controller;
|
|
|
+ }
|
|
|
+ public InteractiveTileController getDraggedTile() {
|
|
|
+ return draggingTile;
|
|
|
+ }
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|