diff --git a/assets/tiled/demo.tmx b/assets/tiled/demo.tmx index ffad6b5..4e1640b 100644 --- a/assets/tiled/demo.tmx +++ b/assets/tiled/demo.tmx @@ -1,5 +1,5 @@ - + @@ -254,6 +254,19 @@ + + + + + + + + + + + + + diff --git a/core/src/main/kotlin/com/last/commit/FirstScreen.kt b/core/src/main/kotlin/com/last/commit/FirstScreen.kt index 1931b4a..c7d0565 100644 --- a/core/src/main/kotlin/com/last/commit/FirstScreen.kt +++ b/core/src/main/kotlin/com/last/commit/FirstScreen.kt @@ -4,16 +4,19 @@ import com.badlogic.gdx.Gdx import com.badlogic.gdx.Input.Keys import com.badlogic.gdx.InputProcessor import com.badlogic.gdx.Screen +import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.GL20 import com.badlogic.gdx.graphics.OrthographicCamera import com.badlogic.gdx.graphics.Texture import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.g2d.TextureRegion +import com.badlogic.gdx.graphics.glutils.ShapeRenderer import com.badlogic.gdx.math.MathUtils import com.badlogic.gdx.math.Vector2 import com.badlogic.gdx.math.Vector3 import com.badlogic.gdx.utils.Json import com.last.commit.config.GameConfig +import com.last.commit.map.Interactable import com.last.commit.map.TimeMap import com.last.commit.stages.InventoryStage import kotlin.math.floor @@ -30,6 +33,9 @@ class FirstScreen : Screen, InputProcessor { lateinit var map: TimeMap // = TimeMap("tiled/base.tmx") val playerTexture = Texture("sprites/characters.png") val player = Player(TextureRegion(playerTexture, 300, 44, 35, 43)) + var shapeRenderer = ShapeRenderer() + + val highlightColor = Color(0f, 0f, 1f, 0.5f) lateinit var inventoryStage: InventoryStage @@ -45,6 +51,7 @@ class FirstScreen : Screen, InputProcessor { player.addItemToInventory("drill") inventoryStage = InventoryStage(player.inventory) + shapeRenderer.setAutoShapeType(true) Gdx.input.setInputProcessor(this) } @@ -68,6 +75,10 @@ class FirstScreen : Screen, InputProcessor { val mousePosition: Vector2 = getMousePosition() player.lookAt(mousePosition) + val interactables = map.getInteractablesAt( + player.getAbsoluteDirection() + ) + batch.projectionMatrix = camera.combined batch.begin() @@ -75,9 +86,31 @@ class FirstScreen : Screen, InputProcessor { this.player.render(batch) batch.end() + //TODO: auslagern in sperate Methode + renderInteractables(interactables) + + inventoryStage.draw() } + fun renderInteractables(interactables: List) { + Gdx.gl.glEnable(GL20.GL_BLEND) + Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA) + shapeRenderer.setProjectionMatrix(this.camera.combined) + shapeRenderer.setColor(highlightColor) + shapeRenderer.begin(ShapeRenderer.ShapeType.Filled) + for (interactable in interactables) { + shapeRenderer.rect( + interactable.getCollider().x, + interactable.getCollider().y, + interactable.getCollider().width, + interactable.getCollider().height + ) + } + shapeRenderer.end() + Gdx.gl.glDisable(GL20.GL_BLEND) + } + private fun getMousePosition(): Vector2 { val unprojectedMousePosition = camera.unproject(Vector3(Gdx.input.x.toFloat(), Gdx.input.y.toFloat(), 0f)) return Vector2(unprojectedMousePosition.x, unprojectedMousePosition.y) @@ -131,7 +164,7 @@ class FirstScreen : Screen, InputProcessor { } private fun checkCollision() { - this.isColliding = map.isCollidingWithWall(player) + this.isColliding = map.isCollidingWith(player) } fun updateCamera() { @@ -183,6 +216,7 @@ class FirstScreen : Screen, InputProcessor { override fun dispose() { // Destroy screen's assets here. batch.dispose() + shapeRenderer.dispose() } override fun keyDown(keycode: Int): Boolean { diff --git a/core/src/main/kotlin/com/last/commit/Player.kt b/core/src/main/kotlin/com/last/commit/Player.kt index 4d255c8..abc0402 100644 --- a/core/src/main/kotlin/com/last/commit/Player.kt +++ b/core/src/main/kotlin/com/last/commit/Player.kt @@ -91,7 +91,7 @@ class Player(private val textureRegion: TextureRegion) : Collidable { } /** - * Returns the direction of the player in World positon + * Returns the direction of the player in World positon considerung the interactionRange */ fun getAbsoluteDirection(): Vector2 { return position.cpy().add(getRelativeDirection()) diff --git a/core/src/main/kotlin/com/last/commit/map/Collectible.kt b/core/src/main/kotlin/com/last/commit/map/Collectible.kt new file mode 100644 index 0000000..74a4ffc --- /dev/null +++ b/core/src/main/kotlin/com/last/commit/map/Collectible.kt @@ -0,0 +1,22 @@ +package com.last.commit.map + +import com.badlogic.gdx.math.Rectangle + +class Collectible(name: String, x: Float, y: Float, width: Float, height: Float) : Interactable { + + val name: String + private val collider: Rectangle + + init { + this.name = name + this.collider = Rectangle(x, y, width, height) + } + + override fun interact() { + + } + + override fun getCollider(): Rectangle { + return this.collider + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/last/commit/map/Door.kt b/core/src/main/kotlin/com/last/commit/map/Door.kt index 7a8f3cb..4f654ef 100644 --- a/core/src/main/kotlin/com/last/commit/map/Door.kt +++ b/core/src/main/kotlin/com/last/commit/map/Door.kt @@ -6,9 +6,9 @@ import com.last.commit.Wall class Door(gridX: Int, gridY: Int, wallCollider: Rectangle, cell: Cell) : - Wall(gridX, gridY, wallCollider, cell), Toggleable { - override fun toggle() { - println("Toggling door$this") + Wall(gridX, gridY, wallCollider, cell), Interactable { + override fun interact() { + println("Toggling door $this") isOpen = !isOpen } diff --git a/core/src/main/kotlin/com/last/commit/map/Interactable.kt b/core/src/main/kotlin/com/last/commit/map/Interactable.kt new file mode 100644 index 0000000..597ac8b --- /dev/null +++ b/core/src/main/kotlin/com/last/commit/map/Interactable.kt @@ -0,0 +1,9 @@ +package com.last.commit.map + +import com.badlogic.gdx.math.Rectangle + +interface Interactable { + fun getCollider(): Rectangle + + fun interact() +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/last/commit/map/TimeMap.kt b/core/src/main/kotlin/com/last/commit/map/TimeMap.kt index a98004d..fb80ce3 100644 --- a/core/src/main/kotlin/com/last/commit/map/TimeMap.kt +++ b/core/src/main/kotlin/com/last/commit/map/TimeMap.kt @@ -19,8 +19,10 @@ import com.last.commit.Wall class TimeMap(fileName: String) { private val CELL_SIZE = 64 - private val walls: Array = Array() - val mapLoader:TmxMapLoader = TmxMapLoader() + private val walls = Array() + private val doors = Array() + private val collectibles = Array() + val mapLoader: TmxMapLoader = TmxMapLoader() var mapRenderer: OrthogonalTiledMapRenderer var map: TiledMap var gridWidth = 0 @@ -38,6 +40,7 @@ class TimeMap(fileName: String) { mapRenderer = OrthogonalTiledMapRenderer(map) loadDimensions() loadWalls() + loadCollectibles() } fun teleport(player: Player) { @@ -51,6 +54,7 @@ class TimeMap(fileName: String) { mapRenderer.map = map loadDimensions() loadWalls() + loadCollectibles() } } else { println("Found illegal teleporter. ${teleporter.properties.get("id")}") @@ -90,6 +94,7 @@ class TimeMap(fileName: String) { 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) { @@ -101,22 +106,44 @@ class TimeMap(fileName: String) { row.toFloat() * wallsLayer.tileHeight, wallsLayer.tileWidth.toFloat(), wallsLayer.tileHeight.toFloat() ) - val wall: Wall if (java.lang.Boolean.TRUE == isDoor) { - wall = Door(column, row, wallCollider, cell) + doors.add(Door(column, row, wallCollider, cell)) } else { - wall = Wall(column, row, wallCollider, cell) + walls.add(Wall(column, row, wallCollider, cell)) } - walls.add(wall) } } } } + 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 y = mapObjectProperties.get("y", Float::class.java) + 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) + this.collectibles.add(Collectible(itemName, x, y, width, height)) + } else { + println("Found non-rectangular map object at ${x}-${y} skipping it") + } + } + println("Loaded ${collectibles.size} collectibles") + } + private fun findDoorByGridPosition(gridX: Int, gridY: Int): Door? { - for (wall in walls) { - if (wall.gridX == gridX && wall.gridY == gridY && wall is Door) { - return wall + for (door in doors) { + if (door.gridX == gridX && door.gridY == gridY && door is Door) { + return door } } return null @@ -153,13 +180,29 @@ class TimeMap(fileName: String) { mapRenderer.render() } - fun isCollidingWithWall(collidable: Collidable): Boolean { + fun isCollidingWith(collidable: Collidable): Boolean { + for (wall in walls) { if (wall.collidesWidth(collidable)) { return true } } + for (door in doors) { + if (door.collidesWidth(collidable)) { + return true + } + } return false } + fun getInteractablesAt(absoluteDirection: Vector2): List { + val interactables = ArrayList() + val c = collectibles.filter { it.getCollider().contains(absoluteDirection) } + interactables.addAll(c) + val w = doors.filter { it.getCollider().contains(absoluteDirection) } + interactables.addAll(w) + + return interactables + } + } \ No newline at end of file diff --git a/core/src/main/kotlin/com/last/commit/map/Toggleable.kt b/core/src/main/kotlin/com/last/commit/map/Toggleable.kt deleted file mode 100644 index 46bc7c2..0000000 --- a/core/src/main/kotlin/com/last/commit/map/Toggleable.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.last.commit.map - -interface Toggleable { - fun toggle() -} \ No newline at end of file