Merge remote-tracking branch 'origin/main' into main

# Conflicts:
#	core/src/main/kotlin/com/last/commit/FirstScreen.kt
viewport-stuff
MehdiAyadi 2 years ago
commit bb42b79f59

@ -24,12 +24,13 @@ import kotlin.math.floor
/** First screen of the application. Displayed after the application is created. */ /** First screen of the application. Displayed after the application is created. */
class FirstScreen(val game: Game) : Screen, InputProcessor { class FirstScreen(val game: Game) : Screen, InputProcessor {
val viewportSize = 800f
private var delta = 0f private var delta = 0f
private var isColliding = false private var isColliding = false
val state = ColorState() val state = ColorState()
val batch = SpriteBatch() val batch = SpriteBatch()
val camera = OrthographicCamera(800f, 600f) val camera = OrthographicCamera(viewportSize, viewportSize)
lateinit var map: TimeMap // = TimeMap("tiled/base.tmx") lateinit var map: TimeMap // = TimeMap("tiled/base.tmx")
val playerTexture = Texture("sprites/characters.png") val playerTexture = Texture("sprites/characters.png")
val player = Player(TextureRegion(playerTexture, 300, 44, 35, 43)) 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 gameConfig = this.loadGameConfig()
val randomMap = gameConfig.getRandomMap() val randomMap = gameConfig.getRandomMap()
map = TimeMap(randomMap) map = TimeMap(randomMap)
handleRatioChange()
this.spawnPlayer() this.spawnPlayer()
this.updateCamera() this.updateCamera()
@ -65,7 +67,7 @@ class FirstScreen(val game: Game) : Screen, InputProcessor {
override fun render(delta: Float) { override fun render(delta: Float) {
this.delta = delta 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. // Draw your screen here. "delta" is the time since last render in seconds.
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
Gdx.gl.glClearColor(state.red, state.green, state.blue, 1f) 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() val mousePosition: Vector2 = getMousePosition()
player.lookAt(mousePosition) player.lookAt(mousePosition)
val interactables = map.getInteractablesAt( val interactables = map.getInteractablesAt(player.getAbsoluteDirection())
player.getAbsoluteDirection()
)
batch.projectionMatrix = camera.combined batch.projectionMatrix = camera.combined
batch.begin() batch.begin()
@ -86,10 +85,9 @@ class FirstScreen(val game: Game) : Screen, InputProcessor {
this.player.render(batch) this.player.render(batch)
batch.end() batch.end()
//TODO: auslagern in sperate Methode // TODO: auslagern in sperate Methode
renderInteractables(interactables) renderInteractables(interactables)
inventoryStage.draw() inventoryStage.draw()
} }
@ -101,10 +99,10 @@ class FirstScreen(val game: Game) : Screen, InputProcessor {
shapeRenderer.begin(ShapeRenderer.ShapeType.Filled) shapeRenderer.begin(ShapeRenderer.ShapeType.Filled)
for (interactable in interactables) { for (interactable in interactables) {
shapeRenderer.rect( shapeRenderer.rect(
interactable.getCollider().x, interactable.getCollider().x,
interactable.getCollider().y, interactable.getCollider().y,
interactable.getCollider().width, interactable.getCollider().width,
interactable.getCollider().height interactable.getCollider().height
) )
} }
shapeRenderer.end() shapeRenderer.end()
@ -112,7 +110,8 @@ class FirstScreen(val game: Game) : Screen, InputProcessor {
} }
private fun getMousePosition(): Vector2 { 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) return Vector2(unprojectedMousePosition.x, unprojectedMousePosition.y)
} }
@ -126,13 +125,7 @@ class FirstScreen(val game: Game) : Screen, InputProcessor {
} }
private fun handleInput() { private fun handleInput() {
val horizontalMovement = Vector2() val horizontalMovement = Vector2()
//if (Gdx.input.isKeyPressed(game.settings.actionKeys.get(ActionCommand.LEFT)))
if (Gdx.input.isKeyPressed(Keys.A) || Gdx.input.isKeyPressed(Keys.LEFT)) { if (Gdx.input.isKeyPressed(Keys.A) || Gdx.input.isKeyPressed(Keys.LEFT)) {
horizontalMovement.sub(Vector2.X) horizontalMovement.sub(Vector2.X)
} }
@ -183,21 +176,22 @@ class FirstScreen(val game: Game) : Screen, InputProcessor {
val playerYPosition: Float = this.player.getY() val playerYPosition: Float = this.player.getY()
val mapWidth: Int = map.width val mapWidth: Int = map.width
val mapHeight: Int = map.height val mapHeight: Int = map.height
cX = if (playerXPosition < halfScreenWidth) { cX = if (playerXPosition < halfScreenWidth) {
halfScreenWidth halfScreenWidth
} else if (playerXPosition > mapWidth - halfScreenWidth) { } else if (playerXPosition > mapWidth - halfScreenWidth) {
mapWidth - halfScreenWidth mapWidth - halfScreenWidth
} else { } else {
playerXPosition playerXPosition
} }
cY = if (playerYPosition < halfScreenHeight) { cY = if (playerYPosition < halfScreenHeight) {
halfScreenHeight halfScreenHeight
} else if (playerYPosition > mapHeight - halfScreenHeight) { } else if (playerYPosition > mapHeight - halfScreenHeight) {
mapHeight - halfScreenHeight mapHeight - halfScreenHeight
} else { } else {
playerYPosition playerYPosition
} }
camera.position[cX, cY] = 0f camera.position[cX, cY] = 0f
camera.update() camera.update()
@ -205,6 +199,24 @@ class FirstScreen(val game: Game) : Screen, InputProcessor {
override fun resize(width: Int, height: Int) { override fun resize(width: Int, height: Int) {
// Resize your screen here. The parameters represent the new window size. // 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() { override fun pause() {
@ -246,6 +258,9 @@ class FirstScreen(val game: Game) : Screen, InputProcessor {
map.teleport(player) map.teleport(player)
} else if (game.settings.isOpenInventoryPressed(keyCode)) { } else if (game.settings.isOpenInventoryPressed(keyCode)) {
inventoryStage.visible = !inventoryStage.visible inventoryStage.visible = !inventoryStage.visible
} else if (character == 'p') {
player.inventory.add("compass")
inventoryStage.refresh()
} }
return false return false
} }
@ -256,7 +271,7 @@ class FirstScreen(val game: Game) : Screen, InputProcessor {
val playerDirection: Vector2 = player.getAbsoluteDirection() val playerDirection: Vector2 = player.getAbsoluteDirection()
println("Player interactor is ${playerDirection.x}:${playerDirection.y}") 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 // TODO Auto-generated method stub
return false return false
} }
@ -265,34 +280,34 @@ class FirstScreen(val game: Game) : Screen, InputProcessor {
println("Attempt to toggle door") println("Attempt to toggle door")
val playerDirection: Vector2 = player.getAbsoluteDirection() val playerDirection: Vector2 = player.getAbsoluteDirection()
println("Player interactor is ${playerDirection.x}:${playerDirection.y}") 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 { fun toWorldCoordinates(x: Float, y: Float): Vector2 {
val mouseInWorldPosition = camera.unproject(Vector3(x, y, 0f)) val mouseInWorldPosition = camera.unproject(Vector3(x, y, 0f))
return Vector2( return Vector2(
floor(mouseInWorldPosition.x.toDouble() / this.map.getTileWidth()).toFloat(), floor(mouseInWorldPosition.x.toDouble() / this.map.getTileWidth()).toFloat(),
floor(mouseInWorldPosition.y.toDouble() / this.map.getTileHeight()).toFloat() floor(mouseInWorldPosition.y.toDouble() / this.map.getTileHeight()).toFloat()
) )
} }
override fun touchUp(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean { override fun touchUp(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
//TODO: ("Not yet implemented") // TODO: ("Not yet implemented")
return false return false
} }
override fun touchDragged(screenX: Int, screenY: Int, pointer: Int): Boolean { override fun touchDragged(screenX: Int, screenY: Int, pointer: Int): Boolean {
//TODO: ("Not yet implemented") // TODO: ("Not yet implemented")
return false return false
} }
override fun mouseMoved(screenX: Int, screenY: Int): Boolean { override fun mouseMoved(screenX: Int, screenY: Int): Boolean {
//TODO: "Not yet implemented" // TODO: "Not yet implemented"
return false return false
} }
override fun scrolled(amountX: Float, amountY: Float): Boolean { override fun scrolled(amountX: Float, amountY: Float): Boolean {
//TODO: Not yet implemented // TODO: Not yet implemented
return false return false
} }
} }

@ -15,7 +15,7 @@ class Player(private val textureRegion: TextureRegion) : Collidable {
private val movementSpeed = 200f private val movementSpeed = 200f
private val interactionRange = 60f private val interactionRange = 60f
val inventory = Inventory() val inventory = Inventory("sprites/genericItems_spritesheet_colored")
init { init {
val size = Math.max(textureRegion.regionWidth, textureRegion.regionHeight).toFloat() val size = Math.max(textureRegion.regionWidth, textureRegion.regionHeight).toFloat()

@ -3,14 +3,7 @@ package com.last.commit
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer.Cell import com.badlogic.gdx.maps.tiled.TiledMapTileLayer.Cell
import com.badlogic.gdx.math.Rectangle import com.badlogic.gdx.math.Rectangle
open class Wall(var gridX: Int, var gridY: Int, wallCollider: Rectangle, cell: Cell) : Collidable { open class Wall(var gridX: Int, var gridY: Int, var wallCollider: Rectangle, var cell: Cell) : Collidable {
var wallCollider: Rectangle
var cell: Cell
init {
this.wallCollider = wallCollider
this.cell = cell
}
override fun getCollider(): Rectangle { override fun getCollider(): Rectangle {
return wallCollider return wallCollider

@ -1,14 +1,17 @@
package com.last.commit.inventory package com.last.commit.inventory
class Inventory { class Inventory(path: String) {
val items: MutableList<InventoryItem> = ArrayList() val items: MutableList<InventoryItem> = ArrayList()
val textureLoader = InventoryItemTextureLoader("sprites/genericItems_spritesheet_colored") val textureLoader = InventoryItemTextureLoader(path)
init { init {
textureLoader.parse() textureLoader.parse()
} }
/**
* @param name the name of the subtexture loaded from xml
*/
fun add(name: String) { fun add(name: String) {
items.add(InventoryItem(name, textureLoader.loadTexture(name))) items.add(InventoryItem(name, textureLoader.loadTexture(name)))
} }

@ -2,12 +2,6 @@ package com.last.commit.inventory
import com.badlogic.gdx.graphics.g2d.TextureRegion import com.badlogic.gdx.graphics.g2d.TextureRegion
class InventoryItem(name: String, texture: TextureRegion) { class InventoryItem(val name: String, val texture: TextureRegion) {
val texture: TextureRegion
val name: String
init {
this.name = name
this.texture = texture
}
} }

@ -1,22 +1,28 @@
package com.last.commit.map package com.last.commit.map
import com.badlogic.gdx.math.Rectangle 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 val name: String
private val collider: Rectangle private val collider: Rectangle
init { init {
this.name = name 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 { override fun getCollider(): Rectangle {
return this.collider return this.collider
} }
} }

@ -7,9 +7,19 @@ import com.last.commit.Wall
class Door(gridX: Int, gridY: Int, wallCollider: Rectangle, cell: Cell) : class Door(gridX: Int, gridY: Int, wallCollider: Rectangle, cell: Cell) :
Wall(gridX, gridY, wallCollider, cell), Interactable { Wall(gridX, gridY, wallCollider, cell), Interactable {
override fun interact() { override fun interact(otherCollider: Rectangle) {
println("Toggling door $this") println("interacting with door $this")
isOpen = !isOpen 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 var isOpen: Boolean

@ -5,5 +5,5 @@ import com.badlogic.gdx.math.Rectangle
interface Interactable { interface Interactable {
fun getCollider(): Rectangle fun getCollider(): Rectangle
fun interact() fun interact(otherCollider: Rectangle)
} }

@ -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()))
}

@ -14,6 +14,7 @@ import com.badlogic.gdx.utils.Array
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 Position
class TimeMap(fileName: String) { class TimeMap(fileName: String) {
@ -124,15 +125,19 @@ class TimeMap(fileName: String) {
return return
} }
val collectibleMapObjects = collectiableLayer.objects val collectibleMapObjects = collectiableLayer.objects
for (mapObject in collectibleMapObjects) { for (mapObject in collectibleMapObjects) {
val mapObjectProperties = mapObject.properties val mapObjectProperties = mapObject.properties
val x = mapObjectProperties.get("x", Float::class.java) val x = mapObjectProperties.get("x", Float::class.java)
val gridX = Math.round(x / mapTileWidth)
val y = mapObjectProperties.get("y", Float::class.java) val y = mapObjectProperties.get("y", Float::class.java)
val gridY = Math.round(y / mapTileHeight)
val width = mapObjectProperties.get("width", Float::class.java) val width = mapObjectProperties.get("width", Float::class.java)
val height = mapObjectProperties.get("height", Float::class.java) val height = mapObjectProperties.get("height", Float::class.java)
if (mapObject is RectangleMapObject) { if (mapObject is RectangleMapObject) {
val itemName = mapObjectProperties.get("item", String::class.java) 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 { } else {
println("Found non-rectangular map object at ${x}-${y} skipping it") println("Found non-rectangular map object at ${x}-${y} skipping it")
} }
@ -140,30 +145,30 @@ class TimeMap(fileName: String) {
println("Loaded ${collectibles.size} collectibles") 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) { for (door in doors) {
if (door.gridX == gridX && door.gridY == gridY && door is Door) { if (door.gridX == gridX && door.gridY == gridY && door is Door) {
return door return door
} }
} }
for (collectible in collectibles) {
if (collectible.pos.gridX == gridX && collectible.pos.gridY == gridY) {
return collectible
}
}
return null 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 gridX = x.toInt() / CELL_SIZE
val gridY = y.toInt() / CELL_SIZE val gridY = y.toInt() / CELL_SIZE
println("Toggling door at $gridX:$gridY") println("Interacting with element at $gridX:$gridY")
val door: Door = this.findDoorByGridPosition(gridX, gridY) ?: return
if (door.isClosed) { //if no door is found return
door.isOpen = true val interactable: Interactable = this.findInteractableAtPosition(gridX, gridY) ?: return
} else if (door.isOpen) { //else continue
if (door.getCollider().overlaps(blockingCollider)) {
// can't close the door cause it is colliding with given collider interactable.interact(blockingCollider)
} else {
door.isOpen = false
}
}
println("Door is now open = ${door.isOpen}")
} }

@ -4,14 +4,21 @@ import com.badlogic.gdx.scenes.scene2d.Stage
import com.badlogic.gdx.scenes.scene2d.ui.Image import com.badlogic.gdx.scenes.scene2d.ui.Image
import com.last.commit.inventory.Inventory import com.last.commit.inventory.Inventory
class InventoryStage(inventory: Inventory) : Stage() { class InventoryStage(val inventory: Inventory) : Stage() {
var visible = false var visible = false
set(visible) {
field = visible
if (visible) {
refresh()
}
}
init { fun refresh() {
for (item in inventory.items) { super.clear()
inventory.items.forEachIndexed { index, inventoryItem ->
val image = Image(item.texture) val image = Image(inventoryItem.texture)
image.x = index * 32f
image.width = 32f image.width = 32f
image.height = 32f image.height = 32f

Loading…
Cancel
Save