You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
gamejam-22/core/src/main/kotlin/com/last/commit/map/TimeMap.kt

186 lines
6.3 KiB
Kotlin

package com.last.commit.map
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.OrthographicCamera
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.maps.tiled.TiledMap
import com.badlogic.gdx.maps.tiled.TmxMapLoader
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer
import com.badlogic.gdx.math.Vector2
import com.badlogic.gdx.scenes.scene2d.ui.Image
import com.last.commit.Collidable
import com.last.commit.Player
import com.last.commit.audio.SoundEngine
import com.last.commit.inventory.SpritesheetTextureLoader
import com.last.commit.stages.DialogStage
class TimeMap(fileName: String, val dialogStage: DialogStage) {
private val CELL_SIZE = 64
val textureLoader = SpritesheetTextureLoader("sprites/genericItems_spritesheet_colored")
val mapLoader: TmxMapLoader = TmxMapLoader()
var mapRenderer: OrthogonalTiledMapRenderer
var mapState: MapState
val mapStates: HashMap<String, MapState> = HashMap()
var map: TiledMap
val gridWidth: Int
get() = mapState.gridSize.x.toInt()
val gridHeight: Int
get() = mapState.gridSize.y.toInt()
val width: Int
get() = mapState.size.x.toInt()
val height: Int
get() = mapState.size.y.toInt()
val mapTileWidth: Int
get() = mapState.tileSize.x.toInt()
val mapTileHeight: Int
get() = mapState.tileSize.y.toInt()
init {
map = mapLoader.load(fileName)
mapState = MapState(map, textureLoader)
mapStates[fileName] = mapState
mapRenderer = OrthogonalTiledMapRenderer(map)
}
fun teleport(player: Player) {
val teleporter = mapState.teleporters.find {
it.rectangle.contains(player.getX(), player.getY())
}
if (teleporter != null) {
SoundEngine.play("TIME_TRAVEL")
val targetMap = teleporter.properties.get("target", String::class.java)
System.out.println("Teleporting to targetMap $targetMap")
loadMap("tiled/$targetMap")
val mapDescription = mapState.description
dialogStage.setTexts(4000L, "You teleported to $mapDescription")
dialogStage.show()
}
}
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, textureLoader)
mapStates[name] = mapState
}
}
fun getPlayerSpawn(): Vector2 {
val mapLayers = map.layers
val spawnPoints = mapLayers["Spawnpoints"].objects
for (spawnPoint in spawnPoints) {
val spawnPointProperties = spawnPoint.properties
if (spawnPointProperties != null && spawnPointProperties.containsKey("playerSpawn")) {
val isPlayerSpawn = spawnPointProperties.get("playerSpawn", Boolean::class.java)
if (java.lang.Boolean.TRUE == isPlayerSpawn) {
val x = spawnPointProperties.get("x", Float::class.java)
val y = spawnPointProperties.get("y", Float::class.java)
return Vector2(x, y)
}
}
}
Gdx.app.debug("SurvislandMap", "No spawn point found in map. Return map origin.")
return Vector2.Zero
}
private fun findInteractableAtPosition(gridX: Int, gridY: Int): Interactable? {
for (door in mapState.doors) {
if (door.gridX == gridX && door.gridY == gridY) {
return door
}
}
for (collectible in mapState.collectibles) {
if (collectible.pos.gridX == gridX && collectible.pos.gridY == gridY) {
return collectible
}
}
return null
}
fun interactWith(x: Float, y: Float, player: Player) {
val gridX = x.toInt() / CELL_SIZE
val gridY = y.toInt() / CELL_SIZE
//if no door is found return
val interactable: Interactable = this.findInteractableAtPosition(gridX, gridY) ?: return
//else continue
if (player.canInteractWith(interactable)) {
println("Interacting with element at $gridX:$gridY")
val interacted = player.interactWith(interactable);
if (interacted && interactable is Collectible) {
mapState.collectibles.remove(interactable)
} else if (!interacted && interactable is Collectible) {
dialogStage.setTexts("You cannot use this at the moment.")
dialogStage.show()
}
} else {
dialogStage.setTexts("You cannot interact with this now.")
dialogStage.show()
println("Cannot interact with $gridX:$gridY")
}
}
fun getTileWidth(): Float {
return mapTileWidth.toFloat()
}
fun getTileHeight(): Float {
return mapTileHeight.toFloat()
}
fun render(batch: SpriteBatch, camera: OrthographicCamera, delta: Float) {
mapRenderer.setView(camera)
mapRenderer.render()
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
image.width = this.getTileWidth() * 0.8f
image.height = this.getTileHeight() * 0.8f
image.draw(batch, 1f)
}
}
fun isCollidingWith(collidable: Collidable): Boolean {
for (wall in mapState.walls) {
if (wall.collidesWidth(collidable)) {
return true
}
}
for (door in mapState.doors) {
if (door.collidesWidth(collidable)) {
return true
}
}
return false
}
fun getInteractablesAt(absoluteDirection: Vector2): List<Interactable> {
val interactables = ArrayList<Interactable>()
val c = mapState.collectibles.filter { it.getCollider().contains(absoluteDirection) }
interactables.addAll(c)
val w = mapState.doors.filter { it.getCollider().contains(absoluteDirection) }
interactables.addAll(w)
return interactables
}
}