this fixes *some* case of abnormal displacement

This commit is contained in:
minjaesong
2017-06-03 00:37:47 +09:00
parent c5765fc08a
commit 7bd7a6532d

View File

@@ -171,7 +171,7 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
* think of a grass cutting on the Zelda games. It would also make a great puzzle to solve. * think of a grass cutting on the Zelda games. It would also make a great puzzle to solve.
* --minjaesong) * --minjaesong)
*/ */
@Volatile var isChronostasis = false var isChronostasis = false
/** /**
* Gravitational Constant G. Load from gameworld. * Gravitational Constant G. Load from gameworld.
@@ -190,8 +190,6 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
actorValue[AVKey.DRAGCOEFF] = value actorValue[AVKey.DRAGCOEFF] = value
} }
@Transient private val UD_COMPENSATOR_MAX = TILE_SIZE
@Transient private val LR_COMPENSATOR_MAX = TILE_SIZE
/** /**
* Post-hit invincibility, in milliseconds * Post-hit invincibility, in milliseconds
@@ -200,10 +198,15 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
@Transient internal val BASE_FRICTION = 0.3 @Transient internal val BASE_FRICTION = 0.3
@Transient internal val BASE_FALLDAMAGE_DAMPEN = 50.0
val fallDamageDampening: Double
get() = BASE_FALLDAMAGE_DAMPEN * (actorValue.getAsDouble(AVKey.FALLDAMPENMULT) ?: 1.0)
var collisionType = COLLISION_DYNAMIC var collisionType = COLLISION_DYNAMIC
@Transient private val CCD_TICK = 1.0 / 16.0 //@Transient private val CCD_TICK = 1.0 / 16.0
@Transient private val CCD_TRY_MAX = 12800 //@Transient private val CCD_TRY_MAX = 12800
// just some trivial magic numbers // just some trivial magic numbers
@Transient private val A_PIXEL = 1.0 @Transient private val A_PIXEL = 1.0
@@ -225,11 +228,11 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
@Transient private var assertPrinted = false @Transient private var assertPrinted = false
// debug only // debug only
internal @Volatile var walledLeft = false internal var walledLeft = false
internal @Volatile var walledRight = false internal var walledRight = false
internal @Volatile var walledTop = false // UNUSED; only for BasicDebugInfoWindow internal var walledTop = false // UNUSED; only for BasicDebugInfoWindow
internal @Volatile var walledBottom = false // UNUSED; only for BasicDebugInfoWindow internal var walledBottom = false // UNUSED; only for BasicDebugInfoWindow
internal @Volatile var colliding = false internal var colliding = false
protected val gameContainer: GameContainer protected val gameContainer: GameContainer
get() = Terrarum.appgc get() = Terrarum.appgc
@@ -490,7 +493,7 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
* Apply only if not grounded; normal force is precessed separately. * Apply only if not grounded; normal force is precessed separately.
*/ */
private fun applyGravitation() { private fun applyGravitation() {
if (!isNoSubjectToGrav && !isWalled(hitbox, COLLIDING_BOTTOM)) { if (!isNoSubjectToGrav && !(gravitation.y > 0 && walledBottom || gravitation.y < 0 && walledTop)) {
//if (!isWalled(hitbox, COLLIDING_BOTTOM)) { //if (!isWalled(hitbox, COLLIDING_BOTTOM)) {
/** /**
* weight; gravitational force in action * weight; gravitational force in action
@@ -541,12 +544,6 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
} }
}*/ }*/
/**
* nextHitbox must NOT be altered before this method is called!
*/
private val ccdSteps = 32 // max allowed velocity = backtrackSteps * TILE_SIZE
private val binaryBranchingMax = 54 // higher = more precise; theoretical max = 54 (# of mantissa + 2)
private fun displaceHitbox() { private fun displaceHitbox() {
fun debug1(wut: Any?) { fun debug1(wut: Any?) {
@@ -570,7 +567,7 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
val vectorSum = externalForce + controllerMoveDelta val vectorSum = externalForce + controllerMoveDelta
val ccdSteps = 16 val ccdSteps = minOf(16, (vectorSum.magnitudeSquared / TILE_SIZE.sqr()).floorInt() + 1) // adaptive
@@ -626,14 +623,7 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
} }
// collision detected // collision detected
else { else {
println("Collision step: $collidingStep") println("== Collision step: $collidingStep / $ccdSteps")
affectingTiles.forEach {
val tileCoord = LandUtil.resolveBlockAddr(it)
println("affectign tile: ${tileCoord.first}, ${tileCoord.second}")
}
val newHitbox = hitbox.reassign(sixteenStep[collidingStep]) val newHitbox = hitbox.reassign(sixteenStep[collidingStep])
@@ -646,6 +636,12 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
// fixme UP and RIGHT && LEFT and DOWN bug // fixme UP and RIGHT && LEFT and DOWN bug
println("Collision type: $selfCollisionStatus")
affectingTiles.forEach {
val tileCoord = LandUtil.resolveBlockAddr(it)
println("affectign tile: ${tileCoord.first}, ${tileCoord.second}")
}
when (selfCollisionStatus) { when (selfCollisionStatus) {
0 -> { println("[ActorWithPhysics] Contradiction -- collision detected by CCD, but isWalled() says otherwise") } 0 -> { println("[ActorWithPhysics] Contradiction -- collision detected by CCD, but isWalled() says otherwise") }
5 -> { zeroX = true } 5 -> { zeroX = true }
@@ -658,12 +654,13 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
2, 7 -> { newHitbox.translatePosY( - newHitbox.endY.modTileDelta()) ; bounceY = true } 2, 7 -> { newHitbox.translatePosY( - newHitbox.endY.modTileDelta()) ; bounceY = true }
// two-side collision // two-side collision
3 -> { 3 -> {
newHitbox.translatePosX(TILE_SIZE - newHitbox.startX.modTileDelta()) println("translateX: ${(TILE_SIZE - newHitbox.startX.modTileDelta()).rem(TILE_SIZE)}")
newHitbox.translatePosX((TILE_SIZE - newHitbox.startX.modTileDelta()).rem(TILE_SIZE))
newHitbox.translatePosY( - newHitbox.endY.modTileDelta()) newHitbox.translatePosY( - newHitbox.endY.modTileDelta())
bounceX = true; bounceY = true bounceX = true; bounceY = true
} }
6 -> { 6 -> {
println(- newHitbox.endY.modTileDelta()) println("translateX: ${( - newHitbox.endX.modTileDelta())}")
newHitbox.translatePosX( - newHitbox.endX.modTileDelta()) newHitbox.translatePosX( - newHitbox.endX.modTileDelta())
newHitbox.translatePosY( - newHitbox.endY.modTileDelta()) newHitbox.translatePosY( - newHitbox.endY.modTileDelta())
bounceX = true; bounceY = true bounceX = true; bounceY = true
@@ -674,8 +671,9 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
bounceX = true; bounceY = true bounceX = true; bounceY = true
} }
12 -> { 12 -> {
println("translateY: ${(TILE_SIZE - newHitbox.startY.modTileDelta()).rem(TILE_SIZE)}")
newHitbox.translatePosX( - newHitbox.endX.modTileDelta()) newHitbox.translatePosX( - newHitbox.endX.modTileDelta())
newHitbox.translatePosY(TILE_SIZE - newHitbox.startY.modTileDelta()) newHitbox.translatePosY((TILE_SIZE - newHitbox.startY.modTileDelta()).rem(TILE_SIZE))
bounceX = true; bounceY = true bounceX = true; bounceY = true
} }
} }
@@ -707,6 +705,13 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
hitbox.reassign(newHitbox) hitbox.reassign(newHitbox)
// slam-into-whatever damage (such dirty; much hack; wow)
// vvvv hack (supposed to be 1.0) vvv 50% hack
val collisionDamage = mass * (vectorSum.magnitude / (10.0 / Terrarum.TARGET_FPS).sqr()) / fallDamageDampening.sqr() * GAME_TO_SI_ACC
// kg * m / s^2 (mass * acceleration), acceleration -> (vectorMagn / (0.01)^2).gameToSI()
if (collisionDamage != 0.0) println("Collision damage: $collisionDamage N")
// grounded = true // grounded = true
}// end of collision not detected }// end of collision not detected
@@ -1193,9 +1198,9 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
blendLightenOnly() blendLightenOnly()
val offsetX = if (!spriteGlow!!.flippedHorizontal()) val offsetX = if (!spriteGlow!!.flippedHorizontal())
hitboxTranslateX * scale + 1 hitboxTranslateX * scale
else else
spriteGlow!!.cellWidth * scale - (hitbox.width + hitboxTranslateX * scale) + 1 spriteGlow!!.cellWidth * scale - (hitbox.width + hitboxTranslateX * scale)
val offsetY = spriteGlow!!.cellHeight * scale - hitbox.height - hitboxTranslateY * scale - 1 val offsetY = spriteGlow!!.cellHeight * scale - hitbox.height - hitboxTranslateY * scale - 1
@@ -1234,9 +1239,9 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
BlendMode.resolve(drawMode) BlendMode.resolve(drawMode)
val offsetX = if (!sprite!!.flippedHorizontal()) val offsetX = if (!sprite!!.flippedHorizontal())
hitboxTranslateX * scale + 1 hitboxTranslateX * scale
else else
sprite!!.cellWidth * scale - (hitbox.width + hitboxTranslateX * scale) + 1 sprite!!.cellWidth * scale - (hitbox.width + hitboxTranslateX * scale)
val offsetY = sprite!!.cellHeight * scale - hitbox.height - hitboxTranslateY * scale - 1 val offsetY = sprite!!.cellHeight * scale - hitbox.height - hitboxTranslateY * scale - 1
@@ -1407,12 +1412,18 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
/** /**
* [m / s^2] * SI_TO_GAME_ACC -> [px / InternalFrame^2] * [m / s^2] * SI_TO_GAME_ACC -> [px / InternalFrame^2]
*/ */
@Transient val SI_TO_GAME_ACC = METER / (Terrarum.TARGET_FPS * Terrarum.TARGET_FPS).toDouble() @Transient val SI_TO_GAME_ACC = METER / (Terrarum.TARGET_FPS * Terrarum.TARGET_FPS)
/** /**
* [m / s] * SI_TO_GAME_VEL -> [px / InternalFrame] * [m / s] * SI_TO_GAME_VEL -> [px / InternalFrame]
*/ */
@Transient val SI_TO_GAME_VEL = METER / Terrarum.TARGET_FPS @Transient val SI_TO_GAME_VEL = METER / Terrarum.TARGET_FPS
/**
* [px / InternalFrame^2] * GAME_TO_SI_ACC -> [m / s^2]
*/
@Transient val GAME_TO_SI_ACC = (Terrarum.TARGET_FPS * Terrarum.TARGET_FPS) / METER
/** /**
* Enumerations that exported to JSON * Enumerations that exported to JSON
*/ */
@@ -1486,6 +1497,7 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
scale.sqrt() scale.sqrt()
} }
fun Int.sqr(): Int = this * this
fun Double.floorInt() = Math.floor(this).toInt() fun Double.floorInt() = Math.floor(this).toInt()
fun Float.floorInt() = FastMath.floor(this) fun Float.floorInt() = FastMath.floor(this)
fun Float.floor() = FastMath.floor(this).toFloat() fun Float.floor() = FastMath.floor(this).toFloat()