Browse Source

Mini Refactoring: Tile Dragging in GameController -> Tilemanager

Jan 6 months ago
parent
commit
39a7fda42c

+ 3 - 171
src/main/java/controller/GameController.java

@@ -385,45 +385,12 @@ public class GameController implements Runnable, Serializable {
         getView().generateNewWorld();
     }
 
-    private int originalGridX, originalGridY;
-
-    /**
-     * Called from GameMouseListener.mousePressed when starting a drag on right-click.
-     */
-    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);
-        }
-    }
-
-    /**
-     * Called from GameMouseListener.mousePressed to clear any residual state.
-     * Retained for compatibility; residual shifting no longer used for mouse drag.
-     */
-    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
-    }
-
     /**
      * 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);
+        getView().tileManager.handleTileShift(dx, dy);
     }
 
     /**
@@ -431,129 +398,9 @@ public class GameController implements Runnable, Serializable {
      * Snaps the tile to grid, validates position, reverts if invalid.
      */
     public void handleTileRelease(int mouseX, int mouseY) {
-        if (draggingTile == null) {
-            return;
-        }
-        InteractiveTileView view = draggingTile.getView();
-        InteractiveTileModel model = draggingTile.getModel();
-
-        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);
+        getView().tileManager.handleTileRelease(mouseX, mouseY);
 
-        // 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 (interactiveTileControllers == null) {
-            return null;
-        }
-        for (InteractiveTileController tile : 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;
-    }
-
-
-    // Ensure you have utility methods:
-    private int worldColToScreenX(int worldCol) {
-        GamePanel gp = getView();
-        return gp.camera.screenX + worldCol * gp.tileSize - gp.camera.worldX;
-    }
-
-    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.
@@ -594,19 +441,6 @@ public class GameController implements Runnable, Serializable {
         }
     }
 
-    /**
-     *
-     */
-    public boolean isTileDragged(InteractiveTileController controller){
-        return draggingTile == controller;
-    }
-    /**
-     *  Initializes the Main Menu for changing worlds etc.
-     */
-    public void loadMainMenu() {
-
-    }
-
     public boolean isRunning() {
         return running;
     }
@@ -615,8 +449,6 @@ public class GameController implements Runnable, Serializable {
         getModel().getInventory().addToInventory(collected);
     }
 
-    public InteractiveTileController getDraggedTile() {
-        return draggingTile;
-    }
+
 }
 

+ 6 - 6
src/main/java/controller/input/GameMouseListener.java

@@ -4,6 +4,7 @@ import controller.GameController;
 import util.GAMESTATE;
 import view.Camera;
 import view.GamePanel;
+import view.tile.TileManager;
 
 import javax.swing.*;
 import java.awt.*;
@@ -67,12 +68,11 @@ public class GameMouseListener implements MouseListener, MouseMotionListener {
     @Override
     public void mousePressed(MouseEvent e) {
         if (SwingUtilities.isRightMouseButton(e)) {
-            // Compute world coords of initial press:
-            int worldX = controller.screenToWorldX(e.getX());
-            int worldY = controller.screenToWorldY(e.getY());
-            controller.setDraggingTile(controller.getTileAt(worldX, worldY));
-            // Reset residuals:
-            controller.resetResidualShift();
+            TileManager tm = controller.getView().tileManager;
+
+            int worldX = tm.screenToWorldX(e.getX());
+            int worldY = tm.screenToWorldY(e.getY());
+            tm.setDraggingTile(tm.getTileAt(worldX, worldY));
         }
         lastY = e.getX();
         lastX = e.getY();

+ 150 - 3
src/main/java/view/tile/TileManager.java

@@ -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);
+        }
+    }
 }