Browse Source

Merge branch 'master' of http://git.famrupp.de/schule/tiny_settlement_schule

Oskar Berger 5 months ago
parent
commit
28eeeb52d9

+ 46 - 12
src/main/java/controller/GameController.java

@@ -18,18 +18,22 @@ import model.items.ITEM_NAME;
 import model.tiles.InteractiveTileModel;
 import model.tiles.InteractiveTileType;
 import util.GAMESTATE;
+import util.WorldGenerator;
+import util.economy.EconomyData;
 import view.GamePanel;
 import view.sound.SoundManager;
 
+import javax.swing.*;
 import java.io.Serializable;
 import java.util.ArrayList;
+import java.util.Map;
 
 /**
  * Controls the main game loop, input handling, entities, and interactive tiles.
  */
 public class GameController implements Runnable, Serializable {
 
-    public final String worldPath = "gamefiles/worlds/world_0.txt";
+    public final String worldPath = "gamefiles/worlds/world.txt";
     private GameModel gameModel;
     private boolean running = true;
     public final int fps = 60;
@@ -43,20 +47,13 @@ public class GameController implements Runnable, Serializable {
     public transient ArrayList<EntityController> entityControllers;
     public transient ArrayList<InteractiveTileController> interactiveTileControllers;
     private transient boolean gameActive;
+    private transient JFrame window;
 
     /**
      * Constructs a GameController, sets up model, view, input, inventory, entities, and interactive tiles.
      */
     public GameController() {
-        initModel();
-        initView();
-        initInputHandler();
-        initControllerLists();
-        initializeStartInventory();
-        initializeInteractiveTiles();
-        initializeEntities();
-        initResourceManager();
-        initShopController();
+        initEverything();
         view.loadMap(worldPath);
     }
 
@@ -71,6 +68,7 @@ public class GameController implements Runnable, Serializable {
      * Creates a new ResourceManager
      */
     private void initResourceManager() {
+        if(ressourceManager != null) ressourceManager.stop();
         ressourceManager = new RessourceManager(this);
         ressourceManager.start();
     }
@@ -92,7 +90,7 @@ public class GameController implements Runnable, Serializable {
     /**
      * Initializes the key handler.
      */
-    private void initInputHandler() {
+    private void initKeyHandler() {
         this.keyHandler = new KeyHandler(this);
     }
 
@@ -222,7 +220,8 @@ public class GameController implements Runnable, Serializable {
     /**
      * Starts the main game loop and resource manager thread.
      */
-    public void startGameLoop() {
+    public void startGameLoop(JFrame window) {
+        this.window = window;
         gameActive = true;
         gameThread = new Thread(this, "GameLoopThread");
         gameThread.start();
@@ -476,5 +475,40 @@ public class GameController implements Runnable, Serializable {
     public void toggleShop() {
         getView().toggleShop();
     }
+
+    public void makeNewGame() {
+        window.remove(view);
+        initEverything();
+
+        WorldGenerator.generateNewWorld(view.maxScreenCol, view.maxScreenRow);
+        view.gameState = GAMESTATE.PLAY;
+
+        view.loadMap(worldPath);
+        window.add(view);
+        window.pack();
+        view.requestFocusInWindow();
+    }
+    private void initEverything(){
+        initModel();
+        initView();
+        initKeyHandler();
+        initControllerLists();
+        initializeStartInventory();
+        initializeInteractiveTiles();
+        initializeEntities();
+        initResourceManager();
+        initShopController();
+    }
+
+    public boolean hasAllResources(EconomyData data, int controllerLevel) {
+        boolean hasAllResources = true;
+        for(Map.Entry<ITEM_NAME, Integer> map : data.getCosts().get(controllerLevel).entrySet()){
+            if(getModel().getInventory().hasEnough(map.getKey(), map.getValue())){
+                hasAllResources = false;
+            }
+        }
+        return hasAllResources;
+    }
+
 }
 

+ 11 - 4
src/main/java/controller/tiles/interactive/upgradeable/SawmillController.java

@@ -2,12 +2,17 @@ package controller.tiles.interactive.upgradeable;
 
 import controller.GameController;
 import controller.tiles.interactive.InteractiveTileController;
+import model.items.ITEM_NAME;
 import model.tiles.InteractiveTileModel;
 import util.Translator;
+import util.economy.EconomyData;
+import util.economy.EconomyInfo;
 import view.popUpMenu.PopupMenu;
 import view.popUpMenu.UpgradeMenu;
 import view.tile.interactive.SawmillView;
 
+import java.util.Map;
+
 public class SawmillController extends InteractiveTileController {
 
     public SawmillController(GameController gc, InteractiveTileModel model) {
@@ -20,12 +25,14 @@ public class SawmillController extends InteractiveTileController {
 
     @Override
     public void upgrade() {
-        boolean condition = false;
-        if(condition){
-            getModel().upgrade();
+        EconomyData data = EconomyInfo.infoOf(getModel().getTileType());
+        int controllerLevel = getModel().getLevel();
+        if(data.getMaxLevel() < controllerLevel
+        && gameController.hasAllResources(data, controllerLevel)
+        && gameController.getModel().getLightHouseLevel() >= data.getRequiredLighthouseLevels().get(controllerLevel)){
+           getModel().upgrade();
         }
     }
-
     @Override
     public void collect() {
         gameController.addToInventory(getModel().collect());

+ 6 - 2
src/main/java/main/Main.java

@@ -2,6 +2,7 @@ package main;
 
 import controller.GameController;
 import model.GameSaver;
+import util.Settings;
 import util.Translator;
 import util.economy.EconomyInfo;
 import view.GamePanel;
@@ -23,7 +24,8 @@ public class Main {
         mm.playBackgroundMusic("sound/background/background.wav", true);
 
         GameController gameController = GameSaver.loadGame();
-
+        Settings settings = gameController.getModel().getSettings();
+        settings.loadCorrectTranslation();
         //gameController.generateNewWorld();
 
         GamePanel gamePanel = gameController.getView();
@@ -33,9 +35,11 @@ public class Main {
         JFrame window = new JFrame();
         window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
         window.setResizable(false);
+
         window.setTitle(Translator.translate("game.title"));
 
         window.setPreferredSize(gamePanel.getPreferredSize());
+
         window.add(gamePanel);
 
         window.pack();
@@ -43,6 +47,6 @@ public class Main {
         window.setLocationRelativeTo(null);
         window.setVisible(true);
 
-        gameController.startGameLoop();
+        gameController.startGameLoop(window);
     }
 }

+ 18 - 0
src/main/java/model/GameModel.java

@@ -1,7 +1,10 @@
 package model;
 
+import controller.tiles.interactive.upgradeable.LighthouseController;
 import model.entity.EntityModel;
 import model.tiles.InteractiveTileModel;
+import model.tiles.InteractiveTileType;
+import util.Settings;
 
 import java.io.Serializable;
 import java.util.ArrayList;
@@ -10,9 +13,11 @@ public class GameModel implements Serializable {
     private Inventory inventory;
     private ArrayList<InteractiveTileModel> interactiveTileModels = new ArrayList<>();
     private ArrayList<EntityModel> entityModels = new ArrayList<>();
+    private Settings settings;
 
     public GameModel() {
         inventory = new Inventory();
+        settings = new Settings();
     }
 
     public Inventory getInventory() {
@@ -34,4 +39,17 @@ public class GameModel implements Serializable {
     public void addEntityModel(EntityModel model) {
         entityModels.add(model);
     }
+
+    public Settings getSettings() {
+        return settings;
+    }
+
+    public int getLightHouseLevel() {
+        for(InteractiveTileModel model : interactiveTileModels){
+            if(model.getTileType() == InteractiveTileType.LIGHTHOUSE){
+                return model.getLevel();
+            }
+        }
+        return 0;
+    }
 }

+ 12 - 0
src/main/java/model/tiles/BackgroundTile.java

@@ -3,5 +3,17 @@ package model.tiles;
 import model.Tile;
 
 public class BackgroundTile extends Tile {
+    private boolean solid = true;
 
+    /**
+     *
+     * @return True if something can be placed on this Tile
+     */
+    public boolean isSolid(){
+        return solid;
+    }
+
+    public void setSolid(boolean solid){
+        this.solid = solid;
+    }
 }

+ 1 - 1
src/main/java/util/GAMESTATE.java

@@ -5,5 +5,5 @@ public enum GAMESTATE {
     PAUSED,
     INVENTORY,
     QUIT,
-    MAIN_MENU, SHOP, SETTINGS, SAVE
+    MAIN_MENU, SHOP, SETTINGS, NEW_GAME, LOAD_GAME, SAVE
 }

+ 11 - 1
src/main/java/util/Settings.java

@@ -3,7 +3,9 @@ package util;
 import view.sound.MusicManager;
 import view.sound.SoundManager;
 
-public class Settings {
+import java.io.Serializable;
+
+public class Settings implements Serializable {
     private static float volume = 100;
     private static String language = "DE";
     private static boolean fullscreen = true;
@@ -28,4 +30,12 @@ public class Settings {
     public static void toggleFullscreen() {
         fullscreen = !fullscreen;
     }
+
+    public void loadCorrectTranslation() {
+        if(language == "DE"){
+            Translator.set_de_de();
+        }else if(language == "EN"){
+            Translator.set_en_us();
+        }
+    }
 }

+ 173 - 125
src/main/java/util/WorldGenerator.java

@@ -8,176 +8,224 @@ import java.util.*;
 
 public class WorldGenerator {
     private static int worldGenNumber = 0;
+    private static final int TILE_GRASS = 0;
+    private static final int TILE_PATH = 5;
+    private static final int TILE_WATER = 2;
+    private static final int TILE_TREE = 4;
+    private static final int TILE_EARTH = 3;
+
+    public static int getWorldGenNumber(){
+        return worldGenNumber;
+    }
 
-    public static String generateNewWorld(int worldWidth, int worldHeight, int seed) {
+    public static String generateNewWorld(int width, int height, long seed) {
         Random rand = new Random(seed);
-        int[][] world = new int[worldHeight][worldWidth];
-        initializeWorld(world);
-        createMainPath(world, worldWidth, worldHeight, rand);
-        addSecondaryPaths(world, worldWidth, worldHeight, rand);
-        addWater(world, worldWidth, worldHeight, rand);
-        addTrees(world, worldWidth, worldHeight, rand);
-        addEarthPatches(world, worldWidth, worldHeight, rand);
-        return writeWorldToFile(world, worldWidth, worldHeight);
+        int[][] world = new int[height][width];
+        fill(world, TILE_GRASS);
+
+        // 1) Roads: random walks for realistic winding one-tile paths
+        generateTrails(world, width, height, rand);
+
+        // 2) Earth clusters (fewer patches)
+        generateEarthClusters(world, width, height, rand, 10, 4);
+
+        // 3) Tree clusters (denser forests)
+        addTreeClusters(world, width, height, rand, 15);
+
+        // 4) Coastline & lakes
+        generateCoastline(world, width, height, rand);
+        addInteriorLakes(world, width, height, rand, 3);
+
+        return writeToFile(world, width, height);
     }
 
-    private static void initializeWorld(int[][] world) {
-        for (int[] row : world) {
-            Arrays.fill(row, 0); // Fill with grass
-        }
+    public static String generateNewWorld(int width, int height) {
+        return generateNewWorld(width, height, System.currentTimeMillis());
     }
 
-    private static void createMainPath(int[][] world, int width, int height, Random rand) {
-        int startX = width / 2;
-        int startY = height / 2;
-        // Create a winding main path with multiple segments
-        drunkardsWalk(world, startX, startY, 300, width, height, rand, true);
+    private static void fill(int[][] world, int tile) {
+        for (int[] row : world) Arrays.fill(row, tile);
     }
 
-    private static void addSecondaryPaths(int[][] world, int width, int height, Random rand) {
-        int numBranches = 10;
-        for (int i = 0; i < numBranches; i++) {
-            // Find a random point on the existing path
-            int startX, startY;
+    // ===== TRAILS =====
+    private static void generateTrails(int[][] world, int width, int height, Random rand) {
+        int numTrails = 6; // increased number of trails
+        for (int i = 0; i < numTrails; i++) {
+            int sx = rand.nextInt(width);
+            int sy = rand.nextInt(height);
+            // end point another random but ensure sufficient distance
+            int tx, ty;
             do {
-                startX = rand.nextInt(width);
-                startY = rand.nextInt(height);
-            } while (world[startY][startX] != 5);
+                tx = rand.nextInt(width);
+                ty = rand.nextInt(height);
+            } while (Math.abs(sx - tx) + Math.abs(sy - ty) < Math.max(width, height) / 5);
+            carveTrail(world, sx, sy, tx, ty, rand);
+        }
+    }
 
-            drunkardsWalk(world, startX, startY, 50 + rand.nextInt(50), width, height, rand, false);
+    private static void carveTrail(int[][] world, int sx, int sy, int tx, int ty, Random rand) {
+        int cx = sx, cy = sy;
+        int maxSteps = (Math.abs(sx - tx) + Math.abs(sy - ty)) * 2;
+        for (int i = 0; i < maxSteps; i++) {
+            world[cy][cx] = TILE_PATH;
+            if (Math.abs(cx - tx) + Math.abs(cy - ty) < 2) break;
+            // direction toward target
+            int dx = Integer.compare(tx, cx);
+            int dy = Integer.compare(ty, cy);
+            // random offset more frequently
+            if (rand.nextDouble() < 0.4) {
+                if (rand.nextBoolean()) dx = 0;
+                else dy = 0;
+            }
+            // apply move
+            cx = Math.max(0, Math.min(world[0].length - 1, cx + dx));
+            cy = Math.max(0, Math.min(world.length - 1, cy + dy));
+            // increased chance for side branches
+            if (rand.nextDouble() < 0.1) carveShortBranch(world, cx, cy, rand, 15 + rand.nextInt(15));
         }
     }
 
-    private static void drunkardsWalk(int[][] world, int startX, int startY, int steps,
-                                      int width, int height, Random rand, boolean isMain) {
-        int x = startX;
-        int y = startY;
-        for (int i = 0; i < steps; i++) {
-            int dir = rand.nextInt(4);
-            switch (dir) {
-                case 0 -> x = Math.min(x + 1, width - 1);
-                case 1 -> x = Math.max(x - 1, 0);
-                case 2 -> y = Math.min(y + 1, height - 1);
-                case 3 -> y = Math.max(y - 1, 0);
+    private static void carveShortBranch(int[][] world, int cx, int cy, Random rand, int steps) {
+        int bx = cx, by = cy;
+        for (int b = 0; b < steps; b++) {
+            world[by][bx] = TILE_PATH;
+            int d = rand.nextInt(4);
+            switch (d) {
+                case 0 -> bx = Math.min(bx + 1, world[0].length - 1);
+                case 1 -> bx = Math.max(bx - 1, 0);
+                case 2 -> by = Math.min(by + 1, world.length - 1);
+                case 3 -> by = Math.max(by - 1, 0);
             }
-            world[y][x] = 5; // Set to path
-
-            // Randomly widen path
-            if (rand.nextDouble() < (isMain ? 0.4 : 0.3)) {
-                int widen = rand.nextInt(2) + 1;
-                for (int dx = -widen; dx <= widen; dx++) {
-                    for (int dy = -widen; dy <= widen; dy++) {
-                        if (x + dx >= 0 && x + dx < width && y + dy >= 0 && y + dy < height) {
-                            if (world[y + dy][x + dx] == 0) {
-                                world[y + dy][x + dx] = 5;
-                            }
-                        }
+        }
+    }
+
+    // ===== EARTH CLUSTERS =====
+    private static void generateEarthClusters(int[][] world, int width, int height,
+                                              Random rand, int clusters, int maxSize) {
+        for (int i = 0; i < clusters; i++) {
+            int cx = rand.nextInt(width);
+            int cy = rand.nextInt(height);
+            int size = 1 + rand.nextInt(maxSize);
+            for (int dx = -size; dx <= size; dx++) {
+                for (int dy = -size; dy <= size; dy++) {
+                    if (cx + dx < 0 || cx + dx >= width || cy + dy < 0 || cy + dy >= height) continue;
+                    if (Math.hypot(dx, dy) < size && rand.nextDouble() < 0.4) {
+                        if (world[cy + dy][cx + dx] == TILE_GRASS) world[cy + dy][cx + dx] = TILE_EARTH;
                     }
                 }
             }
         }
     }
 
-    private static void addWater(int[][] world, int width, int height, Random rand) {
-        for (int i = 0; i < 5; i++) {
-            int x = rand.nextInt(width);
-            int y = rand.nextInt(height);
-            if (world[y][x] == 0) {
-                floodFill(world, x, y, 2, 50 + rand.nextInt(50), width, height);
+    // ===== TREE CLUSTERS =====
+    private static void addTreeClusters(int[][] world, int width, int height,
+                                        Random rand, int clusters) {
+        for (int i = 0; i < clusters; i++) {
+            int tx = rand.nextInt(width);
+            int ty = rand.nextInt(height);
+            int size = 3 + rand.nextInt(3);
+            for (int dx = -size; dx <= size; dx++) {
+                for (int dy = -size; dy <= size; dy++) {
+                    if (tx + dx < 0 || tx + dx >= width || ty + dy < 0 || ty + dy >= height) continue;
+                    if (world[ty + dy][tx + dx] == TILE_GRASS && rand.nextDouble() < 0.75) world[ty + dy][tx + dx] = TILE_TREE;
+                }
             }
         }
     }
 
-    private static void floodFill(int[][] world, int x, int y, int tile, int maxSize, int width, int height) {
-        Queue<Point> queue = new LinkedList<>();
-        Set<Point> visited = new HashSet<>();
-        queue.add(new Point(x, y));
-        int filled = 0;
-
-        while (!queue.isEmpty() && filled < maxSize) {
-            Point p = queue.poll();
-            if (visited.contains(p)) continue;
-            visited.add(p);
-
-            if (world[p.y][p.x] == 0) {
-                world[p.y][p.x] = tile;
-                filled++;
-                // Add neighbors
-                if (p.x > 0) queue.add(new Point(p.x - 1, p.y));
-                if (p.x < width - 1) queue.add(new Point(p.x + 1, p.y));
-                if (p.y > 0) queue.add(new Point(p.x, p.y - 1));
-                if (p.y < height - 1) queue.add(new Point(p.x, p.y + 1));
+    // ===== COASTLINE =====
+    private static void generateCoastline(int[][] world, int width, int height, Random rand) {
+        int borderMax = Math.min(width, height) / 40;
+        double centerX = width / 2.0, centerY = height / 2.0;
+        double baseRadius = Math.min(width, height) / 2.0;
+        double maxRadius = baseRadius - borderMax * 0.75;
+        double[] radiusMap = generateRadiusMap(720, borderMax, rand);
+        for (int y = 0; y < height; y++) {
+            for (int x = 0; x < width; x++) {
+                double dx = x - centerX, dy = y - centerY;
+                double dist = Math.hypot(dx, dy);
+                int angle360 = (int) (Math.toDegrees(Math.atan2(dy, dx)) + 360) % 360;
+                int idx = (int) (angle360 * (radiusMap.length / 360.0));
+                double jitter = radiusMap[idx] * 0.8;
+                double noise = (rand.nextDouble() - 0.5) * borderMax * 1.5;
+                double threshold = maxRadius - jitter + noise;
+                if (dist > threshold) world[y][x] = TILE_WATER;
+                else if (rand.nextDouble() < 0.015 && dist > threshold * 0.85) world[y][x] = TILE_WATER;
             }
         }
     }
 
-    private static void addTrees(int[][] world, int width, int height, Random rand) {
-        for (int i = 0; i < 10; i++) {
-            int x = rand.nextInt(width);
-            int y = rand.nextInt(height);
-            if (world[y][x] == 0) {
-                generateTreeCluster(world, x, y, 4 + rand.nextInt(4), width, height, rand);
-            }
+    private static double[] generateRadiusMap(int resolution, int maxOffset, Random rand) {
+        double[] map = new double[resolution];
+        map[0] = map[resolution/2] = maxOffset;
+        subdivide(map, 0, resolution/2, maxOffset, rand);
+        subdivide(map, resolution/2, resolution, maxOffset, rand);
+        for (int i = 0; i < resolution; i += resolution/8) {
+            int spike = rand.nextInt(resolution);
+            map[spike] += rand.nextDouble() * maxOffset * 1.2;
         }
+        return map;
     }
 
-    private static void generateTreeCluster(int[][] world, int x, int y, int size,
-                                            int width, int height, Random rand) {
-        for (int dx = -size; dx <= size; dx++) {
-            for (int dy = -size; dy <= size; dy++) {
-                if (x + dx >= 0 && x + dx < width && y + dy >= 0 && y + dy < height) {
-                    double dist = Math.sqrt(dx*dx + dy*dy);
-                    if (dist <= size && rand.nextDouble() < 0.7 - (dist / size) * 0.4) {
-                        if (world[y + dy][x + dx] == 0) {
-                            world[y + dy][x + dx] = 4;
-                        }
-                    }
-                }
-            }
+    private static void subdivide(double[] arr, int left, int right, double offset, Random rand) {
+        if (right - left < 2) return;
+        int mid = (left + right) / 2;
+        double a = arr[left];
+        double b = arr[right % arr.length];
+        arr[mid] = (a + b) / 2 + (rand.nextDouble() * 2 - 1) * offset;
+        double newOffset = offset * 0.7;
+        subdivide(arr, left, mid, newOffset, rand);
+        subdivide(arr, mid, right, newOffset, rand);
+    }
+
+    // ===== INTERIOR LAKES =====
+    private static void addInteriorLakes(int[][] world, int width, int height, Random rand, int lakes) {
+        for (int i = 0; i < lakes; i++) {
+            int lx = rand.nextInt(width);
+            int ly = rand.nextInt(height);
+            int size = 5 + rand.nextInt(10);
+            floodFill(world, lx, ly, TILE_WATER, size);
         }
     }
 
-    private static void addEarthPatches(int[][] world, int width, int height, Random rand) {
-        for (int i = 0; i < width * height / 20; i++) {
-            int x = rand.nextInt(width);
-            int y = rand.nextInt(height);
-            if (world[y][x] == 0) {
-                world[y][x] = 3; // Earth
+    private static void floodFill(int[][] world, int x, int y, int tile, int maxSize) {
+        Queue<int[]> q = new LinkedList<>();
+        Set<Long> visited = new HashSet<>();
+        q.add(new int[]{x, y});
+        int filled = 0;
+        int w = world[0].length, h = world.length;
+        while (!q.isEmpty() && filled < maxSize) {
+            int[] p = q.poll();
+            int px = p[0], py = p[1];
+            long key = (((long) px) << 32) | py;
+            if (visited.contains(key)) continue;
+            visited.add(key);
+            if (px < 0 || px >= w || py < 0 || py >= h) continue;
+            if (world[py][px] == TILE_GRASS) {
+                world[py][px] = tile;
+                filled++;
+                q.add(new int[]{px-1, py}); q.add(new int[]{px+1, py});
+                q.add(new int[]{px, py-1}); q.add(new int[]{px, py+1});
             }
         }
     }
 
-    private static String writeWorldToFile(int[][] world, int width, int height) {
-        String fileName = "gamefiles/worlds/world_" + worldGenNumber++ + ".txt";
+    // ===== OUTPUT =====
+    private static String writeToFile(int[][] world, int width, int height) {
+        String dir = "gamefiles/worlds";
+        new File(dir).mkdirs();
+        String fileName = dir + "/world.txt";
         try (PrintWriter writer = new PrintWriter(new File(fileName))) {
             for (int[] row : world) {
-                StringBuilder sb = new StringBuilder();
-                for (int i = 0; i < row.length; i++) {
-                    sb.append(i > 0 ? " " : "").append(row[i]);
+                for (int i = 0; i < width; i++) {
+                    writer.print(row[i] + (i < width-1 ? " " : ""));
                 }
-                writer.println(sb);
+                writer.println();
             }
         } catch (IOException e) {
             e.printStackTrace();
         }
         return fileName;
     }
-
-    private static class Point {
-        int x, y;
-        Point(int x, int y) { this.x = x; this.y = y; }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (o == null || getClass() != o.getClass()) return false;
-            Point point = (Point) o;
-            return x == point.x && y == point.y;
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(x, y);
-        }
-    }
 }
+

+ 8 - 2
src/main/java/view/GamePanel.java

@@ -86,7 +86,7 @@ public class GamePanel extends JPanel{
         this.addKeyListener(controller.getKeyHandler()); // now safe
         this.setFocusable(true);
 
-        gameState = GAMESTATE.PLAY;
+        gameState = GAMESTATE.MAIN_MENU;
     }
     public void loadMap(String worldPath){
         tileManager.loadMap(worldPath);
@@ -137,7 +137,13 @@ public class GamePanel extends JPanel{
         super.paintComponent(g);
         g2 = (Graphics2D) g;
 
-
+        if(gameState == GAMESTATE.NEW_GAME){
+            gameController.makeNewGame();
+            gameState = GAMESTATE.PLAY;
+        }else if(gameState == GAMESTATE.LOAD_GAME){
+            gameController.loadGame();
+            gameState = GAMESTATE.PLAY;
+        }
 
         tileManager.draw(g2);
         entityManager.draw(g2);

+ 16 - 8
src/main/java/view/tile/TileManager.java

@@ -16,7 +16,7 @@ import java.io.*;
 public class TileManager implements RenderingManager {
 
     private GamePanel gamePanel;
-    private Tile[] tile;
+    private BackgroundTile[] tile;
     private int[][] mapTileNum;
     private int mapTileOverflow = 1;
     private InteractiveTileController draggingTile;
@@ -24,7 +24,7 @@ public class TileManager implements RenderingManager {
 
     public TileManager(GamePanel gp){
         this.gamePanel = gp;
-        tile = new Tile[10];
+        tile = new BackgroundTile[10];
         mapTileNum = new int[GamePanel.maxWorldCol][GamePanel.maxWorldRow];
         getTileImage();
     }
@@ -65,7 +65,6 @@ public class TileManager implements RenderingManager {
         }catch (Exception e){
             System.out.println("Couldn't find world path... Creating new World...");
             gamePanel.generateNewWorld();
-
         }
     }
 
@@ -149,10 +148,10 @@ public class TileManager implements RenderingManager {
         try{
             setupTile(0, "grass");
             setupTile(1, "wall");
-            setupTile(2, "water");
+            setupTile(2, "water", false);
             setupTile(3, "earth");
 
-            setupTile(4, "tree");
+            setupTile(4, "tree", false);
 
             setupTile(5, "sand");
 
@@ -160,14 +159,16 @@ public class TileManager implements RenderingManager {
             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 {
+    private void setupTile(int index, String path, boolean solid) throws IOException {
         tile[index] = new BackgroundTile();
-        tile[index].setImage("/tiles/" + path + ".png");
+        tile[index].setImage("/tiles/background/" + path + ".png");
+        tile[index].setSolid(solid);
     }
 
     public void generateNewWorld() {
@@ -257,13 +258,20 @@ public class TileManager implements RenderingManager {
         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) {
+                BackgroundTile bg = getBackgroundTileAt(x,y);
+                if ((other != null && other != draggingTile) || !bg.isSolid()) {
                     return false;
                 }
             }
         }
         return true;
     }
+
+    private BackgroundTile getBackgroundTileAt(int newX, int newY) {
+        int tileNum = mapTileNum[newX][newY];
+        return tile[tileNum];
+    }
+
     /**
      * Returns the InteractiveTileController at the specified grid coordinates, or null if none.
      *

+ 6 - 1
src/main/java/view/ui/menu/MainMenu.java

@@ -14,8 +14,13 @@ public class MainMenu extends AbstractMenu {
     public void draw(Graphics2D g2){
         this.g2 = g2;
         Button newGameButton = new Button(100, 100, "New Game", () -> {
-            gp.gameState = GAMESTATE.PLAY;
+            gp.gameState = GAMESTATE.NEW_GAME;
         });
         drawAndRegisterButton(newGameButton, 10, 10);
+
+        Button savedGameButton = new Button(100, 100, "Load Game", () -> {
+            gp.gameState = GAMESTATE.PLAY;
+        });
+        drawAndRegisterButton(savedGameButton, 120, 10);
     }
 }

+ 0 - 1
src/main/java/view/ui/menu/PauseMenu.java

@@ -4,7 +4,6 @@ import util.GAMESTATE;
 import util.Translator;
 import view.GamePanel;
 import view.components.Button;
-import view.ui.UI;
 
 import java.awt.*;
 

+ 0 - 8
src/main/java/view/ui/menu/SettingsMenu.java

@@ -64,14 +64,6 @@ public class SettingsMenu extends AbstractMenu {
                 });
         drawAndRegisterButton(langButton, buttonX, langY);
 
-        // Fullscreen Toggle
-        Button fullscreenButton = new Button(buttonWidth, buttonHeight,
-                Translator.translate("settings.fullscreen") + ": " + (Settings.isFullscreen() ? "On" : "Off"),
-                () -> {
-                    Settings.toggleFullscreen();
-                });
-        drawAndRegisterButton(fullscreenButton, buttonX, fullscreenY);
-
         // Back button
         Button backButton = new Button(buttonWidth, buttonHeight,
                 Translator.translate("menu.back"), () -> {