package core;
import java.awt.Toolkit;
import java.io.IOException;
import java.io.ObjectInputStream;
import tiles.Empty;
import tiles.Wall;
import tiles.WallAbove;
import tiles.WallAboveLeft;
import tiles.WallAboveLeftEnd;
import tiles.WallAboveRight;
import tiles.WallAboveRightEnd;
import tiles.WallBelow;
import tiles.WallLeft;
import tiles.WallBelowLeft;
import tiles.WallBelowLeftEnd;
import tiles.WallRight;
import tiles.WallBelowRight;
import tiles.WallBelowRightEnd;
/**
* Tilemap zur Darstellung der Levels über ein einfaches Integer Array.
* Ein Tile (Bildobjekte) wird über einen Zahlenindex angesprochen und durch diesen Zahlenindex in der Welt repräsentiert.
*
* @author Marco Strobel
*/
public class Tilemap {
// Instanz für das Singleton
private static Tilemap tilemap;
// Repräsentation des Levels durch ein Array aus Datenobjekten
private int map[][];
// Das Array mit den Bildobjekten
private Sprite tiles[];
// Die Entity Startpositionen
private int[][] entities;
// Größe der Bildobjekte
private int tilesizeX;
private int tilesizeY;
/**
* Instanzrückgabe für das Singleton
*/
public static synchronized Tilemap getInstance() {
if (tilemap == null)
tilemap = new Tilemap();
return tilemap;
}
/**
* Rückgabe der Repräsentation des Levels
*
* @return Die Repräsentation des Levels
*/
public int[][] getMap() {
return map;
}
/**
* Rückgabe der Breite der Bildobjekte
*
* @return Die Breite der Bildobjekte
*/
public int getTilesizeX() {
return tilesizeX;
}
/**
* Rückgabe der Höhe der Bildobjekte
*
* @return Die Höhe der Bildobjekte
*/
public int getTilesizeY() {
return tilesizeY;
}
/**
* Zeichnen der Tilemap über den Renderer
*/
public void draw() {
View view = View.getInstance();
// Werte der ersten Spalte von Tiles in der View
int beginX = (int)view.getMinX() / tilesizeX;
// Werte der letzten Spalte von Tiles in der View
// Falls der Berechnete Wert größer ist als der eigentliche Inhalt der Map, letzte Spalte der Map nutzen
int endX = ((int)view.getMaxX() / tilesizeX + 1 < map[0].length) ? (int)view.getMaxX() / tilesizeX + 1 : map[0].length;
for (int y = 0; y < map.length; y++)
for (int x = beginX; x < endX; x++) {
// Tile das auf den Koordinaten liegt laden
Sprite tempSprite = tiles[map[y][x]];
// Tile auf die Koordinaten setzen und zeichnen
synchronized (tempSprite) {
tempSprite.getHitbox().setLocation(x * tilesizeX, y * tilesizeY);
Renderer.getInstance().draw(tempSprite);
}
}
}
/**
* Finden einer Zahlenrepräsentation eines Bildobjekts an einem Punkt des Koordinatensystems
*
* @param x X-Koordinate
* @param y Y-Koordinate
* @return Bildobjekte an diesem Punkt im Koordinatensystem
*/
public Sprite getTilefromCoord(int x, int y) {
try {
return tiles[map[y / tilesizeY][x / tilesizeX]];
} catch (ArrayIndexOutOfBoundsException e) {
return tiles[0];
}
}
/**
* Laden neuer Kartendaten
*
* @param level Das zu ladende Level
*/
public void loadMap(int level) {
try {
ObjectInputStream in = new ObjectInputStream( getClass().getResourceAsStream("/maps/level" + level + ".map") );
map = (int[][])in.readObject();
in.close();
}catch(ClassNotFoundException ex) {
ex.printStackTrace();
}catch(IOException ex) {
ex.printStackTrace();
}
}
/**
* Laden der Akteure
*
* @param level Das zu ladende Level
*/
public int[][] loadEntityData(int level) {
try {
ObjectInputStream in = new ObjectInputStream( getClass().getResourceAsStream("/maps/level" + level + ".ent") );
entities = (int[][])in.readObject();
in.close();
}catch(ClassNotFoundException ex) {
ex.printStackTrace();
}catch(IOException ex) {
ex.printStackTrace();
}
return entities;
}
/**
* Konstruktor zum erstellen eines Tilemap Objekts
*/
private Tilemap() {
tilesizeX = 64;
tilesizeY = 64;
// Laden der Tilegrafiken für die Tilemap
tiles = new Sprite[] {
new Empty(tilesizeX, tilesizeY,
Toolkit.getDefaultToolkit().getImage( getClass().getResource("/images/tiles/empty.png") )),
new WallBelowLeft(tilesizeX, tilesizeY,
Toolkit.getDefaultToolkit().getImage( getClass().getResource("/images/tiles/wallbelowleft.png") )),
new WallBelowRight(tilesizeX, tilesizeY,
Toolkit.getDefaultToolkit().getImage( getClass().getResource("/images/tiles/wallbelowright.png") )),
new WallLeft(tilesizeX, tilesizeY,
Toolkit.getDefaultToolkit().getImage( getClass().getResource("/images/tiles/wallleft.png") )),
new WallRight(tilesizeX, tilesizeY,
Toolkit.getDefaultToolkit().getImage( getClass().getResource("/images/tiles/wallright.png") )),
new WallBelowLeftEnd(tilesizeX, tilesizeY,
Toolkit.getDefaultToolkit().getImage( getClass().getResource("/images/tiles/wallbelowleftend.png") )),
new WallBelow(tilesizeX, tilesizeY,
Toolkit.getDefaultToolkit().getImage( getClass().getResource("/images/tiles/wallbelow.png") )),
new WallBelowRightEnd(tilesizeX, tilesizeY,
Toolkit.getDefaultToolkit().getImage( getClass().getResource("/images/tiles/wallbelowrightend.png") )),
new Wall(tilesizeX, tilesizeY,
Toolkit.getDefaultToolkit().getImage( getClass().getResource("/images/tiles/wall.png") )),
new WallAboveLeftEnd(tilesizeX, tilesizeY,
Toolkit.getDefaultToolkit().getImage( getClass().getResource("/images/tiles/wallaboveleftend.png") )),
new WallAbove(tilesizeX, tilesizeY,
Toolkit.getDefaultToolkit().getImage( getClass().getResource("/images/tiles/wallabove.png") )),
new WallAboveRightEnd(tilesizeX, tilesizeY,
Toolkit.getDefaultToolkit().getImage( getClass().getResource("/images/tiles/wallaboverightend.png") )),
new WallAboveLeft(tilesizeX, tilesizeY,
Toolkit.getDefaultToolkit().getImage( getClass().getResource("/images/tiles/wallaboveleft.png") )),
new WallAboveRight(tilesizeX, tilesizeY,
Toolkit.getDefaultToolkit().getImage( getClass().getResource("/images/tiles/wallaboveright.png") )),
};
}
}