diff --git a/core/src/main/kotlin/com/last/commit/FirstScreen.kt b/core/src/main/kotlin/com/last/commit/FirstScreen.kt index 5273ea1..dd21cf8 100644 --- a/core/src/main/kotlin/com/last/commit/FirstScreen.kt +++ b/core/src/main/kotlin/com/last/commit/FirstScreen.kt @@ -24,12 +24,13 @@ import kotlin.math.floor /** First screen of the application. Displayed after the application is created. */ class FirstScreen(val game: Game) : Screen, InputProcessor { + val viewportSize = 800f private var delta = 0f private var isColliding = false val state = ColorState() val batch = SpriteBatch() - val camera = OrthographicCamera(800f, 600f) + val camera = OrthographicCamera(viewportSize, viewportSize) lateinit var map: TimeMap // = TimeMap("tiled/base.tmx") val playerTexture = Texture("sprites/characters.png") val player = Player(TextureRegion(playerTexture, 300, 44, 35, 43)) @@ -45,6 +46,7 @@ class FirstScreen(val game: Game) : Screen, InputProcessor { val gameConfig = this.loadGameConfig() val randomMap = gameConfig.getRandomMap() map = TimeMap(randomMap) + handleRatioChange() this.spawnPlayer() this.updateCamera() @@ -65,7 +67,7 @@ class FirstScreen(val game: Game) : Screen, InputProcessor { override fun render(delta: Float) { this.delta = delta -// state.step((delta * 1000).toLong()) + // state.step((delta * 1000).toLong()) // Draw your screen here. "delta" is the time since last render in seconds. Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) Gdx.gl.glClearColor(state.red, state.green, state.blue, 1f) @@ -75,10 +77,7 @@ class FirstScreen(val game: Game) : Screen, InputProcessor { val mousePosition: Vector2 = getMousePosition() player.lookAt(mousePosition) - val interactables = map.getInteractablesAt( - player.getAbsoluteDirection() - ) - + val interactables = map.getInteractablesAt(player.getAbsoluteDirection()) batch.projectionMatrix = camera.combined batch.begin() @@ -86,10 +85,9 @@ class FirstScreen(val game: Game) : Screen, InputProcessor { this.player.render(batch) batch.end() - //TODO: auslagern in sperate Methode + // TODO: auslagern in sperate Methode renderInteractables(interactables) - inventoryStage.draw() } @@ -101,10 +99,10 @@ class FirstScreen(val game: Game) : Screen, InputProcessor { shapeRenderer.begin(ShapeRenderer.ShapeType.Filled) for (interactable in interactables) { shapeRenderer.rect( - interactable.getCollider().x, - interactable.getCollider().y, - interactable.getCollider().width, - interactable.getCollider().height + interactable.getCollider().x, + interactable.getCollider().y, + interactable.getCollider().width, + interactable.getCollider().height ) } shapeRenderer.end() @@ -112,7 +110,8 @@ class FirstScreen(val game: Game) : Screen, InputProcessor { } private fun getMousePosition(): Vector2 { - val unprojectedMousePosition = camera.unproject(Vector3(Gdx.input.x.toFloat(), Gdx.input.y.toFloat(), 0f)) + val unprojectedMousePosition = + camera.unproject(Vector3(Gdx.input.x.toFloat(), Gdx.input.y.toFloat(), 0f)) return Vector2(unprojectedMousePosition.x, unprojectedMousePosition.y) } @@ -126,13 +125,7 @@ class FirstScreen(val game: Game) : Screen, InputProcessor { } private fun handleInput() { - val horizontalMovement = Vector2() - - - //if (Gdx.input.isKeyPressed(game.settings.actionKeys.get(ActionCommand.LEFT))) - - if (Gdx.input.isKeyPressed(Keys.A) || Gdx.input.isKeyPressed(Keys.LEFT)) { horizontalMovement.sub(Vector2.X) } @@ -183,21 +176,22 @@ class FirstScreen(val game: Game) : Screen, InputProcessor { val playerYPosition: Float = this.player.getY() val mapWidth: Int = map.width val mapHeight: Int = map.height + cX = if (playerXPosition < halfScreenWidth) { - halfScreenWidth - } else if (playerXPosition > mapWidth - halfScreenWidth) { - mapWidth - halfScreenWidth - } else { - playerXPosition - } + halfScreenWidth + } else if (playerXPosition > mapWidth - halfScreenWidth) { + mapWidth - halfScreenWidth + } else { + playerXPosition + } cY = if (playerYPosition < halfScreenHeight) { - halfScreenHeight - } else if (playerYPosition > mapHeight - halfScreenHeight) { - mapHeight - halfScreenHeight - } else { - playerYPosition - } + halfScreenHeight + } else if (playerYPosition > mapHeight - halfScreenHeight) { + mapHeight - halfScreenHeight + } else { + playerYPosition + } camera.position[cX, cY] = 0f camera.update() @@ -205,6 +199,24 @@ class FirstScreen(val game: Game) : Screen, InputProcessor { override fun resize(width: Int, height: Int) { // Resize your screen here. The parameters represent the new window size. + inventoryStage.resize(width, height) + handleRatioChange() + } + + fun handleRatioChange() { + val height = Gdx.graphics.height + val width = Gdx.graphics.width + + val wRatio = width.toFloat() / height.toFloat() + val hRatio = height.toFloat() / width.toFloat() + if (wRatio < 1) { + camera.viewportWidth = viewportSize * wRatio + camera.viewportHeight = viewportSize + } else { + camera.viewportHeight = viewportSize * hRatio + camera.viewportWidth = viewportSize + } + updateCamera() } override fun pause() { @@ -246,6 +258,9 @@ class FirstScreen(val game: Game) : Screen, InputProcessor { map.teleport(player) } else if (game.settings.isOpenInventoryPressed(keyCode)) { inventoryStage.visible = !inventoryStage.visible + } else if (character == 'p') { + player.inventory.add("compass") + inventoryStage.refresh() } return false } @@ -256,7 +271,7 @@ class FirstScreen(val game: Game) : Screen, InputProcessor { val playerDirection: Vector2 = player.getAbsoluteDirection() println("Player interactor is ${playerDirection.x}:${playerDirection.y}") - map.toggleDoorAt(playerDirection.x, playerDirection.y, player.getCollider()) + map.interactWith(playerDirection.x, playerDirection.y, player.getCollider()) // TODO Auto-generated method stub return false } @@ -265,34 +280,34 @@ class FirstScreen(val game: Game) : Screen, InputProcessor { println("Attempt to toggle door") val playerDirection: Vector2 = player.getAbsoluteDirection() println("Player interactor is ${playerDirection.x}:${playerDirection.y}") - map.toggleDoorAt(playerDirection.x, playerDirection.y, player.getCollider()) + map.interactWith(playerDirection.x, playerDirection.y, player.getCollider()) } fun toWorldCoordinates(x: Float, y: Float): Vector2 { val mouseInWorldPosition = camera.unproject(Vector3(x, y, 0f)) return Vector2( - floor(mouseInWorldPosition.x.toDouble() / this.map.getTileWidth()).toFloat(), - floor(mouseInWorldPosition.y.toDouble() / this.map.getTileHeight()).toFloat() + floor(mouseInWorldPosition.x.toDouble() / this.map.getTileWidth()).toFloat(), + floor(mouseInWorldPosition.y.toDouble() / this.map.getTileHeight()).toFloat() ) } override fun touchUp(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean { - //TODO: ("Not yet implemented") + // TODO: ("Not yet implemented") return false } override fun touchDragged(screenX: Int, screenY: Int, pointer: Int): Boolean { - //TODO: ("Not yet implemented") + // TODO: ("Not yet implemented") return false } override fun mouseMoved(screenX: Int, screenY: Int): Boolean { - //TODO: "Not yet implemented" + // TODO: "Not yet implemented" return false } override fun scrolled(amountX: Float, amountY: Float): Boolean { - //TODO: Not yet implemented + // TODO: Not yet implemented return false } -} \ No newline at end of file +} diff --git a/core/src/main/kotlin/com/last/commit/Player.kt b/core/src/main/kotlin/com/last/commit/Player.kt index f0fb432..bc63d8d 100644 --- a/core/src/main/kotlin/com/last/commit/Player.kt +++ b/core/src/main/kotlin/com/last/commit/Player.kt @@ -15,7 +15,7 @@ class Player(private val textureRegion: TextureRegion) : Collidable { private val movementSpeed = 200f private val interactionRange = 60f - val inventory = Inventory() + val inventory = Inventory("sprites/genericItems_spritesheet_colored") init { val size = Math.max(textureRegion.regionWidth, textureRegion.regionHeight).toFloat() diff --git a/core/src/main/kotlin/com/last/commit/Wall.kt b/core/src/main/kotlin/com/last/commit/Wall.kt index d05e0b9..c43699e 100644 --- a/core/src/main/kotlin/com/last/commit/Wall.kt +++ b/core/src/main/kotlin/com/last/commit/Wall.kt @@ -3,14 +3,7 @@ package com.last.commit import com.badlogic.gdx.maps.tiled.TiledMapTileLayer.Cell import com.badlogic.gdx.math.Rectangle -open class Wall(var gridX: Int, var gridY: Int, wallCollider: Rectangle, cell: Cell) : Collidable { - var wallCollider: Rectangle - var cell: Cell - - init { - this.wallCollider = wallCollider - this.cell = cell - } +open class Wall(var gridX: Int, var gridY: Int, var wallCollider: Rectangle, var cell: Cell) : Collidable { override fun getCollider(): Rectangle { return wallCollider diff --git a/core/src/main/kotlin/com/last/commit/inventory/Inventory.kt b/core/src/main/kotlin/com/last/commit/inventory/Inventory.kt index 4a99aac..61a8777 100644 --- a/core/src/main/kotlin/com/last/commit/inventory/Inventory.kt +++ b/core/src/main/kotlin/com/last/commit/inventory/Inventory.kt @@ -1,14 +1,17 @@ package com.last.commit.inventory -class Inventory { +class Inventory(path: String) { val items: MutableList = ArrayList() - val textureLoader = InventoryItemTextureLoader("sprites/genericItems_spritesheet_colored") + val textureLoader = InventoryItemTextureLoader(path) init { textureLoader.parse() } + /** + * @param name the name of the subtexture loaded from xml + */ fun add(name: String) { items.add(InventoryItem(name, textureLoader.loadTexture(name))) } diff --git a/core/src/main/kotlin/com/last/commit/inventory/InventoryItem.kt b/core/src/main/kotlin/com/last/commit/inventory/InventoryItem.kt index 2604cf1..b899efa 100644 --- a/core/src/main/kotlin/com/last/commit/inventory/InventoryItem.kt +++ b/core/src/main/kotlin/com/last/commit/inventory/InventoryItem.kt @@ -2,12 +2,6 @@ package com.last.commit.inventory import com.badlogic.gdx.graphics.g2d.TextureRegion -class InventoryItem(name: String, texture: TextureRegion) { - val texture: TextureRegion - val name: String +class InventoryItem(val name: String, val texture: TextureRegion) { - init { - this.name = name - this.texture = texture - } } \ No newline at end of file diff --git a/core/src/main/kotlin/com/last/commit/map/Collectible.kt b/core/src/main/kotlin/com/last/commit/map/Collectible.kt index 74a4ffc..7da3d86 100644 --- a/core/src/main/kotlin/com/last/commit/map/Collectible.kt +++ b/core/src/main/kotlin/com/last/commit/map/Collectible.kt @@ -1,22 +1,28 @@ package com.last.commit.map import com.badlogic.gdx.math.Rectangle +import Position -class Collectible(name: String, x: Float, y: Float, width: Float, height: Float) : Interactable { +class Collectible( + name: String, + val pos: Position, + width: Float, + height: Float +) : Interactable { val name: String private val collider: Rectangle init { this.name = name - this.collider = Rectangle(x, y, width, height) + this.collider = Rectangle(pos.x, pos.y, width, height) } - override fun interact() { - + override fun interact(otherCollider: Rectangle) { + println("Interacting with item $name") } 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 4f654ef..f71a101 100644 --- a/core/src/main/kotlin/com/last/commit/map/Door.kt +++ b/core/src/main/kotlin/com/last/commit/map/Door.kt @@ -7,9 +7,19 @@ import com.last.commit.Wall class Door(gridX: Int, gridY: Int, wallCollider: Rectangle, cell: Cell) : Wall(gridX, gridY, wallCollider, cell), Interactable { - override fun interact() { - println("Toggling door $this") - isOpen = !isOpen + override fun interact(otherCollider: Rectangle) { + println("interacting with door $this") + if (isClosed) { + isOpen = true + } else if (isOpen) { + if (getCollider().overlaps(otherCollider)) { + // can't close the door cause it is colliding with given collider + } else { + isOpen = false + } + } + + println("Door is now open = $isOpen") } var isOpen: Boolean diff --git a/core/src/main/kotlin/com/last/commit/map/Interactable.kt b/core/src/main/kotlin/com/last/commit/map/Interactable.kt index 597ac8b..a5ca6bf 100644 --- a/core/src/main/kotlin/com/last/commit/map/Interactable.kt +++ b/core/src/main/kotlin/com/last/commit/map/Interactable.kt @@ -5,5 +5,5 @@ import com.badlogic.gdx.math.Rectangle interface Interactable { fun getCollider(): Rectangle - fun interact() + fun interact(otherCollider: Rectangle) } \ No newline at end of file diff --git a/core/src/main/kotlin/com/last/commit/map/Position.kt b/core/src/main/kotlin/com/last/commit/map/Position.kt new file mode 100644 index 0000000..7dd5014 --- /dev/null +++ b/core/src/main/kotlin/com/last/commit/map/Position.kt @@ -0,0 +1,21 @@ +import com.badlogic.gdx.math.Vector2 + +public data class Position( + public val pos: Vector2, + public val gridPos: Vector2, +) { + + public val x: Float + get() = pos.x + + public val y: Float + get() = pos.y + + public val gridX: Int + get() = gridPos.x.toInt() + + public val gridY: Int + get() = gridPos.y.toInt() + + constructor(x: Float, y: Float, gridX: Int, gridY: Int): this(Vector2(x, y), Vector2(gridX.toFloat(), gridY.toFloat())) +} \ 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 fb80ce3..4383123 100644 --- a/core/src/main/kotlin/com/last/commit/map/TimeMap.kt +++ b/core/src/main/kotlin/com/last/commit/map/TimeMap.kt @@ -14,6 +14,7 @@ import com.badlogic.gdx.utils.Array import com.last.commit.Collidable import com.last.commit.Player import com.last.commit.Wall +import Position class TimeMap(fileName: String) { @@ -124,15 +125,19 @@ class TimeMap(fileName: String) { 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) - this.collectibles.add(Collectible(itemName, x, y, width, height)) + this.collectibles.add(Collectible(itemName, Position(x, y, gridX, gridY), width, height)) } else { println("Found non-rectangular map object at ${x}-${y} skipping it") } @@ -140,30 +145,30 @@ class TimeMap(fileName: String) { println("Loaded ${collectibles.size} collectibles") } - private fun findDoorByGridPosition(gridX: Int, gridY: Int): Door? { + private fun findInteractableAtPosition(gridX: Int, gridY: Int): Interactable? { for (door in doors) { if (door.gridX == gridX && door.gridY == gridY && door is Door) { return door } } + for (collectible in collectibles) { + if (collectible.pos.gridX == gridX && collectible.pos.gridY == gridY) { + return collectible + } + } return null } - fun toggleDoorAt(x: Float, y: Float, blockingCollider: Rectangle?) { + fun interactWith(x: Float, y: Float, blockingCollider: Rectangle) { val gridX = x.toInt() / CELL_SIZE val gridY = y.toInt() / CELL_SIZE - println("Toggling door at $gridX:$gridY") - val door: Door = this.findDoorByGridPosition(gridX, gridY) ?: return - if (door.isClosed) { - door.isOpen = true - } else if (door.isOpen) { - if (door.getCollider().overlaps(blockingCollider)) { - // can't close the door cause it is colliding with given collider - } else { - door.isOpen = false - } - } - println("Door is now open = ${door.isOpen}") + println("Interacting with element at $gridX:$gridY") + + //if no door is found return + val interactable: Interactable = this.findInteractableAtPosition(gridX, gridY) ?: return + //else continue + + interactable.interact(blockingCollider) } diff --git a/core/src/main/kotlin/com/last/commit/stages/InventoryStage.kt b/core/src/main/kotlin/com/last/commit/stages/InventoryStage.kt index 8924e35..d4d6143 100644 --- a/core/src/main/kotlin/com/last/commit/stages/InventoryStage.kt +++ b/core/src/main/kotlin/com/last/commit/stages/InventoryStage.kt @@ -4,14 +4,21 @@ import com.badlogic.gdx.scenes.scene2d.Stage import com.badlogic.gdx.scenes.scene2d.ui.Image import com.last.commit.inventory.Inventory -class InventoryStage(inventory: Inventory) : Stage() { +class InventoryStage(val inventory: Inventory) : Stage() { var visible = false + set(visible) { + field = visible + if (visible) { + refresh() + } + } - init { - for (item in inventory.items) { - - val image = Image(item.texture) + fun refresh() { + super.clear() + inventory.items.forEachIndexed { index, inventoryItem -> + val image = Image(inventoryItem.texture) + image.x = index * 32f image.width = 32f image.height = 32f