From a1ac9b177a024697fbec5de038c3e1d353955ef7 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Fri, 31 May 2019 04:10:00 +0900 Subject: [PATCH] fixing "roundworld anomaly": some actors won't render --- .../terrarum/gameactors/ActorWBMovable.kt | 47 ++++++++--------- .../torvald/terrarum/modulebasegame/Ingame.kt | 50 ++++++++++++------- .../modulebasegame/gameactors/FixtureBase.kt | 10 +++- .../terrarum/worlddrawer/WorldCamera.kt | 6 +++ 4 files changed, 69 insertions(+), 44 deletions(-) diff --git a/src/net/torvald/terrarum/gameactors/ActorWBMovable.kt b/src/net/torvald/terrarum/gameactors/ActorWBMovable.kt index 19d00d84f..a043a74b4 100644 --- a/src/net/torvald/terrarum/gameactors/ActorWBMovable.kt +++ b/src/net/torvald/terrarum/gameactors/ActorWBMovable.kt @@ -1389,31 +1389,28 @@ open class ActorWBMovable(renderOrder: RenderOrder, val immobileBody: Boolean = // FIXME test me: this extra IF statement is supposed to not draw actors that's outside of the camera. // basic code without offsetX/Y DOES work, but obviously offsets are not tested. - if (hitbox.startX - offsetX in WorldCamera.x - hitbox.width - offsetX..WorldCamera.x + WorldCamera.width + offsetX && - hitbox.endY + offsetY in WorldCamera.y - hitbox.height - offsetY..WorldCamera.y + WorldCamera.height + offsetY) { - if (WorldCamera.xCentre > leftsidePadding && centrePosPoint.x <= rightsidePadding) { - // camera center neg, actor center pos - sprite.render(batch, - (hitbox.startX - offsetX).toFloat() + world!!.width * TILE_SIZE, - (hitbox.startY - offsetY).toFloat(), - (scale).toFloat() - ) - } - else if (WorldCamera.xCentre < rightsidePadding && centrePosPoint.x >= leftsidePadding) { - // camera center pos, actor center neg - sprite.render(batch, - (hitbox.startX - offsetX).toFloat() - world!!.width * TILE_SIZE, - (hitbox.startY - offsetY).toFloat(), - (scale).toFloat() - ) - } - else { - sprite.render(batch, - (hitbox.startX - offsetX).toFloat(), - (hitbox.startY - offsetY).toFloat(), - (scale).toFloat() - ) - } + if (WorldCamera.xCentre > leftsidePadding && centrePosPoint.x <= rightsidePadding) { + // camera center neg, actor center pos + sprite.render(batch, + (hitbox.startX - offsetX).toFloat() + world!!.width * TILE_SIZE, + (hitbox.startY - offsetY).toFloat(), + (scale).toFloat() + ) + } + else if (WorldCamera.xCentre < rightsidePadding && centrePosPoint.x >= leftsidePadding) { + // camera center pos, actor center neg + sprite.render(batch, + (hitbox.startX - offsetX).toFloat() - world!!.width * TILE_SIZE, + (hitbox.startY - offsetY).toFloat(), + (scale).toFloat() + ) + } + else { + sprite.render(batch, + (hitbox.startX - offsetX).toFloat(), + (hitbox.startY - offsetY).toFloat(), + (scale).toFloat() + ) } } diff --git a/src/net/torvald/terrarum/modulebasegame/Ingame.kt b/src/net/torvald/terrarum/modulebasegame/Ingame.kt index 637518f07..0a2377975 100644 --- a/src/net/torvald/terrarum/modulebasegame/Ingame.kt +++ b/src/net/torvald/terrarum/modulebasegame/Ingame.kt @@ -30,6 +30,7 @@ import net.torvald.terrarum.modulebasegame.worldgenerator.WorldGenerator import net.torvald.terrarum.ui.ConsoleWindow import net.torvald.terrarum.ui.UICanvas import net.torvald.terrarum.worlddrawer.CreateTileAtlas +import net.torvald.terrarum.worlddrawer.CreateTileAtlas.TILE_SIZE import net.torvald.terrarum.worlddrawer.FeaturesDrawer import net.torvald.terrarum.worlddrawer.LightmapRenderer import net.torvald.terrarum.worlddrawer.WorldCamera @@ -475,8 +476,12 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) { } + private var worldWidth: Double = 0.0 + + protected fun updateGame(delta: Float) { val world = this.world as GameWorldExtension + worldWidth = world.width.toDouble() * TILE_SIZE particlesActive = 0 @@ -570,6 +575,8 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) { visibleActorsRenderMidTop = actorsRenderMidTop.filter { it.inScreen() } visibleActorsRenderFront = actorsRenderFront.filter { it.inScreen() } visibleActorsRenderOverlay=actorsRenderOverlay.filter { it.inScreen() } + + //printdbg(this, "total visible actors: ${visibleActorsRenderMiddle.size}") } private fun repossessActor() { @@ -716,31 +723,40 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) { private fun distToActorSqr(a: ActorWithBody, p: ActorWithBody) = min(// take min of normal position and wrapped (x < 0) position (a.hitbox.centeredX - p.hitbox.centeredX).sqr() + - (a.hitbox.centeredY - p.hitbox.centeredY).sqr(), - (a.hitbox.centeredX - p.hitbox.centeredX + world.width * CreateTileAtlas.TILE_SIZE).sqr() + - (a.hitbox.centeredY - p.hitbox.centeredY).sqr(), - (a.hitbox.centeredX - p.hitbox.centeredX - world.width * CreateTileAtlas.TILE_SIZE).sqr() + - (a.hitbox.centeredY - p.hitbox.centeredY).sqr() + (a.hitbox.centeredY - p.hitbox.centeredY).sqr(), + ((a.hitbox.centeredX + world.width * CreateTileAtlas.TILE_SIZE) - p.hitbox.centeredX).sqr() + + (a.hitbox.centeredY - p.hitbox.centeredY).sqr(), + ((a.hitbox.centeredX - world.width * CreateTileAtlas.TILE_SIZE) - p.hitbox.centeredX).sqr() + + (a.hitbox.centeredY - p.hitbox.centeredY).sqr() ) private fun distToCameraSqr(a: ActorWithBody) = min( - (a.hitbox.startX - WorldCamera.x).sqr() + - (a.hitbox.startY - WorldCamera.y).sqr(), - (a.hitbox.startX - WorldCamera.x + world.width * CreateTileAtlas.TILE_SIZE).sqr() + - (a.hitbox.startY - WorldCamera.y).sqr(), - (a.hitbox.startX - WorldCamera.x - world.width * CreateTileAtlas.TILE_SIZE).sqr() + - (a.hitbox.startY - WorldCamera.y).sqr() + (a.hitbox.centeredX - WorldCamera.xCentre).sqr() + + (a.hitbox.centeredY - WorldCamera.yCentre).sqr(), + ((a.hitbox.centeredX + world.width * CreateTileAtlas.TILE_SIZE) - WorldCamera.xCentre).sqr() + + (a.hitbox.centeredY - WorldCamera.yCentre).sqr(), + ((a.hitbox.centeredX - world.width * CreateTileAtlas.TILE_SIZE) - WorldCamera.xCentre).sqr() + + (a.hitbox.centeredY - WorldCamera.yCentre).sqr() ) /** whether the actor is within screen */ - // FIXME "roundworld anomaly" private fun ActorWithBody.inScreen() = - distToCameraSqr(this) <= - (Terrarum.WIDTH.plus(this.hitbox.width.div(2)). - times(1 / screenZoom).sqr() + - Terrarum.HEIGHT.plus(this.hitbox.height.div(2)). - times(1 / screenZoom).sqr()) + // y + this.hitbox.endY >= WorldCamera.y && this.hitbox.startY <= WorldCamera.yEnd + + && + + // x: camera is on the right side of the seam + ((this.hitbox.endX - worldWidth >= WorldCamera.x && this.hitbox.startX - worldWidth <= WorldCamera.xEnd) || + // x: camera in on the left side of the seam + (this.hitbox.endX + worldWidth >= WorldCamera.x && this.hitbox.startX + worldWidth <= WorldCamera.xEnd) || + // x: neither + (this.hitbox.endX >= WorldCamera.x && this.hitbox.startX <= WorldCamera.xEnd)) + + + private val cameraWindowX = WorldCamera.x.toDouble()..WorldCamera.xEnd.toDouble() + private val cameraWindowY = WorldCamera.y.toDouble()..WorldCamera.yEnd.toDouble() /** whether the actor is within update range */ private fun ActorWithBody.inUpdateRange() = distToCameraSqr(this) <= ACTOR_UPDATE_RANGE.sqr() diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureBase.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureBase.kt index b868e9a6d..2c64d8cf8 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureBase.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureBase.kt @@ -49,7 +49,14 @@ open class FixtureBase(blockBox0: BlockBox, val blockBoxProps: BlockBoxProps = B for (x in posX until posX + blockBox.width) { for (y in posY until posY + blockBox.height) { - world.setTileTerrain(x, y, blockBox.collisionType) + if (blockBox.collisionType == BlockBox.ALLOW_MOVE_DOWN) { + // if the collision type is allow_move_down, only the top surface tile should be "the platform" + // lower part must not have such property (think of the table!) + // TODO does this ACTUALLY work ?! + world.setTileTerrain(x, y, if (y == posY) BlockBox.ALLOW_MOVE_DOWN else BlockBox.NO_COLLISION) + } + else + world.setTileTerrain(x, y, blockBox.collisionType) } } @@ -67,7 +74,6 @@ open class FixtureBase(blockBox0: BlockBox, val blockBoxProps: BlockBoxProps = B return true // TODO for the tests' sake, just get fucking spawned - // FIXME has "roundworld anomaly"; check 'ActorWithBody.inScreen()' } /** diff --git a/src/net/torvald/terrarum/worlddrawer/WorldCamera.kt b/src/net/torvald/terrarum/worlddrawer/WorldCamera.kt index 6c4a5f721..962718a28 100644 --- a/src/net/torvald/terrarum/worlddrawer/WorldCamera.kt +++ b/src/net/torvald/terrarum/worlddrawer/WorldCamera.kt @@ -17,6 +17,10 @@ object WorldCamera { private set var y: Int = 0 // top position private set + var xEnd: Int = 0 // right position + private set + var yEnd: Int = 0 // bottom position + private set inline val gdxCamX: Float // centre position get() = xCentre.toFloat() inline val gdxCamY: Float// centre position @@ -53,6 +57,8 @@ object WorldCamera { world.height * TILE_SIZE - height - TILE_SIZE.toFloat() )).floorInt().clampCameraY(world) + xEnd = x + width + yEnd = y + height } private fun Int.clampCameraY(world: GameWorld): Int {