Add map state

main
trivernis 1 year ago
parent 4c508a2e55
commit 4afb0cd3fb
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -1,23 +1,18 @@
package com.last.commit.map
import com.badlogic.gdx.math.Rectangle
import com.badlogic.gdx.math.Vector2
import com.last.commit.audio.GameSoundEffect
import Position
import GameState
class Collectible(
name: String,
val pos: Position,
width: Float,
height: Float
) : Interactable {
class Collectible(name: String, val pos: Position, private val size: Vector2) : Interactable {
val name: String
private val collider: Rectangle
init {
this.name = name
this.collider = Rectangle(pos.x, pos.y, width, height)
this.collider = Rectangle(pos.x, pos.y, size.x, size.y)
}
override fun interact(otherCollider: Rectangle, state: GameState) {

@ -0,0 +1,112 @@
package com.last.commit.map
import com.last.commit.map.Collectible
import com.last.commit.map.Door
import com.last.commit.Wall
import com.badlogic.gdx.maps.tiled.TiledMap
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer
import com.badlogic.gdx.maps.MapObject
import com.badlogic.gdx.maps.objects.RectangleMapObject
import com.badlogic.gdx.math.Vector2
import com.badlogic.gdx.math.Rectangle
import kotlin.math.round;
class MapState(val map: TiledMap) {
private val CELL_SIZE = 64
val size: Vector2
val gridSize: Vector2
val tileSize: Vector2
val description: String?
val collectibles: ArrayList<Collectible> = ArrayList()
val teleporters: ArrayList<RectangleMapObject> = ArrayList()
val walls: ArrayList<Wall> = ArrayList()
val doors: ArrayList<Door> = ArrayList()
init {
val prop = map.properties
val gridWidth = prop.get("width", Int::class.java)
val gridHeight = prop.get("height", Int::class.java)
gridSize = Vector2(gridWidth.toFloat(), gridHeight.toFloat())
description = prop.get("description", String::class.java)
val width = gridWidth * CELL_SIZE
val height = gridHeight * CELL_SIZE
size = Vector2(width.toFloat(), height.toFloat())
val tileWidth = map.properties.get("tilewidth", Int::class.java)
val tileHeight = map.properties.get("tileheight", Int::class.java)
tileSize = Vector2(tileWidth.toFloat(), tileHeight.toFloat())
this.loadCollectibles()
this.loadWalls()
for (obj in map.layers["Teleporter"].objects) {
if (obj is RectangleMapObject) {
this.teleporters.add(obj)
println("Teleporter ${obj}")
}
}
if (this.teleporters.isEmpty()) {
println("No Teleporters defined!")
}
}
private fun loadCollectibles() {
val collectiableLayer = map.layers["Collectibles"]
if (collectiableLayer == null) {
println("Could not load collectibles layer. Check map.")
return
}
collectiableLayer.objects.mapNotNullTo(collectibles) { createCollectible(it) }
println("Loaded ${collectibles.size} collectibles")
}
private fun createCollectible(obj: MapObject): Collectible? {
val x = obj.properties.get("x", Float::class.java)
val y = obj.properties.get("y", Float::class.java)
val coords = Vector2(x, y)
val gridCoords = Vector2(round(x / tileSize.x), round(y / tileSize.y))
val width = obj.properties.get("width", Float::class.java)
val height = obj.properties.get("height", Float::class.java)
val size = Vector2(width, height)
return if (obj is RectangleMapObject) {
val itemName: String? = obj.properties.get("item", String::class.java)
if (itemName != null) {
Collectible(itemName, Position(coords, gridCoords), size)
} else {
null
}
} else {
null
}
}
private fun loadWalls() {
walls.clear()
doors.clear()
val wallsLayer = map.layers["Walls"] as TiledMapTileLayer
for (column in 0 until wallsLayer.width) {
for (row in 0 until wallsLayer.height) {
val cell = wallsLayer.getCell(column, row)?: continue
val isDoor: Boolean = cell.getTile().getProperties().get("isDoor", false, Boolean::class.java)
val wallCollider = Rectangle(
column.toFloat() * wallsLayer.tileWidth,
row.toFloat() * wallsLayer.tileHeight, wallsLayer.tileWidth.toFloat(),
wallsLayer.tileHeight.toFloat()
)
if (java.lang.Boolean.TRUE == isDoor) {
doors.add(Door(column, row, wallCollider, cell))
} else {
walls.add(Wall(column, row, wallCollider, cell))
}
}
}
}
}

@ -1,3 +1,5 @@
package com.last.commit.map
import com.badlogic.gdx.math.Vector2
public data class Position(

@ -1,7 +1,5 @@
package com.last.commit.map
import GameState
import Position
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.OrthographicCamera
import com.badlogic.gdx.graphics.g2d.SpriteBatch
@ -12,67 +10,75 @@ import com.badlogic.gdx.maps.tiled.TmxMapLoader
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer
import com.badlogic.gdx.math.Rectangle
import com.badlogic.gdx.math.Vector2
import com.badlogic.gdx.scenes.scene2d.ui.Image
import com.badlogic.gdx.utils.Array
import com.badlogic.gdx.scenes.scene2d.ui.Image
import com.last.commit.Collidable
import com.last.commit.Player
import com.last.commit.Wall
import com.last.commit.audio.GameSoundEffect
import com.last.commit.inventory.InventoryItemTextureLoader
import GameState
class TimeMap(fileName: String, val state: GameState) {
private val CELL_SIZE = 64
val textureLoader = InventoryItemTextureLoader("sprites/genericItems_spritesheet_colored")
private val walls = Array<Wall>()
private val doors = Array<Door>()
private val collectibles = Array<Collectible>()
val mapLoader: TmxMapLoader = TmxMapLoader()
lateinit var mapRenderer: OrthogonalTiledMapRenderer
lateinit var map: TiledMap
var gridWidth = 0
var gridHeight = 0
var width = 0
var height = 0
var mapTileWidth = 0
var mapTileHeight = 0
var halfMapTileWidth = 0f
var halfMapTileHeight = 0f
var description: String = "2020"
private set
var mapRenderer: OrthogonalTiledMapRenderer
var mapState: MapState
val mapStates: HashMap<String, MapState> = HashMap()
var map: TiledMap
val gridWidth: Int
get() = mapState.gridSize.x.toInt()
init {
loadMap(fileName)
loadDimensions()
loadWalls()
loadCollectibles()
this.textureLoader.parse()
}
val gridHeight: Int
get() = mapState.gridSize.y.toInt()
val width: Int
get() = mapState.size.x.toInt()
val height: Int
get() = mapState.size.y.toInt()
private fun loadMap(fileName: String) {
println("Loading map $fileName")
val mapTileWidth: Int
get() = mapState.tileSize.x.toInt()
val mapTileHeight: Int
get() = mapState.tileSize.y.toInt()
init {
map = mapLoader.load(fileName)
mapState = MapState(map)
mapStates[fileName] = mapState
mapRenderer = OrthogonalTiledMapRenderer(map)
this.textureLoader.parse()
}
fun teleport(player: Player) {
val teleporters = map.layers["Teleporter"].objects
for (teleporter in teleporters) {
if (teleporter is RectangleMapObject) {
if (teleporter.rectangle.contains(player.getX(), player.getY())) {
state.soundEngine.play(GameSoundEffect.TIME_TRAVEL)
val targetMap = teleporter.properties.get("target", String::class.java)
System.out.println("Teleporting to targetMap $targetMap")
loadMap("tiled/$targetMap")
loadDimensions()
loadWalls()
loadCollectibles()
}
} else {
println("Found illegal teleporter. ${teleporter.properties.get("id")}")
}
val teleporter = mapState.teleporters.find {
it.rectangle.contains(player.getX(), player.getY())
}
if (teleporter != null) {
state.soundEngine.play(GameSoundEffect.TIME_TRAVEL)
val targetMap = teleporter.properties.get("target", String::class.java)
System.out.println("Teleporting to targetMap $targetMap")
loadMap("tiled/$targetMap")
}
}
private fun loadMap(name: String) {
val newState = this.mapStates.get(name)
if (newState != null) {
mapState = newState
mapRenderer.map = mapState.map
} else {
val map = mapLoader.load(name)
mapRenderer.map = map
mapState = MapState(map)
mapStates[name] = mapState
}
}
@ -95,87 +101,13 @@ class TimeMap(fileName: String, val state: GameState) {
return Vector2.Zero
}
private fun loadDimensions() {
val prop = map.properties
this.gridWidth = prop.get("width", Int::class.java)
this.gridHeight = prop.get("height", Int::class.java)
if (prop.containsKey("description")) {
this.description = prop.get("description", String::class.java)
} else {
this.description = "Unknown time"
}
this.state.mapDescription = this.description
this.width = gridWidth * CELL_SIZE
this.height = gridHeight * CELL_SIZE
this.mapTileWidth = map.properties.get("tilewidth", Int::class.java)
this.mapTileHeight = map.properties.get("tileheight", Int::class.java)
this.halfMapTileWidth = mapTileWidth / 2f
this.halfMapTileHeight = mapTileHeight / 2f
}
private fun loadWalls() {
walls.clear()
doors.clear()
val wallsLayer = map.layers["Walls"] as TiledMapTileLayer
for (column in 0 until wallsLayer.width) {
for (row in 0 until wallsLayer.height) {
val cell: TiledMapTileLayer.Cell? = wallsLayer.getCell(column, row)
if (cell != null) {
val isDoor: Boolean = cell.getTile().getProperties().get("isDoor", false, Boolean::class.java)
val wallCollider = Rectangle(
column.toFloat() * wallsLayer.tileWidth,
row.toFloat() * wallsLayer.tileHeight, wallsLayer.tileWidth.toFloat(),
wallsLayer.tileHeight.toFloat()
)
if (java.lang.Boolean.TRUE == isDoor) {
doors.add(Door(column, row, wallCollider, cell))
} else {
walls.add(Wall(column, row, wallCollider, cell))
}
}
}
}
}
fun loadCollectibles() {
this.collectibles.clear()
val collectiableLayer = map.layers["Collectibles"]
if (collectiableLayer == null) {
println("Could not load collectibles layer. Check map.")
return
}
val collectibleMapObjects = collectiableLayer.objects
for (mapObject in collectibleMapObjects) {
val mapObjectProperties = mapObject.properties
val x = mapObjectProperties.get("x", Float::class.java)
val gridX = Math.round(x / mapTileWidth)
val y = mapObjectProperties.get("y", Float::class.java)
val gridY = Math.round(y / mapTileHeight)
val width = mapObjectProperties.get("width", Float::class.java)
val height = mapObjectProperties.get("height", Float::class.java)
if (mapObject is RectangleMapObject) {
val itemName = mapObjectProperties.get("item", String::class.java)
itemName?. let {
this.collectibles.add(Collectible(itemName, Position(x, y, gridX, gridY), width, height))
}
} else {
println("Found non-rectangular map object at ${x}-${y} skipping it")
}
}
println("Loaded ${collectibles.size} collectibles")
}
private fun findInteractableAtPosition(gridX: Int, gridY: Int): Interactable? {
for (door in doors) {
if (door.gridX == gridX && door.gridY == gridY && door is Door) {
for (door in mapState.doors) {
if (door.gridX == gridX && door.gridY == gridY) {
return door
}
}
for (collectible in collectibles) {
for (collectible in mapState.collectibles) {
if (collectible.pos.gridX == gridX && collectible.pos.gridY == gridY) {
return collectible
}
@ -207,7 +139,7 @@ class TimeMap(fileName: String, val state: GameState) {
fun render(batch: SpriteBatch, camera: OrthographicCamera, delta: Float) {
mapRenderer.setView(camera)
mapRenderer.render()
this.collectibles.forEach { coll ->
this.mapState.collectibles.forEach { coll ->
val image = Image(textureLoader.getTexture(coll.name))
image.x = coll.pos.x + this.getTileWidth() * 0.1f
image.y = coll.pos.y + this.getTileHeight() * 0.1f
@ -219,12 +151,12 @@ class TimeMap(fileName: String, val state: GameState) {
fun isCollidingWith(collidable: Collidable): Boolean {
for (wall in walls) {
for (wall in mapState.walls) {
if (wall.collidesWidth(collidable)) {
return true
}
}
for (door in doors) {
for (door in mapState.doors) {
if (door.collidesWidth(collidable)) {
return true
}
@ -234,9 +166,9 @@ class TimeMap(fileName: String, val state: GameState) {
fun getInteractablesAt(absoluteDirection: Vector2): List<Interactable> {
val interactables = ArrayList<Interactable>()
val c = collectibles.filter { it.getCollider().contains(absoluteDirection) }
val c = mapState.collectibles.filter { it.getCollider().contains(absoluteDirection) }
interactables.addAll(c)
val w = doors.filter { it.getCollider().contains(absoluteDirection) }
val w = mapState.doors.filter { it.getCollider().contains(absoluteDirection) }
interactables.addAll(w)
return interactables

Loading…
Cancel
Save