loading process will try to unstuck the player if the player appears to stuck in the terrain

This commit is contained in:
minjaesong
2023-05-21 16:57:28 +09:00
parent 5d78df9e99
commit 974ad2ec50
5 changed files with 52 additions and 15 deletions

View File

@@ -459,6 +459,40 @@ open class ActorWithBody : Actor {
private val bounceDampenVelThreshold = 0.5 private val bounceDampenVelThreshold = 0.5
/**
* Used on final loading phase, move the player to the opposite direction of the gravitation, until the player's
* not colliding
*/
open fun tryUnstuck() {
val newHitbox = hitbox.clone()
val translation = gravitation.setMagnitude(-1.0)
while (isColliding(newHitbox)) {
newHitbox.translate(translation)
}
hitbox.reassign(newHitbox)
hIntTilewiseHitbox.setFromTwoPoints(
hitbox.startX.plus(PHYS_EPSILON_DIST).div(TILE_SIZE).floor() + 0.5,
hitbox.startY.plus(PHYS_EPSILON_DIST).div(TILE_SIZE).floor() + 0.5,
hitbox.endX.plus(PHYS_EPSILON_DIST).div(TILE_SIZE).floor() + 0.5,
hitbox.endY.plus(PHYS_EPSILON_DIST).div(TILE_SIZE).floor() + 0.5
)
intTilewiseHitbox.setFromTwoPoints(
hitbox.startX.div(TILE_SIZE).floor(),
hitbox.startY.div(TILE_SIZE).floor(),
hitbox.endX.minus(PHYS_EPSILON_DIST).div(TILE_SIZE).floor(),
hitbox.endY.minus(PHYS_EPSILON_DIST).div(TILE_SIZE).floor()
)
centrePosVector.set(hitbox.centeredX, hitbox.centeredY)
centrePosPoint.set(hitbox.centeredX, hitbox.centeredY)
feetPosVector.set(hitbox.centeredX, hitbox.endY)
feetPosPoint.set(hitbox.centeredX, hitbox.endY)
feetPosTile.set(hIntTilewiseHitbox.centeredX.floorInt(), hIntTilewiseHitbox.endY.floorInt())
}
override fun update(delta: Float) { override fun update(delta: Float) {
// re-scale hitbox // re-scale hitbox

View File

@@ -372,6 +372,11 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
} }
// try to unstuck the repositioned player
codices.player.tryUnstuck()
// by doing this, whatever the "possession" the player had will be broken by the game load // by doing this, whatever the "possession" the player had will be broken by the game load
actorNowPlaying = codices.player actorNowPlaying = codices.player
actorGamer = codices.player actorGamer = codices.player

View File

@@ -137,8 +137,7 @@ object WritePlayer {
object ReadPlayer { object ReadPlayer {
operator fun invoke(disk: SimpleFileSystem, dataStream: Reader): IngamePlayer = operator fun invoke(disk: SimpleFileSystem, dataStream: Reader): IngamePlayer =
ReadActor(disk, dataStream) as IngamePlayer ReadActor(disk, dataStream) as IngamePlayer
} }
/** /**
@@ -152,9 +151,11 @@ object ReadPlayer {
object ReadActor { object ReadActor {
operator fun invoke(disk: SimpleFileSystem, dataStream: Reader): Actor = operator fun invoke(disk: SimpleFileSystem, dataStream: Reader): Actor =
fillInDetails(disk, Common.jsoner.fromJson(null, dataStream)) Common.jsoner.fromJson<Actor?>(null, dataStream).also {
fillInDetails(disk, it)
}
private fun fillInDetails(disk: SimpleFileSystem, actor: Actor): Actor { private fun fillInDetails(disk: SimpleFileSystem, actor: Actor) {
actor.reload() actor.reload()
@@ -197,9 +198,6 @@ object ReadActor {
//actor.reassembleSprite(actor.sprite, actor.spriteGlow, null) //actor.reassembleSprite(actor.sprite, actor.spriteGlow, null)
} }
return actor
} }
} }

View File

@@ -99,16 +99,16 @@ object WriteWorld {
object ReadWorld { object ReadWorld {
operator fun invoke(worldDataStream: Reader, origin: File?): GameWorld = operator fun invoke(worldDataStream: Reader, origin: File?): GameWorld =
fillInDetails(Common.jsoner.fromJson(GameWorld::class.java, worldDataStream), origin) Common.jsoner.fromJson(GameWorld::class.java, worldDataStream).also {
fillInDetails(origin, it)
}
private fun fillInDetails(world: GameWorld, origin: File?): GameWorld { private fun fillInDetails(origin: File?, world: GameWorld) {
world.tileNumberToNameMap.forEach { l, s -> world.tileNumberToNameMap.forEach { l, s ->
world.tileNameToNumberMap[s] = l.toInt() world.tileNameToNumberMap[s] = l.toInt()
} }
ItemCodex.loadFromSave(origin, world.dynamicToStaticTable, world.dynamicItemInventory) ItemCodex.loadFromSave(origin, world.dynamicToStaticTable, world.dynamicItemInventory)
return world
} }
private val cw = LandUtil.CHUNK_W private val cw = LandUtil.CHUNK_W

View File

@@ -15,16 +15,16 @@ import java.io.Reader
object ReadSimpleWorld { object ReadSimpleWorld {
operator fun invoke(worldDataStream: Reader, origin: File?): GameWorld = operator fun invoke(worldDataStream: Reader, origin: File?): GameWorld =
fillInDetails(Common.jsoner.fromJson(SimpleGameWorld::class.java, worldDataStream), origin) Common.jsoner.fromJson(SimpleGameWorld::class.java, worldDataStream).also {
fillInDetails(origin, it)
}
private fun fillInDetails(world: GameWorld, origin: File?): GameWorld { private fun fillInDetails(origin: File?, world: GameWorld) {
world.tileNumberToNameMap.forEach { l, s -> world.tileNumberToNameMap.forEach { l, s ->
world.tileNameToNumberMap[s] = l.toInt() world.tileNameToNumberMap[s] = l.toInt()
} }
ItemCodex.loadFromSave(origin, world.dynamicToStaticTable, world.dynamicItemInventory) ItemCodex.loadFromSave(origin, world.dynamicToStaticTable, world.dynamicItemInventory)
return world
} }
fun readWorldAndSetNewWorld(ingame: IngameInstance, worldDataStream: Reader, origin: File?): GameWorld { fun readWorldAndSetNewWorld(ingame: IngameInstance, worldDataStream: Reader, origin: File?): GameWorld {