From 2b31bb962aa5ce0727156c8f6237359d1d66194c Mon Sep 17 00:00:00 2001 From: Song Minjae Date: Sun, 23 Oct 2016 00:48:05 +0900 Subject: [PATCH] implementation of feature ROUNDWORLD Former-commit-id: b869816eceefc4d728919cd2028ea98cf4d0f505 Former-commit-id: 8dc1d95e49aef406899c8086f053ebb13d416884 --- src/net/torvald/terrarum/Terrarum.kt | 7 -- .../terrarum/gameactors/ActorWithBody.kt | 18 ++++- .../torvald/terrarum/gameworld/GameWorld.kt | 35 +++++---- .../torvald/terrarum/mapdrawer/MapCamera.kt | 76 +++++++++---------- .../torvald/terrarum/tilestats/TileStats.kt | 8 +- 5 files changed, 69 insertions(+), 75 deletions(-) diff --git a/src/net/torvald/terrarum/Terrarum.kt b/src/net/torvald/terrarum/Terrarum.kt index b13400c8c..1dc585744 100644 --- a/src/net/torvald/terrarum/Terrarum.kt +++ b/src/net/torvald/terrarum/Terrarum.kt @@ -85,11 +85,6 @@ constructor(gamename: String) : StateBasedGame(gamename) { fontGame = GameFontWhite() fontSmallNumbers = TinyAlphNum() - fontControlGuide = SpriteSheetFont(SpriteSheet( - "./assets/graphics/fonts/" + - if (environment == RunningEnvironment.CONSOLE) "keycaps_gamepad.png" - else "keycaps.png", 18, 18) - , ' ') hasController = gc.input.controllerCount > 0 if (hasController) { @@ -176,8 +171,6 @@ constructor(gamename: String) : StateBasedGame(gamename) { private set lateinit var fontSmallNumbers: Font private set - lateinit var fontControlGuide: Font - private set var joypadLabelStart: Char = 0x00.toChar() // lateinit var joypadLableSelect:Char = 0x00.toChar() // lateinit diff --git a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt index fa167c994..44d256546 100644 --- a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt +++ b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt @@ -39,8 +39,8 @@ open class ActorWithBody : Actor(), Visible { * * Unit: pixel * !! external class should not hitbox.set(); use setHitboxDimension() and setPosition() */ - override val hitbox = Hitbox(0.0, 0.0, 0.0, 0.0) - @Transient val nextHitbox = Hitbox(0.0, 0.0, 0.0, 0.0) + override val hitbox = Hitbox(0.0, 0.0, 0.0, 0.0) // Hitbox is implemented using Double; + @Transient val nextHitbox = Hitbox(0.0, 0.0, 0.0, 0.0) // 52 mantissas ought to be enough for anybody... /** * Velocity vector for newtonian sim. @@ -346,7 +346,7 @@ open class ActorWithBody : Actor(), Visible { // apply our compensation to actual hitbox updateHitbox() - // make sure the actor does not go out of the map + // make sure if the actor tries to go out of the map, loop back instead clampHitbox() } @@ -862,8 +862,18 @@ open class ActorWithBody : Actor(), Visible { } private fun clampHitbox() { + val worldsizePxl = world.width.times(TSIZE) + hitbox.setPositionFromPoint( - clampW(hitbox.pointedX), clampH(hitbox.pointedY)) + //clampW(hitbox.pointedX), + if (hitbox.pointedX < 0) + hitbox.pointedX + worldsizePxl + else if (hitbox.pointedX >= worldsizePxl) + hitbox.pointedX - worldsizePxl + else + hitbox.pointedX, // ROUNDWORLD impl + clampH(hitbox.pointedY) + ) } private fun setNewNextHitbox() { diff --git a/src/net/torvald/terrarum/gameworld/GameWorld.kt b/src/net/torvald/terrarum/gameworld/GameWorld.kt index a8e6abcca..866a039db 100644 --- a/src/net/torvald/terrarum/gameworld/GameWorld.kt +++ b/src/net/torvald/terrarum/gameworld/GameWorld.kt @@ -1,9 +1,6 @@ package net.torvald.terrarum.gameworld -import net.torvald.terrarum.gameactors.Player -import net.torvald.terrarum.gameactors.roundInt -import net.torvald.terrarum.mapdrawer.MapDrawer import org.dyn4j.geometry.Vector2 import org.newdawn.slick.SlickException @@ -89,8 +86,8 @@ constructor(//properties get() = terrainDamage.dataPair fun getTileFromWall(x: Int, y: Int): Int? { - val wall: Int? = layerWall.getTile(x, y) - val wallDamage: Int? = getWallDamage(x, y) + val wall: Int? = layerWall.getTile(x fmod width, y) + val wallDamage: Int? = getWallDamage(x fmod width, y) return if (wall == null || wallDamage == null) null else @@ -98,8 +95,8 @@ constructor(//properties } fun getTileFromTerrain(x: Int, y: Int): Int? { - val terrain: Int? = layerTerrain.getTile(x, y) - val terrainDamage: Int? = getTerrainDamage(x, y) + val terrain: Int? = layerTerrain.getTile(x fmod width, y) + val terrainDamage: Int? = getTerrainDamage(x fmod width, y) return if (terrain == null || terrainDamage == null) null else @@ -107,15 +104,15 @@ constructor(//properties } fun getTileFromWire(x: Int, y: Int): Int? { - return layerWire.getTile(x, y) + return layerWire.getTile(x fmod width, y) } fun getWallDamage(x: Int, y: Int): Int? { - return wallDamage.getData(x, y) + return wallDamage.getData(x fmod width, y) } fun getTerrainDamage(x: Int, y: Int): Int? { - return terrainDamage.getData(x, y) + return terrainDamage.getData(x fmod width, y) } /** @@ -127,7 +124,7 @@ constructor(//properties * @param combinedTilenum (tilenum * 16) + damage */ fun setTileWall(x: Int, y: Int, combinedTilenum: Int) { - setTileWall(x, y, (combinedTilenum / PairedMapLayer.RANGE).toByte(), combinedTilenum % PairedMapLayer.RANGE) + setTileWall(x fmod width, y, (combinedTilenum / PairedMapLayer.RANGE).toByte(), combinedTilenum % PairedMapLayer.RANGE) } /** @@ -139,21 +136,21 @@ constructor(//properties * @param combinedTilenum (tilenum * 16) + damage */ fun setTileTerrain(x: Int, y: Int, combinedTilenum: Int) { - setTileTerrain(x, y, (combinedTilenum / PairedMapLayer.RANGE).toByte(), combinedTilenum % PairedMapLayer.RANGE) + setTileTerrain(x fmod width, y, (combinedTilenum / PairedMapLayer.RANGE).toByte(), combinedTilenum % PairedMapLayer.RANGE) } fun setTileWall(x: Int, y: Int, tile: Byte, damage: Int) { - layerWall.setTile(x, y, tile) - wallDamage.setData(x, y, damage) + layerWall.setTile(x fmod width, y, tile) + wallDamage.setData(x fmod width, y, damage) } fun setTileTerrain(x: Int, y: Int, tile: Byte, damage: Int) { - layerTerrain.setTile(x, y, tile) - terrainDamage.setData(x, y, damage) + layerTerrain.setTile(x fmod width, y, tile) + terrainDamage.setData(x fmod width, y, damage) } fun setTileWire(x: Int, y: Int, tile: Byte) { - layerWire.data[y][x] = tile + layerWire.data[y][x fmod width] = tile } fun getTileFrom(mode: Int, x: Int, y: Int): Int? { @@ -225,4 +222,6 @@ constructor(//properties @Transient val SIZEOF: Byte = MapLayer.SIZEOF @Transient val LAYERS: Byte = 4 // terrain, wall (terrainDamage + wallDamage), wire } -} \ No newline at end of file +} + +infix fun Int.fmod(other: Int) = Math.floorMod(this, other) diff --git a/src/net/torvald/terrarum/mapdrawer/MapCamera.kt b/src/net/torvald/terrarum/mapdrawer/MapCamera.kt index ff2796077..b588bcdf9 100644 --- a/src/net/torvald/terrarum/mapdrawer/MapCamera.kt +++ b/src/net/torvald/terrarum/mapdrawer/MapCamera.kt @@ -20,7 +20,7 @@ import java.util.* * Created by minjaesong on 16-01-19. */ object MapCamera { - val WORLD: GameWorld = Terrarum.ingame.world; + val WORLD: GameWorld = Terrarum.ingame.world var cameraX = 0 private set @@ -237,10 +237,16 @@ object MapCamera { renderHeight = FastMath.ceil(Terrarum.HEIGHT / Terrarum.ingame.screenZoom) // position - (WH / 2) - cameraX = Math.round(FastMath.clamp( + /*cameraX = Math.round(FastMath.clamp( player.hitbox.centeredX.toFloat() - renderWidth / 2, TSIZE.toFloat(), WORLD.width * TSIZE - renderWidth - TSIZE.toFloat())) cameraY = Math.round(FastMath.clamp( player.hitbox.centeredY.toFloat() - renderHeight / 2, TSIZE.toFloat(), WORLD.height * TSIZE - renderHeight - TSIZE.toFloat())) +*/ + cameraX = Math.round( // X only: ROUNDWORLD implementation + player.hitbox.centeredX.toFloat() - renderWidth / 2) + cameraY = Math.round(FastMath.clamp( + player.hitbox.centeredY.toFloat() - renderHeight / 2, TSIZE.toFloat(), WORLD.height * TSIZE - renderHeight - TSIZE.toFloat())) + } fun renderBehind(gc: GameContainer, g: Graphics) { @@ -259,11 +265,11 @@ object MapCamera { } private fun drawTiles(mode: Int, drawModeTilesBlendMul: Boolean) { - val for_y_start = MapCamera.div16(MapCamera.cameraY) - val for_y_end = MapCamera.clampHTile(for_y_start + MapCamera.div16(MapCamera.renderHeight) + 2) + val for_y_start = MapCamera.cameraY / TSIZE + val for_y_end = MapCamera.clampHTile(for_y_start + (MapCamera.renderHeight / TSIZE) + 2) - val for_x_start = MapCamera.div16(MapCamera.cameraX) - val for_x_end = MapCamera.clampWTile(for_x_start + MapCamera.div16(MapCamera.renderWidth) + 2) + val for_x_start = MapCamera.cameraX / TSIZE - 1 + val for_x_end = for_x_start + (MapCamera.renderWidth / TSIZE) + 2 // initialise MapCamera.tilesetBook[mode].startUse() @@ -273,22 +279,22 @@ object MapCamera { for (x in for_x_start..for_x_end - 1) { val thisTile: Int? - if (mode % 3 == MapCamera.WALL) - thisTile = MapCamera.WORLD.getTileFromWall(x, y) - else if (mode % 3 == MapCamera.TERRAIN) - thisTile = MapCamera.WORLD.getTileFromTerrain(x, y) - else if (mode % 3 == MapCamera.WIRE) - thisTile = MapCamera.WORLD.getTileFromWire(x, y) + if (mode % 3 == WALL) + thisTile = WORLD.getTileFromWall(x, y) + else if (mode % 3 == TERRAIN) + thisTile = WORLD.getTileFromTerrain(x, y) + else if (mode % 3 == WIRE) + thisTile = WORLD.getTileFromWire(x, y) else throw IllegalArgumentException() - val noDamageLayer = mode % 3 == MapCamera.WIRE + val noDamageLayer = mode % 3 == WIRE // draw try { if ( - (mode == MapCamera.WALL || mode == MapCamera.TERRAIN) // not an air tile + (mode == WALL || mode == TERRAIN) // not an air tile && (thisTile ?: 0) > 0 && @@ -354,10 +360,10 @@ object MapCamera { */ fun getNearbyTilesInfo(x: Int, y: Int, mode: Int, mark: Int?): Int { val nearbyTiles = IntArray(4) - nearbyTiles[NEARBY_TILE_KEY_LEFT] = WORLD.getTileFrom(mode, x - 1, y) ?: 4096 + nearbyTiles[NEARBY_TILE_KEY_LEFT] = WORLD.getTileFrom(mode, x - 1, y) ?: 4096 nearbyTiles[NEARBY_TILE_KEY_RIGHT] = WORLD.getTileFrom(mode, x + 1, y) ?: 4096 - nearbyTiles[NEARBY_TILE_KEY_UP] = WORLD.getTileFrom(mode, x, y - 1) ?: 4906 - nearbyTiles[NEARBY_TILE_KEY_DOWN] = WORLD.getTileFrom(mode, x, y + 1) ?: 4096 + nearbyTiles[NEARBY_TILE_KEY_UP] = WORLD.getTileFrom(mode, x , y - 1) ?: 4906 + nearbyTiles[NEARBY_TILE_KEY_DOWN] = WORLD.getTileFrom(mode, x , y + 1) ?: 4096 // try for var ret = 0 @@ -372,10 +378,10 @@ object MapCamera { fun getNearbyTilesInfoNonSolid(x: Int, y: Int, mode: Int): Int { val nearbyTiles = IntArray(4) - nearbyTiles[NEARBY_TILE_KEY_LEFT] = WORLD.getTileFrom(mode, x - 1, y) ?: 4096 + nearbyTiles[NEARBY_TILE_KEY_LEFT] = WORLD.getTileFrom(mode, x - 1, y) ?: 4096 nearbyTiles[NEARBY_TILE_KEY_RIGHT] = WORLD.getTileFrom(mode, x + 1, y) ?: 4096 - nearbyTiles[NEARBY_TILE_KEY_UP] = WORLD.getTileFrom(mode, x, y - 1) ?: 4096 - nearbyTiles[NEARBY_TILE_KEY_DOWN] = WORLD.getTileFrom(mode, x, y + 1) ?: 4096 + nearbyTiles[NEARBY_TILE_KEY_UP] = WORLD.getTileFrom(mode, x , y - 1) ?: 4906 + nearbyTiles[NEARBY_TILE_KEY_DOWN] = WORLD.getTileFrom(mode, x , y + 1) ?: 4096 // try for var ret = 0 @@ -396,10 +402,10 @@ object MapCamera { fun getNearbyTilesInfoWallSticker(x: Int, y: Int): Int { val nearbyTiles = IntArray(4) val NEARBY_TILE_KEY_BACK = NEARBY_TILE_KEY_UP - nearbyTiles[NEARBY_TILE_KEY_LEFT] = WORLD.getTileFrom(TERRAIN, x - 1, y) ?: 4096 + nearbyTiles[NEARBY_TILE_KEY_LEFT] = WORLD.getTileFrom(TERRAIN, x - 1, y) ?: 4096 nearbyTiles[NEARBY_TILE_KEY_RIGHT] = WORLD.getTileFrom(TERRAIN, x + 1, y) ?: 4096 - nearbyTiles[NEARBY_TILE_KEY_DOWN] = WORLD.getTileFrom(TERRAIN, x, y + 1) ?: 4096 - nearbyTiles[NEARBY_TILE_KEY_BACK] = WORLD.getTileFrom(WALL, x, y) ?: 4096 + nearbyTiles[NEARBY_TILE_KEY_DOWN] = WORLD.getTileFrom(TERRAIN, x , y + 1) ?: 4096 + nearbyTiles[NEARBY_TILE_KEY_BACK] = WORLD.getTileFrom(WALL, x , y) ?: 4096 try { if (TilePropCodex.getProp(nearbyTiles[NEARBY_TILE_KEY_DOWN]).isSolid) @@ -438,20 +444,6 @@ object MapCamera { } } - fun div16(x: Int): Int = x and 0x7FFFFFFF shr 4 - fun mod16(x: Int): Int = x and 15 - fun quantise16(x: Int): Int = x and 0xFFFFFFF0.toInt() - - fun clampW(x: Int): Int { - if (x < 0) { - return 0 - } else if (x > WORLD.width * TSIZE) { - return WORLD.width * TSIZE - } else { - return x - } - } - fun clampH(x: Int): Int { if (x < 0) { return 0 @@ -482,11 +474,11 @@ object MapCamera { } } - fun getRenderStartX(): Int = div16(cameraX) - fun getRenderStartY(): Int = div16(cameraY) + fun getRenderStartX(): Int = cameraX / TSIZE + fun getRenderStartY(): Int = cameraY / TSIZE - fun getRenderEndX(): Int = clampWTile(getRenderStartX() + div16(renderWidth) + 2) - fun getRenderEndY(): Int = clampHTile(getRenderStartY() + div16(renderHeight) + 2) + fun getRenderEndX(): Int = clampWTile(getRenderStartX() +(renderWidth / TSIZE) + 2) + fun getRenderEndY(): Int = clampHTile(getRenderStartY() +(renderHeight / TSIZE) + 2) fun isConnectSelf(b: Int?): Boolean = TILES_CONNECT_SELF.contains(b) fun isConnectMutual(b: Int?): Boolean = TILES_CONNECT_MUTUAL.contains(b) @@ -497,4 +489,4 @@ object MapCamera { fun tileInCamera(x: Int, y: Int) = x >= cameraX.div(TSIZE) && y >= cameraY.div(TSIZE) && x <= cameraX.plus(renderWidth).div(TSIZE) && y <= cameraY.plus(renderWidth).div(TSIZE) -} \ No newline at end of file +} diff --git a/src/net/torvald/terrarum/tilestats/TileStats.kt b/src/net/torvald/terrarum/tilestats/TileStats.kt index 30e2afbd4..eb8d3599c 100644 --- a/src/net/torvald/terrarum/tilestats/TileStats.kt +++ b/src/net/torvald/terrarum/tilestats/TileStats.kt @@ -38,10 +38,10 @@ object TileStats { val noZoomCameraY = Math.round(FastMath.clamp( player.hitbox.centeredY.toFloat() - renderHeight / 2, TSIZE.toFloat(), map.width * TSIZE - renderHeight - TSIZE.toFloat())) - val for_x_start = MapCamera.div16(noZoomCameraX) - val for_y_start = MapCamera.div16(noZoomCameraY) - val for_y_end = MapCamera.clampHTile(for_y_start + MapCamera.div16(renderHeight) + 2) - val for_x_end = MapCamera.clampWTile(for_x_start + MapCamera.div16(renderWidth) + 2) + val for_x_start = noZoomCameraX / TSIZE + val for_y_start = noZoomCameraY / TSIZE + val for_y_end = MapCamera.clampHTile(for_y_start + (renderHeight / TSIZE) + 2) + val for_x_end = MapCamera.clampWTile(for_x_start + (renderWidth / TSIZE) + 2) for (y in for_y_start..for_y_end - 1) { for (x in for_x_start..for_x_end - 1) {