Compare commits
79 Commits
75b28bbb11
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
865b5e0c52 | ||
|
|
d28a29df45 | ||
|
|
b85a36bf14 | ||
|
|
66d36c4ea2 | ||
|
|
d46d25115e | ||
|
|
5f0b827fab | ||
|
|
ca40e4c01a | ||
|
|
21790ecd7a | ||
|
|
da5c5571b2 | ||
|
|
af51d3776e | ||
| e818037d75 | |||
|
|
3e99a2ebc2 | ||
|
|
dc9a08c9ee | ||
|
|
58a41725eb | ||
|
|
d440ad8f67 | ||
|
|
f386ef49f6 | ||
|
|
3a65c74546 | ||
|
|
e643ec092d | ||
|
|
c035253790 | ||
| a5eed792e7 | |||
| cbc30b0ac5 | |||
|
|
d150a613c4 | ||
|
|
ec74176426 | ||
|
|
28b9404fe9 | ||
|
|
b7da4535d7 | ||
|
|
f36c861726 | ||
| 0b521ca667 | |||
| 1f1f5bbc68 | |||
|
|
12c57e1c3c | ||
|
|
52a59d2808 | ||
|
|
657c7bab9e | ||
|
|
23eba51e5c | ||
|
|
1555acd781 | ||
|
|
4f76c1eaa8 | ||
| 08a67a8a24 | |||
| 595b9b26d9 | |||
| a0f632608a | |||
| fc17421e0b | |||
|
|
a6726b5e25 | ||
|
|
88580aec12 | ||
|
|
9e6dca2a43 | ||
|
|
a0abdd8aa8 | ||
| 0d2d9c8dbf | |||
| d6acbbec29 | |||
| 74e82abbb0 | |||
| 805ae2a960 | |||
|
|
e19165c6c8 | ||
| 83120aef20 | |||
| 8cdf1c22d4 | |||
|
|
71621b0110 | ||
|
|
b63f505030 | ||
|
|
54641a4c29 | ||
|
|
06432bd55b | ||
|
|
fa21364a3f | ||
|
|
2f0aea175c | ||
|
|
9fda8275f8 | ||
|
|
bdff9e5ffb | ||
|
|
4b630769d5 | ||
|
|
eefbd17b26 | ||
|
|
4e6e4198f4 | ||
|
|
39e7e91dd4 | ||
|
|
4cd9c2559a | ||
| 88369aed53 | |||
|
|
6a100c8b88 | ||
|
|
1bb7c7ca7a | ||
|
|
d747e1f94c | ||
|
|
e415e7cbbb | ||
|
|
0a6d76da3a | ||
| 371a4b8be4 | |||
| 91aadb61e6 | |||
| dec597e550 | |||
| 351240b464 | |||
| 953aa20d83 | |||
|
|
7aa013cc7f | ||
|
|
3b424d4c98 | ||
|
|
14e85df71c | ||
|
|
8bab8d02ed | ||
|
|
758c944ec6 | ||
|
|
38e9266696 |
4
.gitignore
vendored
@@ -5,3 +5,7 @@
|
||||
.classpath
|
||||
.project
|
||||
*.log
|
||||
/.idea/
|
||||
/out/
|
||||
/Zoelda.iml
|
||||
/bin/
|
||||
|
||||
BIN
Zoelda/lib/Dokumentation.zip
Normal file
77
Zoelda/src/main/DoorTile.java
Normal file
@@ -0,0 +1,77 @@
|
||||
package main;
|
||||
|
||||
import ea.Ticker;
|
||||
import main.entities.player.Player;
|
||||
import main.maps.Map;
|
||||
|
||||
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 Map map;
|
||||
private boolean waitForLeave;
|
||||
|
||||
public DoorTile(int id, float x, float y, Map map) {
|
||||
super(id, x, y);
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
@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) {
|
||||
if (!waitForLeave) {
|
||||
if (connected != null) {
|
||||
Main.instance.getWorld().changeMap(this);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
waitForLeave = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getSide() {
|
||||
return side;
|
||||
}
|
||||
|
||||
public void setSide(int side) {
|
||||
this.side = side;
|
||||
}
|
||||
|
||||
public void setConnectedDoor(DoorTile door) {
|
||||
connected = door;
|
||||
}
|
||||
|
||||
public DoorTile getConnectedDoor() {
|
||||
return connected;
|
||||
}
|
||||
|
||||
public Map getMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
public void waitForLeave() {
|
||||
waitForLeave = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DoorTile clone() {
|
||||
DoorTile t = new DoorTile(getID(), posX, posY, map);
|
||||
t.setConnectedDoor(connected);
|
||||
t.side = side;
|
||||
t.map = map;
|
||||
return t;
|
||||
}
|
||||
|
||||
public void setMap(Map map) {
|
||||
this.map = map;
|
||||
}
|
||||
}
|
||||
28
Zoelda/src/main/HUD/HUD.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package main.HUD;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
|
||||
import ea.BoundingRechteck;
|
||||
import ea.Knoten;
|
||||
import main.Main;
|
||||
|
||||
public class HUD extends Knoten{
|
||||
|
||||
public final Herzen herzen;
|
||||
public final Inventory inventory;
|
||||
|
||||
|
||||
public HUD() {
|
||||
herzen = new Herzen();
|
||||
inventory = new Inventory();
|
||||
add(herzen);
|
||||
add(inventory);
|
||||
Main.instance.manager.anmelden(herzen, 60);
|
||||
Main.instance.manager.anmelden(inventory, 50);
|
||||
}
|
||||
@Override
|
||||
public void zeichnen(Graphics2D g, BoundingRechteck r) {
|
||||
herzen.zeichnen(g);
|
||||
inventory.zeichnen(g);
|
||||
}
|
||||
}
|
||||
114
Zoelda/src/main/HUD/Herzen.java
Normal file
@@ -0,0 +1,114 @@
|
||||
package main.HUD;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import ea.Knoten;
|
||||
import ea.Ticker;
|
||||
import main.Main;
|
||||
|
||||
public class Herzen extends Knoten implements Ticker{
|
||||
private final static int SCALE = 50;
|
||||
private BufferedImage volles_Herz;
|
||||
private BufferedImage halbes_Herz;
|
||||
private BufferedImage leeres_Herz;
|
||||
private BufferedImage hauptBild;
|
||||
private BufferedImage[] HPLeiste;
|
||||
private boolean shakingSwitch;
|
||||
private float HPVel = 0.3f;
|
||||
private int counter = 0;
|
||||
private float lastHP;
|
||||
private int y;
|
||||
private int HPLeisteY[];
|
||||
|
||||
public Herzen() {
|
||||
// inizialisieren der Variablen, laden der Bilder und für den ticker anmelden
|
||||
HPLeiste = new BufferedImage[5];
|
||||
HPLeisteY = new int [HPLeiste.length];
|
||||
try {
|
||||
hauptBild = ImageIO.read(HUD.class.getResourceAsStream("/res/images/icons.png"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
BufferedImage buff;
|
||||
// volles_Herz:
|
||||
buff = hauptBild.getSubimage(16, 0, 16, 16);
|
||||
volles_Herz = buff;
|
||||
// halbes_Herz:
|
||||
buff = hauptBild.getSubimage(32, 0, 16, 16);
|
||||
halbes_Herz = buff;
|
||||
// leeres_Herz
|
||||
buff = hauptBild.getSubimage(48, 0, 16, 16);
|
||||
leeres_Herz = buff;
|
||||
HPLeiste[0] = volles_Herz;
|
||||
HPLeiste[1] = volles_Herz;
|
||||
HPLeiste[2] = volles_Herz;
|
||||
}
|
||||
|
||||
private int shakeY() {
|
||||
shakingSwitch = !shakingSwitch;
|
||||
if (shakingSwitch == true) {
|
||||
return 3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int regenY() {
|
||||
if (HPVel > 0) {
|
||||
if (counter < HPLeiste.length + 1) {
|
||||
counter++;
|
||||
if (counter * 4 < HPLeiste.length + 1) {
|
||||
return 3;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
counter = 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// wird alle 200ms ausgeführt:
|
||||
public void tick() {
|
||||
// teilt den Wert der HP in Teile auf, welche der Anzahl der Herzen entspricht
|
||||
// und prüft dann für den eigenen Teil des Herzens, ob das jeweilige Herz voll,
|
||||
// halb oder leer ist (BIG BRAIN):
|
||||
HPVel = Main.instance.getWorld().getPlayer().getHP() - lastHP;
|
||||
lastHP = Main.instance.getWorld().getPlayer().getHP();
|
||||
float localeHP;
|
||||
for (int i = 0; i < HPLeiste.length; i++) {
|
||||
localeHP = Main.instance.getWorld().getPlayer().getHP();
|
||||
localeHP -= ((float) i) * (1f / HPLeiste.length);
|
||||
if (localeHP <= 0f) {
|
||||
HPLeiste[i] = leeres_Herz;
|
||||
} else if (localeHP < (1 / (float) (2 * HPLeiste.length))) {
|
||||
HPLeiste[i] = halbes_Herz;
|
||||
} else if (localeHP > 1 / (float) (2 * HPLeiste.length)) {
|
||||
HPLeiste[i] = volles_Herz;
|
||||
}
|
||||
}
|
||||
if(Main.instance.getWorld().getPlayer().getHP() < 0.33f) {
|
||||
y = shakeY();
|
||||
} else {
|
||||
for (int i = 0; i < HPLeiste.length; i++) {
|
||||
HPLeisteY[i] = regenY();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Zeichnet alle Herzen im Array HPLeiste[] auf den Bildschirm
|
||||
public void zeichnen(Graphics2D g) {
|
||||
for (int i = 0; i < HPLeiste.length; i++) {
|
||||
if(Main.instance.getWorld().getPlayer().getHP() < 0.33f) {
|
||||
g.drawImage(HPLeiste[i], (i + 2) * SCALE, y , SCALE, SCALE, null);
|
||||
} else {
|
||||
g.drawImage(HPLeiste[i], (i + 2) * SCALE, HPLeisteY[i] , SCALE, SCALE, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
51
Zoelda/src/main/HUD/Inventory.java
Normal file
@@ -0,0 +1,51 @@
|
||||
package main.HUD;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import ea.Knoten;
|
||||
import ea.Ticker;
|
||||
import main.Main;
|
||||
import main.entities.player.PlayerInventory;
|
||||
import main.worlds.World;
|
||||
|
||||
public class Inventory extends Knoten implements Ticker {
|
||||
|
||||
private static final int SCALE = 50;
|
||||
private BufferedImage inventoryFrame;
|
||||
private BufferedImage coinCounterIcon;
|
||||
private PlayerInventory inventory;
|
||||
|
||||
public Inventory() {
|
||||
inventory = Main.instance.getWorld().getPlayer().getInventory();
|
||||
try {
|
||||
inventoryFrame = ImageIO.read(HUD.class.getResourceAsStream("/res/images/inventory.png"));
|
||||
coinCounterIcon = ImageIO.read(HUD.class.getResourceAsStream("/res/images/coins.png"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
coinCounterIcon = coinCounterIcon.getSubimage(0, 20, 7, 4);
|
||||
|
||||
}
|
||||
|
||||
public void style(Graphics2D g) {
|
||||
Font currentFont = g.getFont();
|
||||
Font newFont = currentFont.deriveFont(Font.BOLD, 20);
|
||||
g.setFont(newFont);
|
||||
}
|
||||
|
||||
public void zeichnen(Graphics2D g) {
|
||||
style(g);
|
||||
g.drawImage(inventoryFrame, 0, 0, SCALE * 2, SCALE * 2, null);
|
||||
g.drawString(String.valueOf(inventory.getCoins()), SCALE + 10, 145);
|
||||
g.drawImage(coinCounterIcon, 0, 125, coinCounterIcon.getWidth() * World.SCALE_FACTOR,
|
||||
coinCounterIcon.getHeight() * World.SCALE_FACTOR, null);
|
||||
}
|
||||
|
||||
// wird alle 50ms ausgef<65>hrt:
|
||||
public void tick() {
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,10 @@
|
||||
package main;
|
||||
|
||||
import ea.Game;
|
||||
import ea.Taste;
|
||||
import main.HUD.HUD;
|
||||
import main.worlds.TestWorld;
|
||||
import main.worlds.World;
|
||||
|
||||
/**
|
||||
* Von hier wird alles initialisiert. Das ist die höchste Klasse.
|
||||
@@ -8,24 +12,32 @@ import ea.Game;
|
||||
public class Main extends Game {
|
||||
|
||||
public static Main instance;
|
||||
public static boolean SHOW_DEBUG = false;
|
||||
|
||||
private World world;
|
||||
|
||||
public static final int WIDTH = 1440; // Fensterbreite
|
||||
public static final int HEIGHT = 1056; // Fensterhöhe
|
||||
private HUD hud;
|
||||
private Sounds sounds;
|
||||
|
||||
public Main() {
|
||||
super(WIDTH, HEIGHT);
|
||||
super(World.SCALE * 15, World.SCALE * 11, 16);
|
||||
instance = this;
|
||||
|
||||
// Welt initialisieren und Spieler hinzufügen
|
||||
world = new World();
|
||||
// die Welt zu EA hinzufügen
|
||||
// Welt initialisieren und Spieler hinzufügen und die Welt zu EA hinzufügen
|
||||
world = new TestWorld();
|
||||
manager.anmelden(world.getPlayer(), 20);
|
||||
world.start();
|
||||
wurzel.add(world);
|
||||
hud = new HUD();
|
||||
wurzel.add(hud);
|
||||
// sounds = new Sounds();
|
||||
// sounds.playSound(2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tasteReagieren(int code) {
|
||||
if (code == Taste.O) {
|
||||
SHOW_DEBUG = !SHOW_DEBUG;
|
||||
}
|
||||
}
|
||||
|
||||
public World getWorld() {
|
||||
|
||||
@@ -11,21 +11,27 @@ import ea.internal.gra.PixelFeld;
|
||||
|
||||
public class SheetLoader {
|
||||
|
||||
private static Figur[] figures;
|
||||
private Figur[] figures;
|
||||
private BufferedImage sheet;
|
||||
|
||||
/**
|
||||
* Macht aus einem Spritesheet Figuren.
|
||||
*
|
||||
* @param path - Der pfad zum sheet
|
||||
* @param width - die Breite von einem Bild
|
||||
* @param height - die Höhe von einem Bild (nicht das ganze sheet)
|
||||
* @param lengths - die Anzahl der Frames der verschiedenen Animationen
|
||||
*/
|
||||
public SheetLoader(String path, int width, int height, int[] frames) {
|
||||
|
||||
public SheetLoader(String path) {
|
||||
try {
|
||||
// Bild laden
|
||||
BufferedImage sheet = ImageIO.read(Tile.class.getResourceAsStream(path));
|
||||
sheet = ImageIO.read(Tile.class.getResourceAsStream(path));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void generateFigures(int width, int height, int[] frames) {
|
||||
// Anzahl der Animationen
|
||||
int rows = frames.length;
|
||||
|
||||
@@ -44,10 +50,6 @@ public class SheetLoader {
|
||||
fig.animationSetzen(sprites[i]);
|
||||
figures[i] = fig;
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public Figur getFigur(int y) {
|
||||
|
||||
45
Zoelda/src/main/Sounds.java
Normal file
@@ -0,0 +1,45 @@
|
||||
package main;
|
||||
|
||||
import ea.Sound;
|
||||
|
||||
public class Sounds {
|
||||
private Sound[] sounds;
|
||||
|
||||
public Sounds() {
|
||||
sounds = new Sound[6];
|
||||
for(int i = 0; i < sounds.length; i++) {
|
||||
sounds[i] = new Sound(getPathFromId(i));
|
||||
}
|
||||
}
|
||||
|
||||
public void playSound(int id) {
|
||||
sounds[id].play();
|
||||
}
|
||||
|
||||
public void loopSound(int id) {
|
||||
sounds[id].loop();
|
||||
}
|
||||
|
||||
public void stopSound(int id) {
|
||||
sounds[id].stop();
|
||||
}
|
||||
|
||||
private String getPathFromId(int id) {
|
||||
switch(id) {
|
||||
case 0:
|
||||
return "/res/sounds/Water-Balloon-Maniacs.mp3";
|
||||
case 1:
|
||||
return "/res/sounds/Runaway-Food-Truck.mp3";
|
||||
case 2:
|
||||
return "/res/sounds/Hypnotic-Puzzle2.mp3" ;
|
||||
case 3:
|
||||
return "/res/sounds/Game-Menu_v001.mp3" ;
|
||||
case 4:
|
||||
return "/res/sounds/Blob-Monsters-on-the-Loose.mp3";
|
||||
case 5:
|
||||
return "/res/sounds/And-the-Machines-Came-at-Midnight.mp3";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import javax.imageio.ImageIO;
|
||||
|
||||
import ea.Bild;
|
||||
import ea.Knoten;
|
||||
import main.worlds.World;
|
||||
|
||||
/**
|
||||
* Ein feld auf der Map
|
||||
@@ -14,14 +15,26 @@ import ea.Knoten;
|
||||
public class Tile extends Knoten {
|
||||
|
||||
// IDs der Tiles
|
||||
public static final int VOID = -1;
|
||||
public static final int GRASS = 0;
|
||||
public static final int WALL_TOP = 1;
|
||||
public static final int WALL_BOTTOM = 2;
|
||||
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 STONE_FLOOR_SHADOW_LEFT = 6;
|
||||
public static final int DOOR_LEFT = 7;
|
||||
public static final int DOOR_RIGHT_LEFT_TOP = 8;
|
||||
public static final int DISCO = 9;
|
||||
public static final int DOOR_RIGHT = 10;
|
||||
public static final int DOOR_TOP = 11;
|
||||
public static final int DOOR_BOTTOM = 12;
|
||||
|
||||
private Bild img; // Bild, das gerendert wird
|
||||
private int id; // Die id dises Tiles
|
||||
private int id; // Die id dises Tiles//
|
||||
protected float posX, posY; // Position dieses Tiles
|
||||
|
||||
private static Bild[] images;
|
||||
|
||||
/**
|
||||
* @param id
|
||||
@@ -29,32 +42,47 @@ public class Tile extends Knoten {
|
||||
* @param y - Y-Koordinate in units
|
||||
*/
|
||||
public Tile(int id, float x, float y) {
|
||||
this.id = id;
|
||||
|
||||
// Das Bild laden
|
||||
if (images == null) {
|
||||
loadImages();
|
||||
}
|
||||
|
||||
this.id = id;
|
||||
posX = x;
|
||||
posY = y;
|
||||
|
||||
if (id != VOID) {
|
||||
img = images[id].clone();
|
||||
img.positionSetzen(posX * World.SCALE, posY * World.SCALE);
|
||||
// Bild zu EA hinzuf<75>gen.
|
||||
add(img);
|
||||
}
|
||||
}
|
||||
|
||||
private static void loadImages() {
|
||||
images = new Bild[13];
|
||||
for (int i = 0; i < images.length; i++) {
|
||||
try {
|
||||
BufferedImage buff = ImageIO.read(Tile.class.getResourceAsStream(getPathFromId(id)));
|
||||
// Gras hat 8 verschiedene Texturen von denen eine zufällig ausgewählt werden
|
||||
BufferedImage buff = ImageIO.read(Tile.class.getResourceAsStream(getPathFromId(i)));
|
||||
// Gras hat 8 verschiedene Texturen von denen eine zufaellig ausgewaehlt werden
|
||||
// muss.
|
||||
if (id == GRASS) {
|
||||
if (i == GRASS) {
|
||||
buff = buff.getSubimage(16 * (int) (Math.random() * 8), 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);
|
||||
|
||||
images[i] = new Bild(0, 0, scaled);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// Bild zu EA hinzufügen.
|
||||
add(img);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return den Pfad der zu der Id gehört.
|
||||
* @return den Pfad der zu der Id gehoert.
|
||||
*/
|
||||
private String getPathFromId(int id) {
|
||||
private static String getPathFromId(int id) {
|
||||
switch (id) {
|
||||
case GRASS:
|
||||
return "/res/images/tiles/grass.png";
|
||||
@@ -66,14 +94,30 @@ public class Tile extends Knoten {
|
||||
return "/res/images/tiles/stone_wall.png";
|
||||
case STONE_WALL_BOTTOM:
|
||||
return "/res/images/tiles/stone_wall_bottom.png";
|
||||
case STONE_FLOOR:
|
||||
return "/res/images/tiles/stone_floor.png";
|
||||
case STONE_FLOOR_SHADOW_LEFT:
|
||||
return "/res/images/tiles/stone_floor_shadow_left.png";
|
||||
case DOOR_LEFT:
|
||||
return "/res/images/tiles/door_left.png";
|
||||
case DOOR_RIGHT_LEFT_TOP:
|
||||
return "/res/images/tiles/door_right_left_top.png";
|
||||
case DISCO:
|
||||
return "/res/images/tiles/disco_sprite_sheet.png";
|
||||
case DOOR_RIGHT:
|
||||
return "/res/images/tiles/door_right.png";
|
||||
case DOOR_TOP:
|
||||
return "/res/images/tiles/door_top.png";
|
||||
case DOOR_BOTTOM:
|
||||
return "/res/images/tiles/door_bottom.png";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return die Größe der Textur
|
||||
* @return die Groesse der Textur
|
||||
*/
|
||||
public static int getSize() {
|
||||
private static int getSize() {
|
||||
return 16;
|
||||
}
|
||||
|
||||
@@ -81,36 +125,53 @@ public class Tile extends Knoten {
|
||||
* @return ob man durch das Tile durchgehen kann
|
||||
*/
|
||||
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 ;
|
||||
// Alle Tiles durch die man nicht laufen soll muessen hier true zurueckgeben,
|
||||
// sonst werden sie bei der Collisiondetection nicht ber<EFBFBD>cksichtigt.
|
||||
return id == WALL_TOP || id == STONE_WALL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Kleine Hifsmethode un die koordinate der Top-Kante rurückzugenben.
|
||||
* Kleine Hifsmethode um die Koordinate der Top-Kante zurueckzugenben.
|
||||
*/
|
||||
public int getTop() {
|
||||
return positionY();
|
||||
}
|
||||
|
||||
/**
|
||||
* Kleine Hifsmethode un die koordinate der Bottom-Kante rurückzugenben.
|
||||
* Kleine Hifsmethode um die Koordinate der Bottom-Kante zurueckzugenben.
|
||||
*/
|
||||
public int getBottom() {
|
||||
return positionY() + getSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Kleine Hifsmethode un die koordinate der Left-Kante rurückzugenben.
|
||||
* Kleine Hifsmethode um die Koordinate der Left-Kante zurueckzugenben.
|
||||
*/
|
||||
public int getLeft() {
|
||||
return positionX();
|
||||
}
|
||||
|
||||
/**
|
||||
* Kleine Hifsmethode un die koordinate der Right-Kante rurückzugenben.
|
||||
* Kleine Hifsmethode um die Koordinate der Right-Kante zurueckzugenben.
|
||||
*/
|
||||
public int getRight() {
|
||||
return positionX() + getSize();
|
||||
}
|
||||
|
||||
public int getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public float getPosX() {
|
||||
return posX;
|
||||
}
|
||||
|
||||
public float getPosY() {
|
||||
return posY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tile clone() {
|
||||
return new Tile(id, posX, posY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
package main;
|
||||
|
||||
import ea.Knoten;
|
||||
import main.entities.Entity;
|
||||
import main.entities.Player;
|
||||
import main.entities.Snake;
|
||||
import main.entities.Spider;
|
||||
import main.maps.Corridor;
|
||||
import main.maps.Map;
|
||||
import main.maps.TestMap;
|
||||
|
||||
/**
|
||||
* Hier werden alle Maps gespeichert.
|
||||
*/
|
||||
public class World extends Knoten {
|
||||
|
||||
public static final int SCALE_FACTOR = 6; // Der Basis Zoomfaktor
|
||||
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.
|
||||
|
||||
public World() {
|
||||
|
||||
// Map initialisieren
|
||||
currentMap = new TestMap();
|
||||
// Map zu EA hinzufügen
|
||||
add(currentMap);
|
||||
|
||||
// und Entities auch
|
||||
Player player = new Player();
|
||||
add(player.actionFigur);
|
||||
currentMap.getEntities().add(player);
|
||||
|
||||
Spider spider = new Spider();
|
||||
// und Spinnen auch
|
||||
add(spider.actionFigur);
|
||||
currentMap.getEntities().add(spider);
|
||||
|
||||
Snake snake = new Snake();
|
||||
add(snake.actionFigur);
|
||||
currentMap.getEntities().add(snake);
|
||||
|
||||
// Alle Entities als ticker registrieren (triggert dann die update methoden)
|
||||
for (Entity e : currentMap.getEntities()) {
|
||||
Main.instance.manager.anmelden(e, 20);
|
||||
}
|
||||
}
|
||||
|
||||
public Map getCurrentMap() {
|
||||
return currentMap;
|
||||
}
|
||||
}
|
||||
77
Zoelda/src/main/entities/AnimatedEntity.java
Normal file
@@ -0,0 +1,77 @@
|
||||
package main.entities;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
|
||||
import ea.ActionFigur;
|
||||
import ea.BoundingRechteck;
|
||||
import ea.Figur;
|
||||
import ea.internal.gra.PixelFeld;
|
||||
import main.Main;
|
||||
import main.worlds.World;
|
||||
|
||||
public abstract class AnimatedEntity extends Entity {
|
||||
|
||||
public ActionFigur actionFigur; // Sprite des Entities
|
||||
protected float spriteScale = 1f; // Skalierung des Sprites
|
||||
protected float spriteOffsetX, spriteOffsetY; // Offset des Sprites. Hier kann man die relative render-Position
|
||||
// nachjustieren.
|
||||
protected boolean side;
|
||||
|
||||
private static Figur noTexture = new Figur();
|
||||
|
||||
static {
|
||||
PixelFeld[] img = new PixelFeld[1];
|
||||
img[0] = new PixelFeld(16, 16, 1);
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int y = 0; y < 16; y++) {
|
||||
img[0].farbeSetzen(x, y, Color.MAGENTA);
|
||||
}
|
||||
}
|
||||
noTexture.animationSetzen(img);
|
||||
}
|
||||
|
||||
public AnimatedEntity() {
|
||||
actionFigur = new ActionFigur(noTexture, "undefined") {
|
||||
// DEBUG: render boxes
|
||||
|
||||
@Override
|
||||
public void zeichnen(Graphics2D g, BoundingRechteck r) {
|
||||
super.zeichnen(g, r);
|
||||
if (Main.SHOW_DEBUG) {
|
||||
g.setColor(Color.CYAN);
|
||||
g.drawRect((int) actionFigur.positionX(), (int) actionFigur.positionY(),
|
||||
(int) actionFigur.getBreite(), (int) actionFigur.getHoehe());
|
||||
g.setColor(Color.GREEN);
|
||||
g.drawRect((int) ((posX - width / 2) * World.SCALE), (int) ((posY - height / 2) * World.SCALE),
|
||||
(int) (width * World.SCALE), (int) (height * World.SCALE));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void update() {
|
||||
|
||||
checkTileCollision(Main.instance.getWorld().getCurrentMap());
|
||||
checkEntityCollision(Main.instance.getWorld().getCurrentMap());
|
||||
|
||||
// Packt das Sprite an die richtige Stelle
|
||||
actionFigur.faktorSetzen((int) (spriteScale * World.SCALE_FACTOR));
|
||||
float offsetX = width / 2 + spriteOffsetX - width / 2;
|
||||
float offsetY = height / 2 + spriteOffsetY - height / 2;
|
||||
actionFigur.positionSetzen((posX + offsetX) * World.SCALE - actionFigur.getBreite() / 2,
|
||||
(posY + offsetY) * World.SCALE - actionFigur.getHoehe() / 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Spiegelt die figur autmatisch, wenn nötig.
|
||||
*/
|
||||
protected void zustandSetzen(String name) {
|
||||
actionFigur.spiegelXSetzen(side);
|
||||
if (!actionFigur.aktuellesVerhalten().equals(name)) {
|
||||
actionFigur.zustandSetzen(name);
|
||||
actionFigur.aktuelleFigur().animationsBildSetzen(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
57
Zoelda/src/main/entities/Coin.java
Normal file
@@ -0,0 +1,57 @@
|
||||
package main.entities;
|
||||
|
||||
import main.Main;
|
||||
import main.SheetLoader;
|
||||
import main.entities.player.Player;
|
||||
|
||||
public class Coin extends AnimatedEntity {
|
||||
|
||||
private static SheetLoader loader = new SheetLoader("/res/images/coins.png");
|
||||
private boolean moveToCounterAnimation;
|
||||
private float animationDestX = 0.2f;
|
||||
private float animationDestY = 2.0f;
|
||||
|
||||
public Coin() {
|
||||
loader.generateFigures(8, 8, new int[] { 8, 8, 1 });
|
||||
|
||||
loader.getFigur(0).animationsGeschwindigkeitSetzen(100);
|
||||
loader.getFigur(1).animationsGeschwindigkeitSetzen(100);
|
||||
loader.getFigur(2).animationsGeschwindigkeitSetzen(100);
|
||||
|
||||
actionFigur.neuerZustand(loader.getFigur(0), "gold");
|
||||
actionFigur.neuerZustand(loader.getFigur(1), "silver");
|
||||
actionFigur.neuerZustand(loader.getFigur(2), "bronze");
|
||||
zustandSetzen("bronze");
|
||||
|
||||
posX = 4f;
|
||||
posY = 4f;
|
||||
width = 0.375f;
|
||||
height = 0.25f;
|
||||
spriteOffsetY = -0.1f;
|
||||
enablePushBack = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void update() {
|
||||
super.update();
|
||||
|
||||
if (moveToCounterAnimation) {
|
||||
float distX = animationDestX - posX;
|
||||
float distY = animationDestY - posY;
|
||||
posX += distX / 10f;
|
||||
posY += distY / 10f;
|
||||
if (distX < 0.05f && distX > -0.05f && distY < 0.05f && distY > -0.05f) {
|
||||
deleteEntity();
|
||||
Main.instance.getWorld().getPlayer().getInventory().addCoins(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEntityCollision(Entity e) {
|
||||
if (e instanceof Player && !moveToCounterAnimation) {
|
||||
moveToCounterAnimation = true;
|
||||
enableTileCollisions = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
package main.entities;
|
||||
|
||||
import ea.Ticker;
|
||||
import ea.Vektor;
|
||||
import main.Main;
|
||||
import main.Tile;
|
||||
import main.maps.Map;
|
||||
|
||||
/*
|
||||
@@ -14,6 +17,9 @@ public abstract class Entity implements Ticker {
|
||||
protected float accelleration = 0.012f; // Beschleunigung des entities in gameunits pro frame.
|
||||
protected float friction = 0.2f; // Entschleunigung des entities in gameunits pro frame.
|
||||
protected float width = 1f, height = 1f; // Breite und Höhe der Hitbox.
|
||||
private boolean deleteEntity; // Wenn true wird dieses Entity von der map gelöscht
|
||||
protected boolean enablePushBack = true; // Ob das Entity von anderen Entities weggedrückt werden kann.
|
||||
protected boolean enableTileCollisions = true; // Ob das Entity von Wänden abprallen soll
|
||||
|
||||
// Das ist die Ticker-Methode von ea; wird jeden frame ausgeführt (frameloop)
|
||||
@Override
|
||||
@@ -45,12 +51,16 @@ public abstract class Entity implements Ticker {
|
||||
/**
|
||||
* Checkt collision mit tiles von der map. Fertig, clean, nie wieder ändern.
|
||||
*/
|
||||
public void checkTileCollisions(Map map) {
|
||||
public void checkTileCollision(Map map) {
|
||||
if (!enableTileCollisions) {
|
||||
return;
|
||||
}
|
||||
for (int x = (int) (posX - 2); x < posX + 2; x++) {
|
||||
for (int y = (int) (posY - 2); y < posY + 2; y++) {
|
||||
if (x >= 0 && x < map.getWidth() && y >= 0 && y < map.getHeight()) {
|
||||
if (map.getTile(x, y).isCollidable()) {
|
||||
if (posY + height / 2 > y && posY - height / 2 < y + 1 && posX + width / 2 > x && posX - width / 2 < x + 1) {
|
||||
if (posY + height / 2 > y && posY - height / 2 < y + 1 && posX + width / 2 > x
|
||||
&& posX - width / 2 < x + 1) {
|
||||
float distN = Math.abs((y + 1 + height / 2) - posY);
|
||||
float distE = Math.abs((x + 1 + width / 2) - posX);
|
||||
float distS = Math.abs((y - height / 2) - posY);
|
||||
@@ -71,6 +81,37 @@ public abstract class Entity implements Ticker {
|
||||
}
|
||||
}
|
||||
|
||||
public void checkEntityCollision(Map map) {
|
||||
for (int i = 0; i < map.getEntities().size(); i++) {
|
||||
Entity e = map.getEntities().get(i);
|
||||
if (e != this) {
|
||||
float esize = (e.getWidth() + e.getHeight()) / 2;
|
||||
float size = (width + height) / 2;
|
||||
float dist = dist(e);
|
||||
float sizes = esize / 2 + size / 2;
|
||||
if (dist < sizes) {
|
||||
if (enablePushBack && e.enablePushBack) {
|
||||
float overlap = dist - sizes;
|
||||
float xDist = e.posX - posX;
|
||||
float yDist = e.posY - posY;
|
||||
if (xDist == 0f) {
|
||||
xDist = (float) (Math.random() - 0.5f) * 0.01f;
|
||||
}
|
||||
if (yDist == 0f) {
|
||||
yDist = (float) (Math.random() - 0.5f) * 0.01f;
|
||||
}
|
||||
posX += (overlap * xDist);
|
||||
posY += (overlap * yDist);
|
||||
}
|
||||
onEntityCollision(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onEntityCollision(Entity e) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gehört mit zur collision detection. Hier werden kollisionen aufgelöst.
|
||||
*/
|
||||
@@ -105,7 +146,118 @@ public abstract class Entity implements Ticker {
|
||||
* @return die entifernung zu diesem Entity
|
||||
*/
|
||||
public float dist(Entity e) {
|
||||
return (float) Math.sqrt(e.posX * e.posX + posY * posY);
|
||||
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
|
||||
*/
|
||||
public Vektor vectorToEntity(Entity e) {
|
||||
Vektor v = new Vektor(e.posX - posX, e.posY - posY);
|
||||
;
|
||||
if (v.x == 0 && v.y == 0) {
|
||||
return new Vektor(0.001f, 0.001f);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
protected boolean lineOfSightClear(Entity e) {
|
||||
Vektor direct = vectorToEntity(e).normiert();
|
||||
direct = direct.teilen(4f);
|
||||
Vektor loc = new Vektor(posX, posY);
|
||||
float lastDist;
|
||||
float dist = Float.MAX_VALUE;
|
||||
boolean clear = true;
|
||||
do {
|
||||
loc = loc.summe(direct);
|
||||
lastDist = dist;
|
||||
dist = Math.abs(e.posX - loc.x) + Math.abs(e.posY - loc.y);
|
||||
Tile t = Main.instance.getWorld().getCurrentMap().getTile((int) loc.x, (int) loc.y);
|
||||
if (t != null && t.isCollidable()) {
|
||||
clear = false;
|
||||
break;
|
||||
}
|
||||
} while (dist < lastDist);
|
||||
return clear;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt den velX Wert zurück.
|
||||
*
|
||||
* @return gibt den velX Wert als float zurück.
|
||||
*/
|
||||
public float getVelX() {
|
||||
return velX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt den velY Wert zurück.
|
||||
*
|
||||
* @return gibt den velY Wert als float zurück.
|
||||
*/
|
||||
public float getVelY() {
|
||||
return velY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt eine neue velX velocity.
|
||||
*
|
||||
* @param velX neuer float velX Wert.
|
||||
*/
|
||||
public void setVelX(float velX) {
|
||||
this.velX = velX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt eine neue Y velocity.
|
||||
*
|
||||
* @param velY neuer float velY Wert.
|
||||
*/
|
||||
public void setVelY(float velY) {
|
||||
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 float getPosX() {
|
||||
return posX;
|
||||
}
|
||||
|
||||
public float getPosY() {
|
||||
return posY;
|
||||
}
|
||||
|
||||
public void deleteEntity() {
|
||||
deleteEntity = true;
|
||||
}
|
||||
|
||||
public boolean isReadyToDelete() {
|
||||
return deleteEntity;
|
||||
}
|
||||
|
||||
public float getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public float getHeight() {
|
||||
return height;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,63 +1,47 @@
|
||||
package main.entities;
|
||||
|
||||
import ea.ActionFigur;
|
||||
import ea.Figur;
|
||||
import main.World;
|
||||
|
||||
/*
|
||||
* Alles was zustände hat und sich Bewegen kann, ist ein LivingEntity.
|
||||
*/
|
||||
public class LivingEntity extends Entity {
|
||||
public abstract class LivingEntity extends AnimatedEntity {
|
||||
|
||||
protected boolean side; // true = gespiegelt, false = nicht
|
||||
public ActionFigur actionFigur; // Sprite des Entities
|
||||
protected float spriteScale = 1f; // Skalierung des Sprites
|
||||
protected float spriteOffsetX, spriteOffsetY; // Offset des Sprites. Hier kann man die relative render-Position nachjustieren.
|
||||
protected boolean mirrored; // true = gespiegelt, false = nicht
|
||||
protected float hp = 1f; //hp des Entitys
|
||||
protected boolean mirrored;
|
||||
/**
|
||||
* @param figur - erstes (standart) Sprite
|
||||
* @param name - name des Zustands
|
||||
*/
|
||||
public LivingEntity(Figur figur, String name) {
|
||||
actionFigur = new ActionFigur(figur, name) {
|
||||
// DEBUG: render boxes
|
||||
|
||||
// @Override
|
||||
// public void zeichnen(Graphics2D g, BoundingRechteck r) {
|
||||
// g.setColor(Color.GREEN);
|
||||
// g.drawRect((int) actionFigur.positionX(), (int) actionFigur.positionY(), (int) actionFigur.getBreite(), (int) actionFigur.getHoehe());
|
||||
// g.drawRect((int) ((posX - width / 2) * World.SCALE), (int) ((posY - height / 2) * World.SCALE), (int) (width * World.SCALE), (int) (height * World.SCALE));
|
||||
// super.zeichnen(g, r);
|
||||
// }
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void update() {
|
||||
// Prüft zu welcher seite man guckt
|
||||
if (velX < 0) {
|
||||
side = true;
|
||||
side = !mirrored;
|
||||
} else if (velX > 0) {
|
||||
side = false;
|
||||
side = mirrored;
|
||||
}
|
||||
|
||||
// Packt das Sprite an die richtige Stelle
|
||||
actionFigur.faktorSetzen((int) (spriteScale * World.SCALE_FACTOR));
|
||||
float offsetX = width / 2 + spriteOffsetX - width / 2;
|
||||
float offsetY = height / 2 + spriteOffsetY - height / 2;
|
||||
actionFigur.positionSetzen((posX + offsetX) * World.SCALE - actionFigur.getBreite() / 2, (posY + offsetY) * World.SCALE - actionFigur.getHoehe() / 2);
|
||||
if (hp <= 0) {
|
||||
actionFigur.zustandSetzen(getDeathAnimationName());
|
||||
velX = 0;
|
||||
velY = 0;
|
||||
if (actionFigur.aktuelleFigur().aktuellesBild() == actionFigur.aktuelleFigur().animation().length - 1 && !isReadyToDelete()) {
|
||||
deleteEntity();
|
||||
onDeath();
|
||||
}
|
||||
}
|
||||
super.update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Spiegelt die figur autmatisch, wenn nötig.
|
||||
*/
|
||||
protected void zustandSetzen(String name) {
|
||||
actionFigur.spiegelXSetzen(mirrored ? !side : side);
|
||||
actionFigur.zustandSetzen(name);
|
||||
}
|
||||
|
||||
protected float getHealthPoints() {
|
||||
public float getHP() {
|
||||
return hp;
|
||||
}
|
||||
|
||||
public void takeDamage(float damage, Entity e) {
|
||||
zustandSetzen(getDamageAnimationName());
|
||||
actionFigur.aktuelleFigur().animationsBildSetzen(0);
|
||||
hp -= damage;
|
||||
}
|
||||
|
||||
public abstract String getDeathAnimationName();
|
||||
public abstract String getDamageAnimationName();
|
||||
|
||||
protected void onDeath() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
package main.entities;
|
||||
|
||||
import ea.Taste;
|
||||
import main.Main;
|
||||
import main.SheetLoader;
|
||||
|
||||
public class Player extends LivingEntity {
|
||||
|
||||
private static SheetLoader loader = new SheetLoader("/res/images/player_sprite_sheet.png", 64, 32, new int[] {5, 8, 7, 6, 2, 5, 4, 7});
|
||||
|
||||
public Player() {
|
||||
super(loader.getFigur(0), "idle");
|
||||
|
||||
// Entity-Eigenschaften werden festgelegt
|
||||
width = 0.7f;
|
||||
height = 0.8f;
|
||||
spriteOffsetY = -0.14f;
|
||||
spriteScale = 0.8f;
|
||||
posX = 4f;
|
||||
posY = 4f;
|
||||
|
||||
// unterschiedliche Animationsgeschwindigkeiten
|
||||
// für idle
|
||||
loader.getFigur(0).animationsGeschwindigkeitSetzen(200);
|
||||
// fürs laufen
|
||||
loader.getFigur(1).animationsGeschwindigkeitSetzen(50);
|
||||
|
||||
// Zustände werden hinzugefügt
|
||||
actionFigur.neuerZustand(loader.getFigur(0), "idle");
|
||||
actionFigur.neuerZustand(loader.getFigur(1), "walk");
|
||||
actionFigur.neuerZustand(loader.getFigur(2), "strike");
|
||||
actionFigur.neuerZustand(loader.getFigur(3), "swipe");
|
||||
actionFigur.neuerZustand(loader.getFigur(7), "die");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void update() {
|
||||
// Bei dieser animation bleibt man sofort stehen.
|
||||
if (!((actionFigur.aktuellesVerhalten().equals("strike"))
|
||||
&& actionFigur.aktuelleFigur().aktuellesBild() < actionFigur.aktuelleFigur().animation().length - 1)) {
|
||||
// Bei diser soll man sich nicht bewegen können aber weiter rutschen
|
||||
if (!((actionFigur.aktuellesVerhalten().equals("swipe"))
|
||||
&& actionFigur.aktuelleFigur().aktuellesBild() < actionFigur.aktuelleFigur().animation().length - 1)) {
|
||||
|
||||
// wasd movement
|
||||
if (Main.instance.tasteGedrueckt(Taste.A)) {
|
||||
velX -= accelleration;
|
||||
}
|
||||
if (Main.instance.tasteGedrueckt(Taste.D)) {
|
||||
velX += accelleration;
|
||||
}
|
||||
if (Main.instance.tasteGedrueckt(Taste.W)) {
|
||||
velY -= accelleration;
|
||||
}
|
||||
if (Main.instance.tasteGedrueckt(Taste.S)) {
|
||||
velY += accelleration;
|
||||
}
|
||||
|
||||
// Auf idle stellen wenn man sich nicht bewegt
|
||||
if (velX == 0 && velY == 0) {
|
||||
zustandSetzen("idle");
|
||||
} else {
|
||||
zustandSetzen("walk");
|
||||
}
|
||||
|
||||
// Attacken
|
||||
if (Main.instance.tasteGedrueckt(Taste.LEERTASTE)) {
|
||||
zustandSetzen("swipe");
|
||||
}
|
||||
if (Main.instance.tasteGedrueckt(Taste.Q)) {
|
||||
zustandSetzen("strike");
|
||||
}
|
||||
if (Main.instance.tasteGedrueckt(Taste.F)) {
|
||||
zustandSetzen("die");
|
||||
}
|
||||
}
|
||||
|
||||
// auf Kollisionen prüfen
|
||||
checkTileCollisions(Main.instance.getWorld().getCurrentMap());
|
||||
// LivingEntity auch updaten lassen
|
||||
super.update();
|
||||
} else {
|
||||
velX = 0;
|
||||
velY = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
36
Zoelda/src/main/entities/Rick.java
Normal file
@@ -0,0 +1,36 @@
|
||||
package main.entities;
|
||||
|
||||
import main.SheetLoader;
|
||||
|
||||
public class Rick extends LivingEntity{
|
||||
|
||||
private static SheetLoader loader = new SheetLoader("/res/images/rick_sprite_sheet.png");
|
||||
|
||||
public Rick() {
|
||||
loader.generateFigures(24, 24, new int[] {4});
|
||||
|
||||
width = 0.7f;
|
||||
height = 0.8f;
|
||||
spriteOffsetY = -0.14f;
|
||||
spriteScale = 0.8f;
|
||||
posX = 4f;
|
||||
posY = 4f;
|
||||
mirrored = true;
|
||||
|
||||
loader.getFigur(0).animationsGeschwindigkeitSetzen(265);
|
||||
actionFigur.neuerZustand(loader.getFigur(0), "dancin");
|
||||
zustandSetzen("dancin");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeathAnimationName() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDamageAnimationName() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,80 +1,95 @@
|
||||
package main.entities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import ea.Vektor;
|
||||
import main.Main;
|
||||
import main.SheetLoader;
|
||||
import main.Tile;
|
||||
import main.entities.player.Player;
|
||||
|
||||
public class Snake extends LivingEntity {
|
||||
|
||||
private static SheetLoader loader = new SheetLoader("/res/images/snake_spritesheet_calciumtrice.png", 32, 32, new int[] { 10, 10, 10, 10, 10 });
|
||||
private static SheetLoader loader = new SheetLoader("/res/images/snake_spritesheet_calciumtrice.png");
|
||||
|
||||
private float damage = 0.1f;
|
||||
private boolean attackOnce;
|
||||
|
||||
public Snake() {
|
||||
super(loader.getFigur(0), "idle");
|
||||
|
||||
loader.generateFigures(32, 32, new int[] { 10, 10, 10, 10, 13, 8 });
|
||||
posX = 9f;
|
||||
posY = 9f;
|
||||
accelleration = 0.008f;
|
||||
accelleration = 0.006f;
|
||||
spriteOffsetY = -0.6f;
|
||||
width = 0.65f;
|
||||
height = 0.8f;
|
||||
mirrored = true;
|
||||
|
||||
actionFigur.neuerZustand(loader.getFigur(0), "idle");
|
||||
actionFigur.neuerZustand(loader.getFigur(1), "lost_sight");
|
||||
actionFigur.neuerZustand(loader.getFigur(2), "walk");
|
||||
actionFigur.neuerZustand(loader.getFigur(3), "attack");
|
||||
actionFigur.neuerZustand(loader.getFigur(4), "die");
|
||||
actionFigur.neuerZustand(loader.getFigur(4), getDeathAnimationName());
|
||||
actionFigur.neuerZustand(loader.getFigur(5), getDamageAnimationName());
|
||||
|
||||
loader.getFigur(3).animationsGeschwindigkeitSetzen(80);
|
||||
loader.getFigur(5).animationsGeschwindigkeitSetzen(60);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void update() {
|
||||
ArrayList<Entity> entities = Main.instance.getWorld().getCurrentMap().getEntities();
|
||||
Entity nearestPlayer = null;
|
||||
for (Entity e : entities) {
|
||||
if (e instanceof Player) {
|
||||
if (nearestPlayer == null || e.dist(this) < nearestPlayer.dist(this)) {
|
||||
nearestPlayer = e;
|
||||
Player player = Main.instance.getWorld().getPlayer();
|
||||
if (!actionFigur.aktuellesVerhalten().equals(getDamageAnimationName())) {
|
||||
if (lineOfSightClear(player)) {
|
||||
if (dist(player) < 1f) {
|
||||
zustandSetzen("attack");
|
||||
if (actionFigur.aktuelleFigur().aktuellesBild() == 6) {
|
||||
if (!attackOnce) {
|
||||
attackOnce = true;
|
||||
player.takeDamage(damage, this);
|
||||
}
|
||||
} else {
|
||||
attackOnce = false;
|
||||
}
|
||||
}
|
||||
if (nearestPlayer != null && lineOfSightClear(nearestPlayer)) {
|
||||
Vektor toPlayer = new Vektor(nearestPlayer.posX - posX, nearestPlayer.posY - posY);
|
||||
toPlayer = toPlayer.normiert();
|
||||
} else {
|
||||
Vektor toPlayer = vectorToEntity(player).normiert();
|
||||
velX += toPlayer.x * accelleration;
|
||||
velY += toPlayer.y * accelleration;
|
||||
zustandSetzen("walk");
|
||||
} else {
|
||||
if (actionFigur.aktuellesVerhalten().equals("walk")) {
|
||||
zustandSetzen("lost_sight");
|
||||
}
|
||||
if (actionFigur.aktuellesVerhalten().equals("lost_sight") && actionFigur.aktuelleFigur().aktuellesBild() == actionFigur.aktuelleFigur().animation().length - 1) {
|
||||
actionFigur.aktuelleFigur().animationsBildSetzen(0);
|
||||
} else {
|
||||
if (!actionFigur.aktuellesVerhalten().equals("idle")) {
|
||||
zustandSetzen("lost_sight");
|
||||
if (actionFigur.aktuelleFigur().aktuellesBild() == actionFigur.aktuelleFigur().animation().length
|
||||
- 1) {
|
||||
zustandSetzen("idle");
|
||||
}
|
||||
}
|
||||
this.checkTileCollisions(Main.instance.getWorld().getCurrentMap());
|
||||
}
|
||||
} else {
|
||||
if (actionFigur.aktuelleFigur().aktuellesBild() == actionFigur.aktuelleFigur().animation().length - 1) {
|
||||
zustandSetzen("walk");
|
||||
}
|
||||
}
|
||||
super.update();
|
||||
}
|
||||
|
||||
private boolean lineOfSightClear(Entity e) {
|
||||
Vektor direct = new Vektor(e.posX - posX, e.posY - posY).normiert();
|
||||
direct = direct.teilen(4f);
|
||||
Vektor loc = new Vektor(posX, posY);
|
||||
float lastDist;
|
||||
float dist = Float.MAX_VALUE;
|
||||
boolean clear = true;
|
||||
do {
|
||||
loc = loc.summe(direct);
|
||||
lastDist = dist;
|
||||
dist = Math.abs(e.posX - loc.x) + Math.abs(e.posY - loc.y);
|
||||
Tile t = Main.instance.getWorld().getCurrentMap().getTile((int) loc.x, (int) loc.y);
|
||||
if (t != null && t.isCollidable()) {
|
||||
clear = false;
|
||||
break;
|
||||
@Override
|
||||
public String getDeathAnimationName() {
|
||||
return "die";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDamageAnimationName() {
|
||||
return "damage";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDeath() {
|
||||
int count = (int) (Math.random() * 3);
|
||||
for (int i = 0; i < count; i++) {
|
||||
Coin c = new Coin();
|
||||
float x = posX + (float) Math.random() * width - width / 2;
|
||||
float y = posY + (float) Math.random() * height - height / 2;
|
||||
c.setPos(x, y);
|
||||
Main.instance.getWorld().getCurrentMap().addAnimatedEntity(c);
|
||||
}
|
||||
} while (dist < lastDist);
|
||||
return clear;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
package main.entities;
|
||||
|
||||
import ea.Vektor;
|
||||
import main.Main;
|
||||
import main.SheetLoader;
|
||||
import main.entities.player.Player;
|
||||
|
||||
public class Spider extends LivingEntity {
|
||||
|
||||
private static SheetLoader loader = new SheetLoader("/res/images/spider_sprite_sheet.png", 32, 32,
|
||||
new int[] { 5, 6, 9, 1, 4, 3, 9, 6, 5, 6, 9, 1, 4, 3, 9, 6 });
|
||||
private static SheetLoader loader = new SheetLoader("/res/images/spider_sprite_sheet.png");
|
||||
|
||||
public Spider() {
|
||||
super(loader.getFigur(0), "walk");
|
||||
loader.generateFigures(32, 32, new int[] { 5, 3, 6, 9, 9, 8 });
|
||||
|
||||
width = 0.7f;
|
||||
height = 0.8f;
|
||||
@@ -17,17 +18,55 @@ public class Spider extends LivingEntity {
|
||||
spriteScale = 0.8f;
|
||||
posX = 4f;
|
||||
posY = 4f;
|
||||
mirrored = true;
|
||||
|
||||
actionFigur.neuerZustand(loader.getFigur(0), "idle");
|
||||
actionFigur.neuerZustand(loader.getFigur(1), "lost_sight");
|
||||
actionFigur.neuerZustand(loader.getFigur(2), "walk");
|
||||
actionFigur.neuerZustand(loader.getFigur(3), "attack");
|
||||
actionFigur.neuerZustand(loader.getFigur(4), getDeathAnimationName());
|
||||
actionFigur.neuerZustand(loader.getFigur(5), getDamageAnimationName());
|
||||
|
||||
loader.getFigur(3).animationsGeschwindigkeitSetzen(80);
|
||||
loader.getFigur(5).animationsGeschwindigkeitSetzen(40);
|
||||
}
|
||||
|
||||
protected void update() {
|
||||
|
||||
// auf Kollisionen prüfen
|
||||
checkTileCollisions(Main.instance.getWorld().getCurrentMap());
|
||||
// LivingEntity auch updaten lassen
|
||||
Player player = Main.instance.getWorld().getPlayer();
|
||||
if (!actionFigur.aktuellesVerhalten().equals(getDamageAnimationName())) {
|
||||
if (lineOfSightClear(player)) {
|
||||
if (dist(player) < 1f) {
|
||||
zustandSetzen("attack");
|
||||
} else {
|
||||
Vektor toPlayer = vectorToEntity(player).normiert();
|
||||
velX += toPlayer.x * accelleration;
|
||||
velY += toPlayer.y * accelleration;
|
||||
zustandSetzen("walk");
|
||||
}
|
||||
} else {
|
||||
if (!actionFigur.aktuellesVerhalten().equals("idle")) {
|
||||
zustandSetzen("lost_sight");
|
||||
if (actionFigur.aktuelleFigur().aktuellesBild() == actionFigur.aktuelleFigur().animation().length - 1) {
|
||||
zustandSetzen("idle");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (actionFigur.aktuelleFigur().aktuellesBild() == actionFigur.aktuelleFigur().animation().length - 1) {
|
||||
zustandSetzen("walk");
|
||||
}
|
||||
}
|
||||
super.update();
|
||||
velX = 0;
|
||||
velY = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeathAnimationName() {
|
||||
return "die";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDamageAnimationName() {
|
||||
return "damage";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
133
Zoelda/src/main/entities/player/Player.java
Normal file
@@ -0,0 +1,133 @@
|
||||
package main.entities.player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import ea.Taste;
|
||||
import ea.Vektor;
|
||||
import main.Main;
|
||||
import main.SheetLoader;
|
||||
import main.entities.Entity;
|
||||
import main.entities.LivingEntity;
|
||||
|
||||
public class Player extends LivingEntity {
|
||||
|
||||
private static SheetLoader loader = new SheetLoader("/res/images/player_sprite_sheet.png");
|
||||
private boolean onlyAttackOnceTrigger;
|
||||
private float range = 1.2f; // die reichweite der Attacke
|
||||
private PlayerInventory inventory;
|
||||
|
||||
public Player() {
|
||||
loader.generateFigures(64, 32, new int[] { 5, 8, 7, 6, 2, 5, 4, 7 });
|
||||
|
||||
// Entity-Eigenschaften werden festgelegt
|
||||
width = 0.7f;
|
||||
height = 0.8f;
|
||||
spriteOffsetY = -0.14f;
|
||||
spriteScale = 0.8f;
|
||||
posX = 7.5f;
|
||||
posY = 5.5f;
|
||||
|
||||
// unterschiedliche Animationsgeschwindigkeiten
|
||||
// f<>r idle
|
||||
loader.getFigur(0).animationsGeschwindigkeitSetzen(200);
|
||||
// f<>rs laufen
|
||||
loader.getFigur(1).animationsGeschwindigkeitSetzen(50);
|
||||
|
||||
// Zust<73>nde werden hinzugef<65>gt
|
||||
actionFigur.neuerZustand(loader.getFigur(0), "idle");
|
||||
actionFigur.neuerZustand(loader.getFigur(1), "walk");
|
||||
actionFigur.neuerZustand(loader.getFigur(2), "strike");
|
||||
actionFigur.neuerZustand(loader.getFigur(3), "swipe");
|
||||
actionFigur.neuerZustand(loader.getFigur(6), getDamageAnimationName());
|
||||
actionFigur.neuerZustand(loader.getFigur(7), getDeathAnimationName());
|
||||
|
||||
//Spieler Inventar
|
||||
inventory = new PlayerInventory(5);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void update() {
|
||||
// Bei dieser animation bleibt man sofort stehen.
|
||||
if (!((actionFigur.aktuellesVerhalten().equals("strike"))
|
||||
&& actionFigur.aktuelleFigur().aktuellesBild() < actionFigur.aktuelleFigur().animation().length - 1)) {
|
||||
// Bei diser soll man sich nicht bewegen k<>nnen aber weiter rutschen
|
||||
if (!((actionFigur.aktuellesVerhalten().equals("swipe")) && actionFigur.aktuelleFigur()
|
||||
.aktuellesBild() < actionFigur.aktuelleFigur().animation().length - 1)) {
|
||||
|
||||
// wasd movement
|
||||
if (Main.instance.tasteGedrueckt(Taste.A)) {
|
||||
velX -= accelleration;
|
||||
}
|
||||
if (Main.instance.tasteGedrueckt(Taste.D)) {
|
||||
velX += accelleration;
|
||||
}
|
||||
if (Main.instance.tasteGedrueckt(Taste.W)) {
|
||||
velY -= accelleration;
|
||||
}
|
||||
if (Main.instance.tasteGedrueckt(Taste.S)) {
|
||||
velY += accelleration;
|
||||
}
|
||||
|
||||
// Auf idle stellen wenn man sich nicht bewegt
|
||||
if (velX == 0 && velY == 0) {
|
||||
zustandSetzen("idle");
|
||||
} else {
|
||||
zustandSetzen("walk");
|
||||
}
|
||||
|
||||
// Attacken
|
||||
if (Main.instance.tasteGedrueckt(Taste.LEERTASTE)) {
|
||||
zustandSetzen("swipe");
|
||||
}
|
||||
if (Main.instance.tasteGedrueckt(Taste.Q)) {
|
||||
zustandSetzen("strike");
|
||||
}
|
||||
if (Main.instance.tasteGedrueckt(Taste.F)) {
|
||||
zustandSetzen("die");
|
||||
}
|
||||
onlyAttackOnceTrigger = false;
|
||||
}
|
||||
// LivingEntity auch updaten lassen
|
||||
super.update();
|
||||
} else {
|
||||
velX = 0;
|
||||
velY = 0;
|
||||
}
|
||||
|
||||
if (!actionFigur.aktuellesVerhalten().equals(getDamageAnimationName())) {
|
||||
if (!onlyAttackOnceTrigger && actionFigur.aktuellesVerhalten().equals("swipe")
|
||||
&& actionFigur.aktuelleFigur().aktuellesBild() == 1) {
|
||||
onlyAttackOnceTrigger = true;
|
||||
ArrayList<Entity> entities = Main.instance.getWorld().getCurrentMap().getEntities();
|
||||
for (Entity e : entities) {
|
||||
if (e instanceof LivingEntity && e != this && e.dist(this) <= range) {
|
||||
LivingEntity le = (LivingEntity) e;
|
||||
if (le.getHP() > 0) {
|
||||
Vektor toE = vectorToEntity(le);
|
||||
toE = toE.normiert();
|
||||
if ((toE.x > 0 && !side) || (toE.x <= 0 && side)) {
|
||||
le.setVelX(le.getVelX() + toE.x * 0.1f);
|
||||
le.setVelY(le.getVelY() + toE.y * 0.1f);
|
||||
le.takeDamage(0.1f, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public PlayerInventory getInventory() {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeathAnimationName() {
|
||||
return "die";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDamageAnimationName() {
|
||||
return "damage";
|
||||
}
|
||||
}
|
||||
114
Zoelda/src/main/entities/player/PlayerInventory.java
Normal file
@@ -0,0 +1,114 @@
|
||||
package main.entities.player;
|
||||
|
||||
import main.items.Item;
|
||||
|
||||
/**
|
||||
* Container Klasse für das Inventar des Spielers,
|
||||
* eventuell später verallgemeinerbar für Truhen o.ä. je nach design dieser.
|
||||
*/
|
||||
public class PlayerInventory {
|
||||
private int coins;
|
||||
private Item[] items;
|
||||
private int currentItem;
|
||||
|
||||
/**
|
||||
* Erstellt ein Player Inventar, welches einen Coin counter und ein Item Inventar enthält.
|
||||
* @param inventorySize Gibt die größe des Item inventars als int an.
|
||||
*/
|
||||
public PlayerInventory(int inventorySize){
|
||||
items = new Item [inventorySize];
|
||||
currentItem = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter für den Coin counter
|
||||
* @return Gibt die Anzahl der Coins im Inventar als int zurück.
|
||||
*/
|
||||
public int getCoins(){
|
||||
return coins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt die Anzahl von Coins im Inventar zu angegebener Anzahl.
|
||||
* @param coins Anzahl an coins als int, die im Inventar sein sollen.
|
||||
*/
|
||||
public void setCoins(int coins) {
|
||||
this.coins = coins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt die angegebene Anzahl an Coins in das Inventar hinzu.
|
||||
* @param amount Die Anzahl an Coins als int, die hinzugefügt werden soll.
|
||||
*/
|
||||
public void addCoins(int amount){
|
||||
this.coins+= amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Entfernt die angegebene Anzahl an Coins vom Inventar.
|
||||
* @param amount Die Anzahl an Coins als int, die entfernt werden soll.
|
||||
*/
|
||||
public void subtractCoins(int amount){
|
||||
this.coins-= amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter für das Items im Inventar.
|
||||
* @return gibt ein Array mit allen Item Objekten zurück, die im Inventar enthalten sind.
|
||||
*/
|
||||
public Item[] getItems(){
|
||||
return items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ersetzt das jetzige Inventar um ein neues mit im Item-Array items angegebenen Items.
|
||||
* @param items Array mit Items die das Inventar ersetzen sollen.
|
||||
*/
|
||||
public void setItems(Item[] items) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Entfernt ein Item auf angegebner Position im Item-Array.
|
||||
* @param itemPosition Position des Items das entfernt werden soll, angegeben als int.
|
||||
*/
|
||||
public void removeItem(int itemPosition) {
|
||||
items[itemPosition]=null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das gerade ausgewählte Item fest.
|
||||
* @param currentItem int gibt an welcher Index des Item Arrays ausgewählt werden soll.
|
||||
*/
|
||||
public void setCurrentItem(int currentItem) {
|
||||
this.currentItem = currentItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wechselt auf den nächsten Slot im Inventar.
|
||||
*/
|
||||
public void changeCurrentItem(){
|
||||
if(currentItem>=items.length) currentItem=0;
|
||||
else currentItem++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Methode zum Hinzufügen von Items.
|
||||
* @param newItem Das Item, dass hinzugefügt werden soll.
|
||||
* @return gibt zurück ob das Item hinzugefügt wurde, d.h. true wenn hinzugefügt und false wenn nicht hinzugefügt.
|
||||
*/
|
||||
public boolean addItem(Item newItem){
|
||||
for(int i =0;i< items.length;i++) {
|
||||
if (items[i] == null) {
|
||||
items[i] = newItem;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
16
Zoelda/src/main/items/Item.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package main.items;
|
||||
//TODO:Hier soll die Item Oberklasse entstehen
|
||||
public class Item {
|
||||
private String icon;
|
||||
|
||||
public Item(String iconPath){
|
||||
icon=iconPath;
|
||||
}
|
||||
/**
|
||||
* Gibt den Pfad zu dem Icon dieses Items an.
|
||||
* @return String, der den Pfad des Icons dieses Items beschreibt
|
||||
*/
|
||||
public String getIconPath(){
|
||||
return icon;
|
||||
}
|
||||
}
|
||||
@@ -5,22 +5,39 @@ import main.Tile;
|
||||
public class Corridor extends Map {
|
||||
|
||||
public Corridor() {
|
||||
super(5, 10);
|
||||
super(15, 11);
|
||||
|
||||
for (int x = 0; x < map.length; x++) {
|
||||
for (int y = 0; y < map[0].length; y++) {
|
||||
if((y == 0 || x == 0 || y == 9 || x == 4) && x != 2 ) {
|
||||
map[x][y] = new Tile(3, x, y);
|
||||
add(map[x][y]);
|
||||
} else if(y == 1 && (x != 0 || x != 4)&& x != 2 ) {
|
||||
map[x][y] = new Tile(4, x, y);
|
||||
add(map[x][y]);
|
||||
for (int x = 0; x < tiles.length; x++) {
|
||||
for (int y = 0; y < tiles[0].length; y++) {
|
||||
// Wand
|
||||
if ((y == 0 || x == 5 || y == 10 || x == 9) && x != 7 && x >= 5 && x <= 9) {
|
||||
tiles[x][y] = new Tile(Tile.STONE_WALL, x, y);
|
||||
add(tiles[x][y]);
|
||||
}
|
||||
else {
|
||||
map[x][y] = new Tile(0, x, y);
|
||||
add(map[x][y]);
|
||||
// 3D-Wand
|
||||
else if (y == 1 && (x != 0 || x != 4) && x != 7 && x >= 6 && x <= 8) {
|
||||
tiles[x][y] = new Tile(Tile.STONE_WALL_BOTTOM, x, y);
|
||||
add(tiles[x][y]);
|
||||
}
|
||||
// Steinboden
|
||||
else if (x >= 6 && x <= 8) {
|
||||
if (x == 7 && (y == 0 || y == tiles[0].length - 1)) {
|
||||
} else {
|
||||
tiles[x][y] = new Tile(Tile.STONE_FLOOR, x, y);
|
||||
add(tiles[x][y]);
|
||||
}
|
||||
} else {
|
||||
tiles[x][y] = new Tile(Tile.VOID, x, y);
|
||||
add(tiles[x][y]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map clone() {
|
||||
Corridor c = new Corridor();
|
||||
c.cloneTiles(this);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
106
Zoelda/src/main/maps/ImageMap.java
Normal file
@@ -0,0 +1,106 @@
|
||||
package main.maps;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import main.DoorTile;
|
||||
import main.Tile;
|
||||
|
||||
public class ImageMap extends Map {
|
||||
|
||||
// Erstellung der abzulesenden Tiles (einem Tile wird eine Farbe zugewiesen)
|
||||
|
||||
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_LEFT, new Color(255, 150, 0)),
|
||||
new PixelTile(Tile.DOOR_RIGHT, new Color(69, 150, 0)),
|
||||
new PixelTile(Tile.DOOR_BOTTOM, new Color(150, 150, 0)),
|
||||
new PixelTile(Tile.DOOR_TOP, new Color(0, 147, 150)),
|
||||
new PixelTile(Tile.STONE_WALL_BOTTOM, new Color(145, 145, 145)),
|
||||
new PixelTile(Tile.STONE_FLOOR_SHADOW_LEFT, new Color(251, 251, 129)) };
|
||||
|
||||
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_LEFT) {
|
||||
DoorTile door = new DoorTile(id, x, y, this);
|
||||
leftDoor = door;
|
||||
door.setSide(DoorTile.LEFT);
|
||||
tiles[x][y] = door;
|
||||
add(tiles[x][y]);
|
||||
continue;
|
||||
}
|
||||
if (id == Tile.DOOR_RIGHT ) {
|
||||
DoorTile door = new DoorTile(id, x, y, this);
|
||||
rightDoor = door;
|
||||
door.setSide(DoorTile.RIGHT);
|
||||
tiles[x][y] = door;
|
||||
add(tiles[x][y]);
|
||||
continue;
|
||||
}
|
||||
if (id == Tile.DOOR_TOP) {
|
||||
DoorTile door = new DoorTile(id, x, y, this);
|
||||
topDoor = door;
|
||||
door.setSide(DoorTile.TOP);
|
||||
tiles[x][y] = door;
|
||||
add(tiles[x][y]);
|
||||
continue;
|
||||
}
|
||||
if (id == Tile.DOOR_BOTTOM) {
|
||||
DoorTile door = new DoorTile(id, x, y, this);
|
||||
bottomDoor = door;
|
||||
door.setSide(DoorTile.BOTTOM);
|
||||
tiles[x][y] = door;
|
||||
add(tiles[x][y]);
|
||||
continue;
|
||||
}
|
||||
|
||||
tiles[x][y] = new Tile(id, x, y);
|
||||
add(tiles[x][y]);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public ImageMap(ImageMap map) {
|
||||
super(map.getWidth(), map.getHeight());
|
||||
cloneTiles(map);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageMap clone() {
|
||||
return new ImageMap(this);
|
||||
}
|
||||
}
|
||||
@@ -3,42 +3,155 @@ package main.maps;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import ea.Knoten;
|
||||
import ea.Ticker;
|
||||
import main.DoorTile;
|
||||
import main.Main;
|
||||
import main.Tile;
|
||||
import main.entities.AnimatedEntity;
|
||||
import main.entities.Entity;
|
||||
import main.entities.player.Player;
|
||||
|
||||
/**
|
||||
* Auf der Map sind alle Entities, sowie die Tiles gespiechert.
|
||||
*/
|
||||
public abstract class Map extends Knoten {
|
||||
public abstract class Map extends Knoten implements Ticker {
|
||||
|
||||
protected Tile[][] map; // Die Tiles der map in einem 2D Array.
|
||||
protected Tile[][] tiles; // Die Tiles der map in einem 2D Array.
|
||||
private ArrayList<Entity> entities;
|
||||
private boolean started;
|
||||
|
||||
public DoorTile topDoor;
|
||||
public DoorTile leftDoor;
|
||||
public DoorTile rightDoor;
|
||||
public DoorTile bottomDoor;
|
||||
|
||||
public Map(int width, int height) {
|
||||
map = new Tile[width][height];
|
||||
tiles = new Tile[width][height];
|
||||
|
||||
entities = new ArrayList<>(100);
|
||||
|
||||
Main.instance.manager.anmelden(this, 20);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt das Tile-Objekt an der gegebenen Koordinate zurück. (nur wenn es existiert)
|
||||
* Gibt das Tile-Objekt an der gegebenen Koordinate zurück. (nur wenn es
|
||||
* existiert)
|
||||
*/
|
||||
public Tile getTile(int x, int y) {
|
||||
if (x >= 0 && x < map.length && y >= 0 && y < map[0].length) {
|
||||
return map[x][y];
|
||||
if (x >= 0 && x < tiles.length && y >= 0 && y < tiles[0].length) {
|
||||
return tiles[x][y];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
for (int i = 0; i < entities.size(); i++) {
|
||||
Entity e = entities.get(i);
|
||||
if (e.isReadyToDelete()) {
|
||||
if (e instanceof AnimatedEntity) {
|
||||
entfernen(((AnimatedEntity) e).actionFigur);
|
||||
}
|
||||
Main.instance.manager.abmelden(e);
|
||||
entities.remove(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return map.length;
|
||||
return tiles.length;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return map[0].length;
|
||||
return tiles[0].length;
|
||||
}
|
||||
|
||||
public ArrayList<Entity> getEntities() {
|
||||
return entities;
|
||||
}
|
||||
|
||||
public void addAnimatedEntity(AnimatedEntity e) {
|
||||
entities.add(e);
|
||||
add(e.actionFigur);
|
||||
if (started) {
|
||||
Main.instance.manager.anmelden(e, 20);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract Map clone();
|
||||
|
||||
public void cloneTiles(Map map) {
|
||||
for (int x = 0; x < map.getWidth(); x++) {
|
||||
for (int y = 0; y < map.getHeight(); y++) {
|
||||
tiles[x][y] = map.getTile(x, y).clone();
|
||||
if (tiles[x][y] instanceof DoorTile) {
|
||||
DoorTile dt = (DoorTile) tiles[x][y];
|
||||
if (dt.getSide() == DoorTile.TOP) {
|
||||
topDoor = dt;
|
||||
topDoor.setMap(this);
|
||||
}
|
||||
if (dt.getSide() == DoorTile.BOTTOM) {
|
||||
bottomDoor = dt;
|
||||
bottomDoor.setMap(this);
|
||||
}
|
||||
if (dt.getSide() == DoorTile.LEFT) {
|
||||
leftDoor = dt;
|
||||
leftDoor.setMap(this);
|
||||
}
|
||||
if (dt.getSide() == DoorTile.RIGHT) {
|
||||
rightDoor = dt;
|
||||
rightDoor.setMap(this);
|
||||
}
|
||||
}
|
||||
add(tiles[x][y]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void start() {
|
||||
if (topDoor != null) {
|
||||
Main.instance.manager.anmelden(topDoor, 50);
|
||||
}
|
||||
if (bottomDoor != null) {
|
||||
Main.instance.manager.anmelden(bottomDoor, 50);
|
||||
}
|
||||
if (leftDoor != null) {
|
||||
Main.instance.manager.anmelden(leftDoor, 50);
|
||||
}
|
||||
if (rightDoor != null) {
|
||||
Main.instance.manager.anmelden(rightDoor, 50);
|
||||
}
|
||||
for (Entity e : entities) {
|
||||
if (!(e instanceof Player)) {
|
||||
Main.instance.manager.anmelden(e, 20);
|
||||
}
|
||||
}
|
||||
started = true;
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
if (topDoor != null) {
|
||||
Main.instance.manager.abmelden(topDoor);
|
||||
}
|
||||
if (bottomDoor != null) {
|
||||
Main.instance.manager.abmelden(bottomDoor);
|
||||
}
|
||||
if (leftDoor != null) {
|
||||
Main.instance.manager.abmelden(leftDoor);
|
||||
}
|
||||
if (rightDoor != null) {
|
||||
Main.instance.manager.abmelden(rightDoor);
|
||||
}
|
||||
for (Entity e : entities) {
|
||||
if (!(e instanceof Player)) {
|
||||
Main.instance.manager.abmelden(e);
|
||||
}
|
||||
}
|
||||
started = false;
|
||||
}
|
||||
|
||||
public void connectDoors(DoorTile door, DoorTile door2) {
|
||||
door.setConnectedDoor(door2);
|
||||
door2.setConnectedDoor(door);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
package main.maps;
|
||||
|
||||
import main.Tile;
|
||||
|
||||
public class TestMap extends Map {
|
||||
|
||||
public TestMap() {
|
||||
super(15, 11);
|
||||
|
||||
for (int x = 0; x < map.length; x++) {
|
||||
for (int y = 0; y < map[0].length; y++) {
|
||||
map[x][y] = new Tile(Math.random() * 5 < 1 ? 1 : 0, x, y);
|
||||
add(map[x][y]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
41
Zoelda/src/main/maps/TutorialMap.java
Normal file
@@ -0,0 +1,41 @@
|
||||
package main.maps;
|
||||
|
||||
import main.Tile;
|
||||
import main.entities.Snake;
|
||||
import main.entities.Spider;
|
||||
|
||||
public class TutorialMap extends Map {
|
||||
|
||||
public TutorialMap() {
|
||||
super(15, 11);
|
||||
for (int x = 0; x < tiles.length; x++) {
|
||||
for (int y = 0; y < tiles[0].length; y++) {
|
||||
//Wand, Sichtschutz
|
||||
if (y == 0 ||y == tiles[0].length - 1 || x == 0 || x == tiles.length - 1 || ((y == 4|| y == 5) && x == 10 )) {
|
||||
tiles[x][y] = new Tile (1, x, y);
|
||||
add(tiles [x][y]);
|
||||
}
|
||||
//3D-Wand, 3F-Sichtschutz
|
||||
else if(y == 1 || ( y == 6 && x == 10)) {
|
||||
tiles[x][y] = new Tile (2, x, y);
|
||||
add(tiles [x][y]);
|
||||
}
|
||||
//Grasboden
|
||||
else{
|
||||
tiles[x][y] = new Tile(0, x, y);
|
||||
add(tiles[x][y]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addAnimatedEntity(new Spider());
|
||||
addAnimatedEntity(new Snake());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map clone() {
|
||||
TutorialMap c = new TutorialMap();
|
||||
c.cloneTiles(this);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
41
Zoelda/src/main/worlds/TestWorld.java
Normal file
@@ -0,0 +1,41 @@
|
||||
package main.worlds;
|
||||
|
||||
import main.entities.Coin;
|
||||
import main.entities.Rick;
|
||||
import main.entities.Snake;
|
||||
import main.entities.Spider;
|
||||
import main.maps.Map;
|
||||
|
||||
public class TestWorld extends World {
|
||||
|
||||
public TestWorld() {
|
||||
super(4);
|
||||
|
||||
Map m2 = maps[3].clone();
|
||||
getCurrentMap().connectDoors(getCurrentMap().bottomDoor, m2.topDoor);
|
||||
|
||||
for (int i = 0; i < 15; i++) {
|
||||
Coin c = new Coin();
|
||||
c.setPosX(i * 0.5f + 4);
|
||||
getCurrentMap().addAnimatedEntity(c);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
Snake s = new Snake();
|
||||
s.setPosX((float) (Math.random() * 5 + 2));
|
||||
getCurrentMap().addAnimatedEntity(s);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
Spider spooda = new Spider();
|
||||
spooda.setPosX((float) (Math.random() * 5 + 2));
|
||||
getCurrentMap().addAnimatedEntity(spooda);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 1; i++) {
|
||||
Rick astley = new Rick();
|
||||
astley.setPosX((float) (Math.random() * 5 + 2));
|
||||
getCurrentMap().addAnimatedEntity(astley);
|
||||
}
|
||||
}
|
||||
}
|
||||
67
Zoelda/src/main/worlds/World.java
Normal file
@@ -0,0 +1,67 @@
|
||||
package main.worlds;
|
||||
|
||||
import ea.Knoten;
|
||||
import main.DoorTile;
|
||||
import main.entities.player.Player;
|
||||
import main.maps.ImageMap;
|
||||
import main.maps.Map;
|
||||
|
||||
/**
|
||||
* Hier werden alle Maps gespeichert.
|
||||
*/
|
||||
public abstract class World extends Knoten {
|
||||
|
||||
public static final int SCALE_FACTOR = 4; // Der Basis Zoomfaktor
|
||||
public static final int SCALE = SCALE_FACTOR * 16; // Eine Gameunit ist so viele pixel lang
|
||||
|
||||
private Map currentMap; // Die Map die aktuell angezeigt werden soll.
|
||||
|
||||
private Player player;
|
||||
|
||||
protected static Map[] maps;
|
||||
|
||||
public World(int startMap) {
|
||||
if (maps == null) {
|
||||
maps = new ImageMap[8];
|
||||
for (int i = 0; i < maps.length; i++) {
|
||||
maps[i] = new ImageMap("/res/images/maps/map" + i + "a.png");
|
||||
}
|
||||
}
|
||||
init(maps[startMap]);
|
||||
}
|
||||
|
||||
public World(Map startMap) {
|
||||
init(startMap);
|
||||
}
|
||||
|
||||
private void init(Map startMap) {
|
||||
currentMap = startMap;
|
||||
player = new Player();
|
||||
add(currentMap);
|
||||
}
|
||||
|
||||
public Map getCurrentMap() {
|
||||
return currentMap;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public void changeMap(DoorTile door) {
|
||||
currentMap.stop();
|
||||
currentMap.entfernen(player.actionFigur);
|
||||
entfernen(currentMap);
|
||||
currentMap = door.getConnectedDoor().getMap();
|
||||
add(currentMap);
|
||||
currentMap.add(player.actionFigur);
|
||||
currentMap.start();
|
||||
player.setPos(door.getConnectedDoor().getPosX() + 0.5f, door.getConnectedDoor().getPosY() + 0.5f);
|
||||
door.getConnectedDoor().waitForLeave();
|
||||
}
|
||||
|
||||
public void start() {
|
||||
currentMap.addAnimatedEntity(player);
|
||||
currentMap.start();
|
||||
}
|
||||
}
|
||||
BIN
Zoelda/src/res/images/coinUpscaled.png
Normal file
|
After Width: | Height: | Size: 250 B |
BIN
Zoelda/src/res/images/coins.png
Normal file
|
After Width: | Height: | Size: 414 B |
BIN
Zoelda/src/res/images/herzen.png
Normal file
|
After Width: | Height: | Size: 327 B |
BIN
Zoelda/src/res/images/icons.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
Zoelda/src/res/images/inventory.png
Normal file
|
After Width: | Height: | Size: 116 B |
BIN
Zoelda/src/res/images/maps/map0.png
Normal file
|
After Width: | Height: | Size: 168 B |
BIN
Zoelda/src/res/images/maps/map0a.png
Normal file
|
After Width: | Height: | Size: 183 B |
BIN
Zoelda/src/res/images/maps/map1.png
Normal file
|
After Width: | Height: | Size: 169 B |
BIN
Zoelda/src/res/images/maps/map1a.png
Normal file
|
After Width: | Height: | Size: 180 B |
BIN
Zoelda/src/res/images/maps/map2.png
Normal file
|
After Width: | Height: | Size: 181 B |
BIN
Zoelda/src/res/images/maps/map2a.png
Normal file
|
After Width: | Height: | Size: 174 B |
BIN
Zoelda/src/res/images/maps/map3.png
Normal file
|
After Width: | Height: | Size: 171 B |
BIN
Zoelda/src/res/images/maps/map3a.png
Normal file
|
After Width: | Height: | Size: 292 B |
BIN
Zoelda/src/res/images/maps/map4.png
Normal file
|
After Width: | Height: | Size: 162 B |
BIN
Zoelda/src/res/images/maps/map4a.png
Normal file
|
After Width: | Height: | Size: 162 B |
BIN
Zoelda/src/res/images/maps/map5.png
Normal file
|
After Width: | Height: | Size: 166 B |
BIN
Zoelda/src/res/images/maps/map5a.png
Normal file
|
After Width: | Height: | Size: 161 B |
BIN
Zoelda/src/res/images/maps/map6.png
Normal file
|
After Width: | Height: | Size: 164 B |
BIN
Zoelda/src/res/images/maps/map6a.png
Normal file
|
After Width: | Height: | Size: 163 B |
BIN
Zoelda/src/res/images/maps/map7.png
Normal file
|
After Width: | Height: | Size: 160 B |
BIN
Zoelda/src/res/images/maps/map7a.png
Normal file
|
After Width: | Height: | Size: 173 B |
BIN
Zoelda/src/res/images/maps/mapdrei.png
Normal file
|
After Width: | Height: | Size: 248 B |
BIN
Zoelda/src/res/images/red-potion.png
Normal file
|
After Width: | Height: | Size: 593 B |
BIN
Zoelda/src/res/images/rick_sprite_sheet.png
Normal file
|
After Width: | Height: | Size: 444 B |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 1.8 KiB |
BIN
Zoelda/src/res/images/tiles/disco_sprite_sheet.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
Zoelda/src/res/images/tiles/door_bottom.png
Normal file
|
After Width: | Height: | Size: 262 B |
BIN
Zoelda/src/res/images/tiles/door_left.png
Normal file
|
After Width: | Height: | Size: 245 B |
BIN
Zoelda/src/res/images/tiles/door_right.png
Normal file
|
After Width: | Height: | Size: 243 B |
BIN
Zoelda/src/res/images/tiles/door_right_left_top.png
Normal file
|
After Width: | Height: | Size: 502 B |
BIN
Zoelda/src/res/images/tiles/door_top.png
Normal file
|
After Width: | Height: | Size: 276 B |
|
Before Width: | Height: | Size: 211 B After Width: | Height: | Size: 137 B |
BIN
Zoelda/src/res/images/tiles/stone_floor_shadow_left.png
Normal file
|
After Width: | Height: | Size: 151 B |
|
Before Width: | Height: | Size: 481 B After Width: | Height: | Size: 230 B |
|
Before Width: | Height: | Size: 342 B After Width: | Height: | Size: 450 B |