mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 12:21:52 +09:00
fixing "roundworld anomaly": some actors won't render
This commit is contained in:
@@ -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()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()'
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user