| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- package view.tile;
- import controller.tiles.interactive.InteractiveTileController;
- import model.Tile;
- import model.tiles.BackgroundTile;
- import model.tiles.InteractiveTileModel;
- import util.WorldGenerator;
- import view.GamePanel;
- import view.sound.SoundManager;
- import view.tile.interactive.InteractiveTileView;
- import view.util.RenderingManager;
- import java.awt.*;
- import java.io.*;
- public class TileManager implements RenderingManager {
- private GamePanel gamePanel;
- private Tile[] tile;
- private int[][] mapTileNum;
- private int mapTileOverflow = 1;
- private InteractiveTileController draggingTile;
- private int originalGridX, originalGridY;
- public TileManager(GamePanel gp){
- this.gamePanel = gp;
- tile = new Tile[10];
- mapTileNum = new int[GamePanel.maxWorldCol][GamePanel.maxWorldRow];
- getTileImage();
- }
- public int getTileSize(){
- return gamePanel.tileSize;
- }
- public void addInteractiveTile(InteractiveTileController tile) {
- gamePanel.gameController.interactiveTileControllers.add(tile);
- }
- public void loadMap(String filePath){
- try{
- InputStream is = getClass().getResourceAsStream(filePath);
- BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath)));
- int col = 0;
- int row = 0;
- while(col < gamePanel.maxWorldCol && row < gamePanel.maxWorldRow){
- String line = br.readLine();
- while(col < gamePanel.maxWorldRow){
- String numbers[] = line.split(" ");
- int num = Integer.parseInt(numbers[col]);
- mapTileNum[col][row] = num;
- col++;
- }
- if(col == gamePanel.maxWorldCol) {
- col = 0;
- row++;
- }
- }
- br.close();
- }catch (Exception e){
- System.out.println("Couldn't find world path... Creating new World...");
- gamePanel.generateNewWorld();
- }
- }
- public void draw(Graphics2D g2){
- int worldCol = 0;
- int worldRow = 0;
- while (worldCol< gamePanel.maxWorldCol && worldRow < gamePanel.maxWorldRow){
- int tileNum = mapTileNum[worldCol][worldRow];
- int worldX = worldCol * gamePanel.tileSize;
- int worldY = worldRow * gamePanel.tileSize;
- double screenX = worldX - gamePanel.camera.worldX + gamePanel.camera.screenX;
- double screenY = worldY - gamePanel.camera.worldY + gamePanel.camera.screenY;
- if(worldX + gamePanel.tileSize*mapTileOverflow > gamePanel.camera.worldX - gamePanel.camera.screenX &&
- worldX - gamePanel.tileSize*mapTileOverflow < gamePanel.camera.worldX + gamePanel.camera.screenX &&
- worldY + gamePanel.tileSize*mapTileOverflow > gamePanel.camera.worldY - gamePanel.camera.screenY &&
- worldY - gamePanel.tileSize*mapTileOverflow < gamePanel.camera.worldY + gamePanel.camera.screenY ) {
- g2.drawImage(tile[tileNum].image, (int) screenX, (int) screenY, gamePanel.tileSize, gamePanel.tileSize, null);
- }
- worldCol++;
- if(worldCol == gamePanel.maxWorldCol){
- worldCol = 0;
- worldRow++;
- }
- }
- 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.
- */
- public void drawAllTiles(Graphics2D g2) {
- // Optionally draw non-dragged first, then dragged to render on top
- for (InteractiveTileController tile : gamePanel.gameController.interactiveTileControllers) {
- if (!isTileDragged(tile)) {
- InteractiveTileModel model = tile.getModel();
- int sx = worldColToScreenX(model.getWorldGridX());
- int sy = worldRowToScreenY(model.getWorldGridY());
- tile.getView().setScreenCoordinates(sx, sy);
- tile.drawTile(g2);
- }
- }
- if (getDraggedTile() != null) {
- // Draw dragged tile on top
- getDraggedTile().drawTile(g2);
- }
- }
- public int worldColToScreenX(int worldCol) {
- double worldX = worldCol * gamePanel.tileSize; // Reactively use tileSize
- return (int) (worldX - gamePanel.camera.worldX + gamePanel.camera.screenX);
- }
- public int worldRowToScreenY(int worldRow) {
- double worldY = worldRow * gamePanel.tileSize; // Reactively use tileSize
- return (int) (worldY - gamePanel.camera.worldY + gamePanel.camera.screenY);
- }
- public void getTileImage(){
- try{
- setupTile(0, "grass");
- setupTile(1, "wall");
- setupTile(2, "water");
- setupTile(3, "earth");
- setupTile(4, "tree");
- setupTile(5, "sand");
- }catch (IOException e){
- e.printStackTrace();
- }
- }
- private void setupTile(int index, String path) throws IOException {
- tile[index] = new BackgroundTile();
- tile[index].setImage("/tiles/background/" + path + ".png");
- }
- private void setupInteractiveTile( int index, String path) throws IOException {
- tile[index] = new BackgroundTile();
- tile[index].setImage("/tiles/" + path + ".png");
- }
- public void generateNewWorld() {
- String filePath = WorldGenerator.generateNewWorld(GamePanel.maxWorldCol, GamePanel.maxWorldRow, (int) Math.floor(Math.random()*100000));
- loadMap(filePath);
- }
- @Override
- public void drawPopup(Graphics2D g2) {
- for (InteractiveTileController tile : gamePanel.gameController.interactiveTileControllers) {
- tile.drawPopup(g2);
- }
- }
- @Override
- public void resize(int newTileSize) {
- for (InteractiveTileController tile : gamePanel.gameController.interactiveTileControllers) {
- tile.resize(newTileSize);
- }
- }
- public void handleTileRelease() {
- SoundManager.getInstance().stopLoopSound(SoundManager.SOUNDS.MOVING_BUSH);
- 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);
- }
- }
- }
|