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 package com.last.commit.map
import com.badlogic.gdx.math.Rectangle import com.badlogic.gdx.math.Rectangle
import com.badlogic.gdx.math.Vector2
import com.last.commit.audio.GameSoundEffect import com.last.commit.audio.GameSoundEffect
import Position
import GameState import GameState
class Collectible( class Collectible(name: String, val pos: Position, private val size: Vector2) : Interactable {
name: String,
val pos: Position,
width: Float,
height: Float
) : Interactable {
val name: String val name: String
private val collider: Rectangle private val collider: Rectangle
init { init {
this.name = name 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) { 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 import com.badlogic.gdx.math.Vector2
public data class Position( public data class Position(

@ -1,7 +1,5 @@
package com.last.commit.map package com.last.commit.map
import GameState
import Position
import com.badlogic.gdx.Gdx import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.OrthographicCamera import com.badlogic.gdx.graphics.OrthographicCamera
import com.badlogic.gdx.graphics.g2d.SpriteBatch 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.maps.tiled.renderers.OrthogonalTiledMapRenderer
import com.badlogic.gdx.math.Rectangle import com.badlogic.gdx.math.Rectangle
import com.badlogic.gdx.math.Vector2 import com.badlogic.gdx.math.Vector2
import com.badlogic.gdx.scenes.scene2d.ui.Image
import com.badlogic.gdx.utils.Array import com.badlogic.gdx.utils.Array
import com.badlogic.gdx.scenes.scene2d.ui.Image
import com.last.commit.Collidable import com.last.commit.Collidable
import com.last.commit.Player import com.last.commit.Player
import com.last.commit.Wall import com.last.commit.Wall
import com.last.commit.audio.GameSoundEffect import com.last.commit.audio.GameSoundEffect
import com.last.commit.inventory.InventoryItemTextureLoader import com.last.commit.inventory.InventoryItemTextureLoader
import GameState
class TimeMap(fileName: String, val state: GameState) { class TimeMap(fileName: String, val state: GameState) {
private val CELL_SIZE = 64 private val CELL_SIZE = 64
val textureLoader = InventoryItemTextureLoader("sprites/genericItems_spritesheet_colored") 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() val mapLoader: TmxMapLoader = TmxMapLoader()
lateinit var mapRenderer: OrthogonalTiledMapRenderer var mapRenderer: OrthogonalTiledMapRenderer
lateinit var map: TiledMap var mapState: MapState
var gridWidth = 0 val mapStates: HashMap<String, MapState> = HashMap()
var gridHeight = 0 var map: TiledMap
var width = 0
var height = 0
var mapTileWidth = 0
var mapTileHeight = 0
var halfMapTileWidth = 0f
var halfMapTileHeight = 0f
var description: String = "2020"
private set
val gridWidth: Int
get() = mapState.gridSize.x.toInt()
init { val gridHeight: Int
loadMap(fileName) get() = mapState.gridSize.y.toInt()
loadDimensions()
loadWalls() val width: Int
loadCollectibles() get() = mapState.size.x.toInt()
this.textureLoader.parse()
} val height: Int
get() = mapState.size.y.toInt()
private fun loadMap(fileName: String) { val mapTileWidth: Int
println("Loading map $fileName") get() = mapState.tileSize.x.toInt()
val mapTileHeight: Int
get() = mapState.tileSize.y.toInt()
init {
map = mapLoader.load(fileName) map = mapLoader.load(fileName)
mapState = MapState(map)
mapStates[fileName] = mapState
mapRenderer = OrthogonalTiledMapRenderer(map) mapRenderer = OrthogonalTiledMapRenderer(map)
this.textureLoader.parse()
} }
fun teleport(player: Player) { fun teleport(player: Player) {
val teleporters = map.layers["Teleporter"].objects val teleporter = mapState.teleporters.find {
for (teleporter in teleporters) { it.rectangle.contains(player.getX(), player.getY())
if (teleporter is RectangleMapObject) { }
if (teleporter.rectangle.contains(player.getX(), player.getY())) { if (teleporter != null) {
state.soundEngine.play(GameSoundEffect.TIME_TRAVEL) state.soundEngine.play(GameSoundEffect.TIME_TRAVEL)
val targetMap = teleporter.properties.get("target", String::class.java) val targetMap = teleporter.properties.get("target", String::class.java)
System.out.println("Teleporting to targetMap $targetMap") System.out.println("Teleporting to targetMap $targetMap")
loadMap("tiled/$targetMap") loadMap("tiled/$targetMap")
loadDimensions() }
loadWalls() }
loadCollectibles()
} private fun loadMap(name: String) {
} else { val newState = this.mapStates.get(name)
println("Found illegal teleporter. ${teleporter.properties.get("id")}") 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 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? { private fun findInteractableAtPosition(gridX: Int, gridY: Int): Interactable? {
for (door in doors) { for (door in mapState.doors) {
if (door.gridX == gridX && door.gridY == gridY && door is Door) { if (door.gridX == gridX && door.gridY == gridY) {
return door return door
} }
} }
for (collectible in collectibles) { for (collectible in mapState.collectibles) {
if (collectible.pos.gridX == gridX && collectible.pos.gridY == gridY) { if (collectible.pos.gridX == gridX && collectible.pos.gridY == gridY) {
return collectible return collectible
} }
@ -207,7 +139,7 @@ class TimeMap(fileName: String, val state: GameState) {
fun render(batch: SpriteBatch, camera: OrthographicCamera, delta: Float) { fun render(batch: SpriteBatch, camera: OrthographicCamera, delta: Float) {
mapRenderer.setView(camera) mapRenderer.setView(camera)
mapRenderer.render() mapRenderer.render()
this.collectibles.forEach { coll -> this.mapState.collectibles.forEach { coll ->
val image = Image(textureLoader.getTexture(coll.name)) val image = Image(textureLoader.getTexture(coll.name))
image.x = coll.pos.x + this.getTileWidth() * 0.1f image.x = coll.pos.x + this.getTileWidth() * 0.1f
image.y = coll.pos.y + this.getTileHeight() * 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 { fun isCollidingWith(collidable: Collidable): Boolean {
for (wall in walls) { for (wall in mapState.walls) {
if (wall.collidesWidth(collidable)) { if (wall.collidesWidth(collidable)) {
return true return true
} }
} }
for (door in doors) { for (door in mapState.doors) {
if (door.collidesWidth(collidable)) { if (door.collidesWidth(collidable)) {
return true return true
} }
@ -234,9 +166,9 @@ class TimeMap(fileName: String, val state: GameState) {
fun getInteractablesAt(absoluteDirection: Vector2): List<Interactable> { fun getInteractablesAt(absoluteDirection: Vector2): List<Interactable> {
val interactables = ArrayList<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) interactables.addAll(c)
val w = doors.filter { it.getCollider().contains(absoluteDirection) } val w = mapState.doors.filter { it.getCollider().contains(absoluteDirection) }
interactables.addAll(w) interactables.addAll(w)
return interactables return interactables

Loading…
Cancel
Save