diff --git a/Zoelda/src/main/DoorTile.java b/Zoelda/src/main/DoorTile.java new file mode 100644 index 0000000..f080961 --- /dev/null +++ b/Zoelda/src/main/DoorTile.java @@ -0,0 +1,51 @@ +package main; + +import ea.Ticker; +import main.entities.player.Player; +import main.maps.ImageMap; + +public class DoorTile extends Tile implements Ticker { + + public static final int TOP = 0; + public static final int BOTTOM = 1; + public static final int LEFT = 2; + public static final int RIGHT = 3; + + private int side; + private DoorTile connected; + private ImageMap map; + + public DoorTile(float x, float y, ImageMap map) { + super(Tile.DOOR, x, y); + this.map = map; + + Main.instance.tickerAnmelden(this, 50); + } + + @Override + public void tick() { + if (Main.instance.getWorld() != null) { + Player player = Main.instance.getWorld().getPlayer(); + float dist = player.dist(posX + 0.5f, posY + 0.5f); + if (dist < 0.5f) { + Main.instance.getWorld().changeMap(this); + } + } + } + + public int getSide() { + return side; + } + + public void setSide(int side) { + this.side = side; + } + + public void setConnectedDoor(DoorTile door) { + connected = door; + } + + public ImageMap getMap() { + return map; + } +} diff --git a/Zoelda/src/main/Tile.java b/Zoelda/src/main/Tile.java index 76ea94a..0dd8b69 100644 --- a/Zoelda/src/main/Tile.java +++ b/Zoelda/src/main/Tile.java @@ -20,37 +20,46 @@ public class Tile extends Knoten { public static final int STONE_WALL = 3; public static final int STONE_WALL_BOTTOM = 4; public static final int STONE_FLOOR = 5; + public static final int VOID = 6; + public static final int DOOR = 7; private Bild img; // Bild, das gerendert wird private int id; // Die id dises Tiles + protected float posX, posY; // Position dieses Tiles /** * @param id - * @param x - X-Koordinate in units - * @param y - Y-Koordinate in units + * @param x - X-Koordinate in units + * @param y - Y-Koordinate in units */ public Tile(int id, float x, float y) { this.id = id; + posX = x; + posY = y; - // Das Bild laden - try { - BufferedImage buff = ImageIO.read(Tile.class.getResourceAsStream(getPathFromId(id))); - // Gras hat 8 verschiedene Texturen von denen eine zufällig ausgewählt werden - // muss. - if (id == GRASS) { - buff = buff.getSubimage(16 * (int) (Math.random() * 8), 0, 16, 16); + if (id == VOID) { + BufferedImage buff = new BufferedImage(World.SCALE, World.SCALE, BufferedImage.TYPE_INT_RGB); + img = new Bild(x * World.SCALE, y * World.SCALE, buff); + } else { + // Das Bild laden + try { + BufferedImage buff = ImageIO.read(Tile.class.getResourceAsStream(getPathFromId(id))); + // Gras hat 8 verschiedene Texturen von denen eine zufällig ausgewählt werden + // muss. + if (id == GRASS) { + buff = buff.getSubimage(16 * (int) (Math.random() * 8), 0, 16, 16); + } + // if (id == STONE_FLOOR) { + // buff = buff.getSubimage(16 * (int) (Math.random() * 10), 0, 16, 16); + // } + // Skalieren + BufferedImage scaled = new BufferedImage(World.SCALE, World.SCALE, BufferedImage.TYPE_INT_RGB); + scaled.getGraphics().drawImage(buff, 0, 0, World.SCALE, World.SCALE, null); + img = new Bild(x * World.SCALE, y * World.SCALE, scaled); + + } catch (IOException e) { + e.printStackTrace(); } - //if (id == STONE_FLOOR) { - // buff = buff.getSubimage(16 * (int) (Math.random() * 10), 0, 16, 16); - //} - // Skalieren - BufferedImage scaled = new BufferedImage(World.SCALE, World.SCALE, BufferedImage.TYPE_INT_RGB); - scaled.getGraphics().drawImage(buff, 0, 0, World.SCALE, World.SCALE, null); - img = new Bild(x * World.SCALE, y * World.SCALE, scaled); - - - } catch (IOException e) { - e.printStackTrace(); } // Bild zu EA hinzufügen. add(img); @@ -73,6 +82,8 @@ public class Tile extends Knoten { return "/res/images/tiles/stone_wall_bottom.png"; case STONE_FLOOR: return "/res/images/tiles/TestTest.png"; + case DOOR: + return "/res/images/tiles/door.png"; } return null; } @@ -90,7 +101,7 @@ public class Tile extends Knoten { public boolean isCollidable() { // Alle Tiles durch die man nicht laufen soll müssen hier true zurückgeben, // sonst werden sie bei der Collisiondetection nicht berücksichtigt. - return id == WALL_TOP || id == STONE_WALL ; + return id == WALL_TOP || id == STONE_WALL; } /** @@ -120,4 +131,8 @@ public class Tile extends Knoten { public int getRight() { return positionX() + getSize(); } + + public int getID() { + return id; + } } diff --git a/Zoelda/src/main/World.java b/Zoelda/src/main/World.java index a9ecb4b..1b1d313 100644 --- a/Zoelda/src/main/World.java +++ b/Zoelda/src/main/World.java @@ -1,8 +1,11 @@ package main; +import java.util.ArrayList; + import ea.Knoten; +import main.entities.player.Player; +import main.maps.ImageMap; import main.maps.Map; -import main.maps.TutorialMap; /** * Hier werden alle Maps gespeichert. @@ -13,16 +16,43 @@ public class World extends Knoten { public static final int SCALE = SCALE_FACTOR * Tile.getSize(); // Eine Gameunit ist so viele pixel lang private Map currentMap; // Die Map die aktuell angezeigt werden soll. + private ArrayList dungeon; + + private Player player; public World() { - // Map initialisieren - currentMap = new TutorialMap(); - // Map zu EA hinzufügen + dungeon = new ArrayList<>(50); + + ImageMap start = new ImageMap("/res/images/maps/map1.png"); + dungeon.add(start); + currentMap = start; + + start.generate(dungeon); + + + player = new Player(); + currentMap.getEntities().add(player); + currentMap.add(player.actionFigur); + Main.instance.manager.anmelden(player, 20); + add(currentMap); + } public Map getCurrentMap() { return currentMap; } + + public Player getPlayer() { + return player; + } + + public void changeMap(DoorTile door) { + entfernen(currentMap); + currentMap = door.getMap(); + currentMap.add(player.actionFigur); + add(currentMap); + player.setPos(7, 5); + } } diff --git a/Zoelda/src/main/entities/Entity.java b/Zoelda/src/main/entities/Entity.java index 19aeb4a..1d25735 100644 --- a/Zoelda/src/main/entities/Entity.java +++ b/Zoelda/src/main/entities/Entity.java @@ -112,6 +112,13 @@ public abstract class Entity implements Ticker { return (float) Math.sqrt((e.posX - posX) * (e.posX - posX) + (e.posY - posY) * (e.posY - posY)); } + /** + * @return die entifernung zu dieser Koordinate + */ + public float dist(float x, float y) { + return (float) Math.sqrt((x - posX) * (x - posX) + (y - posY) * (y - posY)); + } + /** * Generiert einen vektor von diesm Entity zu einem anderen */ @@ -175,6 +182,19 @@ public abstract class Entity implements Ticker { this.velY = velY; } + public void setPosX(float x) { + posX = x; + } + + public void setPosY(float y) { + posY = y; + } + + public void setPos(float x, float y) { + posX = x; + posY = y; + } + public void deleteEntity() { deleteEntity = true; } diff --git a/Zoelda/src/main/entities/Snake.java b/Zoelda/src/main/entities/Snake.java index 1a2dc79..9a0ca7e 100644 --- a/Zoelda/src/main/entities/Snake.java +++ b/Zoelda/src/main/entities/Snake.java @@ -33,7 +33,7 @@ public class Snake extends LivingEntity { @Override protected void update() { - Player player = Main.instance.getWorld().getCurrentMap().getPlayer(); + Player player = Main.instance.getWorld().getPlayer(); if (!actionFigur.aktuellesVerhalten().equals(getDamageAnimationName())) { if (lineOfSightClear(player)) { if (dist(player) < 1f) { diff --git a/Zoelda/src/main/entities/player/Player.java b/Zoelda/src/main/entities/player/Player.java index 1150884..5097ccd 100644 --- a/Zoelda/src/main/entities/player/Player.java +++ b/Zoelda/src/main/entities/player/Player.java @@ -24,8 +24,8 @@ public class Player extends LivingEntity { height = 0.8f; spriteOffsetY = -0.14f; spriteScale = 0.8f; - posX = 4f; - posY = 4f; + posX = 7.5f; + posY = 5.5f; // unterschiedliche Animationsgeschwindigkeiten // für idle diff --git a/Zoelda/src/main/maps/Corridor.java b/Zoelda/src/main/maps/Corridor.java index 072c6fd..957d88b 100644 --- a/Zoelda/src/main/maps/Corridor.java +++ b/Zoelda/src/main/maps/Corridor.java @@ -2,31 +2,37 @@ package main.maps; import main.Tile; -import main.entities.Snake; - public class Corridor extends Map { public Corridor() { super(15, 11); - + for (int x = 0; x < map.length; x++) { for (int y = 0; y < map[0].length; y++) { - //Wand - if((y == 0 || x == 5 || y == 10 || x == 9) && x != 7 && x >= 5 && x <= 9) { - map[x][y] = new Tile(3, x, y); - add(map[x][y]); - } - //3D-Wand - else if(y == 1 && (x != 0 || x != 4)&& x != 7 && x >= 6 && x <= 8 ) { - map[x][y] = new Tile(4, x, y); + // Wand + if ((y == 0 || x == 5 || y == 10 || x == 9) && x != 7 && x >= 5 && x <= 9) { + map[x][y] = new Tile(Tile.STONE_WALL, x, y); add(map[x][y]); } - //Steinboden - else if (x >= 6 && x <= 8 ) { - map[x][y] = new Tile(5, x, y); + // 3D-Wand + else if (y == 1 && (x != 0 || x != 4) && x != 7 && x >= 6 && x <= 8) { + map[x][y] = new Tile(Tile.STONE_WALL_BOTTOM, x, y); + add(map[x][y]); + } + // Steinboden + else if (x >= 6 && x <= 8) { + if (x == 7 && (y == 0 || y == map[0].length - 1)) { + } else { + map[x][y] = new Tile(Tile.STONE_FLOOR, x, y); + add(map[x][y]); + } + } else { + map[x][y] = new Tile(Tile.VOID, x, y); add(map[x][y]); } } } + + registerEntities(); } } diff --git a/Zoelda/src/main/maps/ImageMap.java b/Zoelda/src/main/maps/ImageMap.java new file mode 100644 index 0000000..7363cb3 --- /dev/null +++ b/Zoelda/src/main/maps/ImageMap.java @@ -0,0 +1,152 @@ +package main.maps; + +import java.awt.Color; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.util.ArrayList; + +import javax.imageio.ImageIO; + +import main.DoorTile; +import main.Tile; + +public class ImageMap extends Map { + + private static PixelTile[] pixels = { new PixelTile(Tile.STONE_WALL, new Color(100, 100, 100)), + new PixelTile(Tile.STONE_FLOOR, new Color(127, 127, 127)), new PixelTile(Tile.VOID, new Color(0, 0, 0)), + new PixelTile(Tile.DOOR, new Color(255, 0, 0)) }; + + public DoorTile topDoor; + public DoorTile leftDoor; + public DoorTile rightDoor; + public DoorTile bottomDoor; + + public ImageMap(String path) { + super(15, 11); + + try { + BufferedImage img = ImageIO.read(ImageMap.class.getResourceAsStream(path)); + if (img.getWidth() != 15 || img.getHeight() != 11) { + System.err.println("Odd map size! Use 15x11"); + } + for (int x = 0; x < img.getWidth(); x++) { + for (int y = 0; y < img.getHeight(); y++) { + int id = Tile.VOID; + int rgb = img.getRGB(x, y); + for (PixelTile t : pixels) { + if (t.c == rgb) { + id = t.id; + break; + } + } + if (id == Tile.DOOR) { + DoorTile door = new DoorTile(x, y, this); + map[x][y] = door; + if (x == 7) { + if (y < 5) { + topDoor = door; + door.setSide(DoorTile.TOP); + } else { + bottomDoor = door; + door.setSide(DoorTile.BOTTOM); + } + } + if (y == 5) { + if (x < 7) { + leftDoor = door; + door.setSide(DoorTile.LEFT); + } else { + rightDoor = door; + door.setSide(DoorTile.RIGHT); + } + } + } else { + map[x][y] = new Tile(id, x, y); + } + add(map[x][y]); + } + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + private static class PixelTile { + public final int c; + public final int id; + + public PixelTile(int id, Color c) { + this.c = c.getRGB(); + this.id = id; + } + } + + public void generate(ArrayList dungeon) { + if (topDoor != null) { + ImageMap map; + do { + map = nextMap(); + } while (!connectDoors(topDoor, map)); + dungeon.add(map); + } + if (bottomDoor != null) { + ImageMap map; + do { + map = nextMap(); + } while (!connectDoors(bottomDoor, map)); + dungeon.add(map); + } + if (leftDoor != null) { + ImageMap map; + do { + map = nextMap(); + } while (!connectDoors(leftDoor, map)); + dungeon.add(map); + } + if (rightDoor != null) { + ImageMap map; + do { + map = nextMap(); + } while (!connectDoors(rightDoor, map)); + dungeon.add(map); + } + } + + private ImageMap nextMap() { + return new ImageMap("/res/images/maps/map" + ((int) (Math.random() * 7) + 1) + ".png"); + } + + private boolean connectDoors(DoorTile door, ImageMap otherMap) { + switch (door.getSide()) { + case DoorTile.TOP: + if (otherMap.bottomDoor == null) { + return false; + } + door.setConnectedDoor(otherMap.bottomDoor); + otherMap.bottomDoor.setConnectedDoor(door); + return true; + case DoorTile.BOTTOM: + if (otherMap.topDoor == null) { + return false; + } + door.setConnectedDoor(otherMap.topDoor); + otherMap.topDoor.setConnectedDoor(door); + return true; + case DoorTile.LEFT: + if (otherMap.rightDoor == null) { + return false; + } + door.setConnectedDoor(otherMap.rightDoor); + otherMap.rightDoor.setConnectedDoor(door); + return true; + case DoorTile.RIGHT: + if (otherMap.leftDoor == null) { + return false; + } + door.setConnectedDoor(otherMap.leftDoor); + otherMap.leftDoor.setConnectedDoor(door); + return true; + } + return true; + } +} diff --git a/Zoelda/src/main/maps/Map.java b/Zoelda/src/main/maps/Map.java index 3057a95..cd6ed88 100644 --- a/Zoelda/src/main/maps/Map.java +++ b/Zoelda/src/main/maps/Map.java @@ -8,7 +8,6 @@ import main.Main; import main.Tile; import main.entities.Entity; import main.entities.LivingEntity; -import main.entities.player.Player; /** * Auf der Map sind alle Entities, sowie die Tiles gespiechert. @@ -17,7 +16,7 @@ public abstract class Map extends Knoten implements Ticker { protected Tile[][] map; // Die Tiles der map in einem 2D Array. private ArrayList entities; - private Player player; + public Map(int width, int height) { map = new Tile[width][height]; @@ -64,14 +63,6 @@ public abstract class Map extends Knoten implements Ticker { return entities; } - public Player getPlayer() { - return player; - } - - public void setPlayer(Player player) { - this.player = player; - } - public void registerEntities() { for (Entity e : getEntities()) { Main.instance.manager.anmelden(e, 20); diff --git a/Zoelda/src/main/maps/TutorialMap.java b/Zoelda/src/main/maps/TutorialMap.java index 168cce2..1e0e716 100644 --- a/Zoelda/src/main/maps/TutorialMap.java +++ b/Zoelda/src/main/maps/TutorialMap.java @@ -3,7 +3,6 @@ package main.maps; import main.Tile; import main.entities.Snake; import main.entities.Spider; -import main.entities.player.Player; public class TutorialMap extends Map { @@ -28,10 +27,6 @@ public class TutorialMap extends Map { } } } - - Player player = new Player(); - add(player.actionFigur); - getEntities().add(player); // und Spinnen auch Spider spider = new Spider(); @@ -42,8 +37,6 @@ public class TutorialMap extends Map { Snake snake = new Snake(); add(snake.actionFigur); getEntities().add(snake); - - setPlayer(player); // Alle Entities als ticker registrieren (triggert dann die update methoden) registerEntities(); diff --git a/Zoelda/src/res/images/maps/map1.png b/Zoelda/src/res/images/maps/map1.png new file mode 100644 index 0000000..bea5452 Binary files /dev/null and b/Zoelda/src/res/images/maps/map1.png differ diff --git a/Zoelda/src/res/images/maps/map2.png b/Zoelda/src/res/images/maps/map2.png new file mode 100644 index 0000000..5361062 Binary files /dev/null and b/Zoelda/src/res/images/maps/map2.png differ diff --git a/Zoelda/src/res/images/maps/map3.png b/Zoelda/src/res/images/maps/map3.png new file mode 100644 index 0000000..8182b79 Binary files /dev/null and b/Zoelda/src/res/images/maps/map3.png differ diff --git a/Zoelda/src/res/images/maps/map4.png b/Zoelda/src/res/images/maps/map4.png new file mode 100644 index 0000000..a3e5eee Binary files /dev/null and b/Zoelda/src/res/images/maps/map4.png differ diff --git a/Zoelda/src/res/images/maps/map5.png b/Zoelda/src/res/images/maps/map5.png new file mode 100644 index 0000000..2c0ed6d Binary files /dev/null and b/Zoelda/src/res/images/maps/map5.png differ diff --git a/Zoelda/src/res/images/maps/map6.png b/Zoelda/src/res/images/maps/map6.png new file mode 100644 index 0000000..0c17146 Binary files /dev/null and b/Zoelda/src/res/images/maps/map6.png differ diff --git a/Zoelda/src/res/images/maps/map7.png b/Zoelda/src/res/images/maps/map7.png new file mode 100644 index 0000000..fd4ad1e Binary files /dev/null and b/Zoelda/src/res/images/maps/map7.png differ diff --git a/Zoelda/src/res/images/maps/map8.png b/Zoelda/src/res/images/maps/map8.png new file mode 100644 index 0000000..0f3cc49 Binary files /dev/null and b/Zoelda/src/res/images/maps/map8.png differ diff --git a/Zoelda/src/res/images/tiles/door.png b/Zoelda/src/res/images/tiles/door.png new file mode 100644 index 0000000..028f7b2 Binary files /dev/null and b/Zoelda/src/res/images/tiles/door.png differ