mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-10 05:41:51 +09:00
y-down blocking work (can jump down to hit the ground but not the ceiling)
This commit is contained in:
@@ -459,7 +459,10 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
|
||||
|
||||
jumpAcc = pwr * timedJumpCharge * JUMP_ACCELERATION_MOD * Math.sqrt(scale) // positive value
|
||||
|
||||
walkY -= jumpAcc
|
||||
walkY -= jumpAcc // feed negative value to the vector
|
||||
// do not think of resetting this to zero when counter hit the ceiling; that's HOW NOT
|
||||
// newtonian physics work, stupid myself :(
|
||||
|
||||
}
|
||||
// not sure we need this...
|
||||
/*else if (!jumpable) {
|
||||
@@ -502,7 +505,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
|
||||
noClip = b
|
||||
|
||||
if (b) {
|
||||
moveDelta.zero()
|
||||
externalForce.zero()
|
||||
controllerMoveDelta?.zero()
|
||||
}
|
||||
}
|
||||
@@ -517,7 +520,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
|
||||
|
||||
if (grounded) {
|
||||
// set anim row
|
||||
if (moveDelta.x != 0.0) {
|
||||
if (controllerMoveDelta?.x != 0.0) {
|
||||
if (sprite != null) sprite!!.switchRow(SPRITE_ROW_WALK)
|
||||
if (spriteGlow != null) spriteGlow!!.switchRow(SPRITE_ROW_WALK)
|
||||
}
|
||||
|
||||
@@ -521,14 +521,14 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
||||
if (moveDelta.y > 0.0) {
|
||||
if (isTouchingSide(hitbox, COLLIDING_TOP)) { // hit the ceiling
|
||||
hitAndReflectY() //hitAndForciblyReflectY()
|
||||
grounded = false
|
||||
//grounded = false
|
||||
}
|
||||
else if (isTouchingSide(hitbox, COLLIDING_BOTTOM)) { // actor hit something on its bottom
|
||||
hitAndReflectY()
|
||||
grounded = true
|
||||
}
|
||||
else { // the actor is not grounded at all
|
||||
grounded = false
|
||||
//grounded = false
|
||||
}
|
||||
}
|
||||
// or was moving upward?
|
||||
@@ -653,77 +653,89 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
||||
|
||||
|
||||
// collision not found
|
||||
var collisionNotFound = false
|
||||
if (ccdTick == ccdSteps) {
|
||||
hitbox.translate(externalForce)
|
||||
println("no collision; endX = ${hitbox.endPointX}")
|
||||
return
|
||||
collisionNotFound = true
|
||||
}
|
||||
|
||||
if (!collisionNotFound) {
|
||||
println("embedding befure: ${simulationHitbox.endPointX}")
|
||||
|
||||
println("embedding befure: ${simulationHitbox.endPointX}")
|
||||
// find no-collision point using binary search
|
||||
// trust me, X- and Y-axis must move simultaneously.
|
||||
//// binary search ////
|
||||
if (ccdTick >= 1) {
|
||||
var low = (ccdTick - 1).toDouble() / ccdSteps
|
||||
var high = (ccdTick).toDouble() / ccdSteps
|
||||
var bmid: Double
|
||||
|
||||
// find no-collision point using binary search
|
||||
// trust me, X- and Y-axis must move simultaneously.
|
||||
//// binary search ////
|
||||
if (ccdTick >= 1) {
|
||||
var low = (ccdTick - 1).toDouble() / ccdSteps
|
||||
var high = (ccdTick).toDouble() / ccdSteps
|
||||
var bmid: Double
|
||||
(1..binaryBranchingMax).forEach { _ ->
|
||||
|
||||
(1..binaryBranchingMax).forEach { _ ->
|
||||
bmid = (low + high) / 2.0
|
||||
|
||||
bmid = (low + high) / 2.0
|
||||
simulationHitbox.reassign(hitbox)
|
||||
simulationHitbox.translate(getBacktrackDelta(bmid))
|
||||
|
||||
simulationHitbox.reassign(hitbox)
|
||||
simulationHitbox.translate(getBacktrackDelta(bmid))
|
||||
print("bmid = $bmid, new endY: ${simulationHitbox.endPointY}")
|
||||
|
||||
print("bmid = $bmid, new endY: ${simulationHitbox.endPointY}")
|
||||
|
||||
// set new mid
|
||||
if (isColliding(simulationHitbox)) { //COLLIDING_EXTRA_SIZE: doing trick so that final pos would be x.99800000 instead of y.0000000
|
||||
print(", going back\n")
|
||||
high = bmid
|
||||
}
|
||||
else {
|
||||
print(", going forth\n")
|
||||
low = bmid
|
||||
// set new mid
|
||||
if (isColliding(simulationHitbox)) { //COLLIDING_EXTRA_SIZE: doing trick so that final pos would be x.99800000 instead of y.0000000
|
||||
print(", going back\n")
|
||||
high = bmid
|
||||
}
|
||||
else {
|
||||
print(", going forth\n")
|
||||
low = bmid
|
||||
}
|
||||
}
|
||||
|
||||
println("binarySearch embedding: ${simulationHitbox.endPointY}")
|
||||
|
||||
|
||||
// force set grounded-ness
|
||||
grounded = true
|
||||
// reset walkY
|
||||
walkY = 0.0
|
||||
println("!! grounded !!")
|
||||
}
|
||||
|
||||
println("binarySearch embedding: ${simulationHitbox.endPointY}")
|
||||
|
||||
// snap to closest tile
|
||||
// naturally, binarySearch gives you a point like 7584.99999999 (barely not colliding) or
|
||||
// 7585.000000000 (colliding as fuck), BUT what we want is 7584.00000000 .
|
||||
// [Procedure]
|
||||
// 1. get touching area of four sides incl. edge points
|
||||
// 2. a side with most touching area is the "colliding side"
|
||||
// 3. round the hitbox so that coord of "colliding" side be integer
|
||||
// 3.1. there's two main cases: "main axis" being X; "main axis" being Y
|
||||
// 3.2. edge cases: (TBA)
|
||||
|
||||
// test: assume hitting bottom
|
||||
//val roundedInteger = simulationHitbox.endPointY.div(TILE_SIZE).roundInt() * TILE_SIZE
|
||||
val displacementMainAxis = -1.0// - simulationHitbox.endPointY
|
||||
val displacementSecondAxis = displacementMainAxis * externalForce.x / externalForce.y
|
||||
|
||||
simulationHitbox.translate(displacementSecondAxis, displacementMainAxis)
|
||||
println("dx: $displacementSecondAxis, dy: $displacementMainAxis")
|
||||
|
||||
|
||||
println("externalForce: $externalForce, displacement: ${simulationHitbox - hitbox}")
|
||||
//hitbox.translate(getBacktrackDelta(bmid))
|
||||
hitbox.reassign(simulationHitbox)
|
||||
}
|
||||
|
||||
|
||||
// snap to closest tile
|
||||
// naturally, binarySearch gives you a point like 7584.99999999 (barely not colliding) or
|
||||
// 7585.000000000 (colliding as fuck), BUT what we want is 7584.00000000 .
|
||||
// [Procedure]
|
||||
// 1. get touching area of four sides incl. edge points
|
||||
// 2. a side with most touching area is the "colliding side"
|
||||
// 3. round the hitbox so that coord of "colliding" side be integer
|
||||
// 3.1. there's two main cases: "main axis" being X; "main axis" being Y
|
||||
// 3.2. edge cases: (TBA)
|
||||
|
||||
// test: assume hitting bottom
|
||||
val roundedInteger = simulationHitbox.endPointY.div(TILE_SIZE).roundInt() * TILE_SIZE
|
||||
val displacementMainAxis = roundedInteger - simulationHitbox.endPointY
|
||||
val displacementSecondAxis = displacementMainAxis * externalForce.x / externalForce.y
|
||||
|
||||
simulationHitbox.translate(displacementSecondAxis, displacementMainAxis)
|
||||
println("dx: $displacementSecondAxis, dy: $displacementMainAxis")
|
||||
|
||||
|
||||
println("externalForce: $externalForce, displacement: ${simulationHitbox - hitbox}")
|
||||
//hitbox.translate(getBacktrackDelta(bmid))
|
||||
hitbox.reassign(simulationHitbox)
|
||||
}
|
||||
|
||||
|
||||
// resolve controllerMoveDelta
|
||||
if (controllerMoveDelta != null) {
|
||||
hitbox.translate(controllerMoveDelta)
|
||||
}
|
||||
|
||||
|
||||
|
||||
println("# final hitbox.endY = ${hitbox.endPointY}")
|
||||
println("# final hitbox: $hitbox, wx: $walkX, wy: $walkY")
|
||||
|
||||
|
||||
|
||||
@@ -752,7 +764,7 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
||||
*/
|
||||
|
||||
externalForce.x *= -elasticity
|
||||
if (this is Controllable) walkX *= -elasticity
|
||||
//if (this is Controllable) walkX *= -elasticity
|
||||
|
||||
//println("$this\t${externalForce.x}")
|
||||
}
|
||||
@@ -760,7 +772,7 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
||||
private fun hitAndReflectY() {
|
||||
println("** reflY **")
|
||||
externalForce.y *= -elasticity
|
||||
if (this is Controllable) walkY *= -elasticity
|
||||
//if (this is Controllable) walkY *= -elasticity
|
||||
}
|
||||
|
||||
@Transient private val CEILING_HIT_ELASTICITY = 0.3
|
||||
@@ -843,28 +855,28 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
||||
*/
|
||||
|
||||
if (option == COLLIDING_TOP) {
|
||||
x1 = hitbox.posX - A_PIXEL
|
||||
x2 = hitbox.endPointX
|
||||
x1 = hitbox.posX
|
||||
x2 = hitbox.endPointX - A_PIXEL
|
||||
y1 = hitbox.posY - A_PIXEL - A_PIXEL
|
||||
y2 = y1
|
||||
}
|
||||
else if (option == COLLIDING_BOTTOM) {
|
||||
x1 = hitbox.posX - A_PIXEL
|
||||
x2 = hitbox.endPointX
|
||||
y1 = hitbox.endPointY + A_PIXEL
|
||||
x1 = hitbox.posX
|
||||
x2 = hitbox.endPointX - A_PIXEL
|
||||
y1 = hitbox.endPointY
|
||||
y2 = y1
|
||||
}
|
||||
else if (option == COLLIDING_LEFT) {
|
||||
x1 = hitbox.posX - A_PIXEL
|
||||
x2 = x1
|
||||
y1 = hitbox.posY - A_PIXEL
|
||||
y2 = hitbox.endPointY
|
||||
y1 = hitbox.posY
|
||||
y2 = hitbox.endPointY - A_PIXEL
|
||||
}
|
||||
else if (option == COLLIDING_RIGHT) {
|
||||
x1 = hitbox.endPointX
|
||||
x2 = x1
|
||||
y1 = hitbox.posY - A_PIXEL
|
||||
y2 = hitbox.endPointY
|
||||
y1 = hitbox.posY
|
||||
y2 = hitbox.endPointY - A_PIXEL
|
||||
}
|
||||
else throw IllegalArgumentException()
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import net.torvald.terrarum.worlddrawer.FeaturesDrawer
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.blendNormal
|
||||
import net.torvald.terrarum.blendScreen
|
||||
import net.torvald.terrarum.gameactors.ActorWithPhysics
|
||||
import net.torvald.terrarum.worlddrawer.WorldCamera
|
||||
import org.newdawn.slick.Color
|
||||
import org.newdawn.slick.GameContainer
|
||||
@@ -43,14 +44,14 @@ class BasicDebugInfoWindow : UICanvas {
|
||||
}
|
||||
|
||||
override fun update(gc: GameContainer, delta: Int) {
|
||||
val player = Terrarum.ingame!!.player
|
||||
val hitbox = player?.hitbox
|
||||
val player = Terrarum.ingame!!.player!!
|
||||
val hitbox = player.hitbox
|
||||
|
||||
xdelta = hitbox?.pointedX ?: 0 - prevPlayerX
|
||||
ydelta = hitbox?.pointedY ?: 0 - prevPlayerY
|
||||
xdelta = hitbox.pointedX - prevPlayerX
|
||||
ydelta = hitbox.pointedY - prevPlayerY
|
||||
|
||||
prevPlayerX = hitbox?.pointedX ?: 0.0
|
||||
prevPlayerY = hitbox?.pointedY ?: 0.0
|
||||
prevPlayerX = hitbox.pointedX
|
||||
prevPlayerY = hitbox.pointedY
|
||||
}
|
||||
|
||||
override fun render(gc: GameContainer, g: Graphics) {
|
||||
@@ -85,8 +86,8 @@ class BasicDebugInfoWindow : UICanvas {
|
||||
+ (hitbox?.endPointY?.div(FeaturesDrawer.TILE_SIZE))?.toInt().toString()
|
||||
+ ")")
|
||||
|
||||
printLine(g, 3, "veloX reported $ccG${player?.moveDelta?.x}")
|
||||
printLine(g, 4, "veloY reported $ccG${player?.moveDelta?.y}")
|
||||
printLine(g, 3, "veloX reported $ccG${player?.externalForce?.x} ${player?.controllerMoveDelta?.x}")
|
||||
printLine(g, 4, "veloY reported $ccG${player?.externalForce?.y} ${player?.controllerMoveDelta?.y}")
|
||||
|
||||
printLineColumn(g, 2, 3, "veloX measured $ccG${xdelta}")
|
||||
printLineColumn(g, 2, 4, "veloY measured $ccG${ydelta}")
|
||||
@@ -98,10 +99,14 @@ class BasicDebugInfoWindow : UICanvas {
|
||||
if (player != null) {
|
||||
printLine(g, 7,
|
||||
"walled ${if (player.walledLeft) "$ccR" else "$ccG"}L" +
|
||||
"${if (player.walledTop) "$ccR" else "$ccG"}${0x1E.toChar()}" +
|
||||
"${if (player.walledBottom) "$ccR" else "$ccG"}${0x1F.toChar()}" +
|
||||
"${if (player.walledRight) "$ccR" else "$ccG"}R"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
//printLine(g, 7, "jump $ccG${player.jumpAcc}")
|
||||
|
||||
val lightVal: String
|
||||
|
||||
Reference in New Issue
Block a user