mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-13 20:14:05 +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
|
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...
|
// not sure we need this...
|
||||||
/*else if (!jumpable) {
|
/*else if (!jumpable) {
|
||||||
@@ -502,7 +505,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
|
|||||||
noClip = b
|
noClip = b
|
||||||
|
|
||||||
if (b) {
|
if (b) {
|
||||||
moveDelta.zero()
|
externalForce.zero()
|
||||||
controllerMoveDelta?.zero()
|
controllerMoveDelta?.zero()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -517,7 +520,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
|
|||||||
|
|
||||||
if (grounded) {
|
if (grounded) {
|
||||||
// set anim row
|
// set anim row
|
||||||
if (moveDelta.x != 0.0) {
|
if (controllerMoveDelta?.x != 0.0) {
|
||||||
if (sprite != null) sprite!!.switchRow(SPRITE_ROW_WALK)
|
if (sprite != null) sprite!!.switchRow(SPRITE_ROW_WALK)
|
||||||
if (spriteGlow != null) spriteGlow!!.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 (moveDelta.y > 0.0) {
|
||||||
if (isTouchingSide(hitbox, COLLIDING_TOP)) { // hit the ceiling
|
if (isTouchingSide(hitbox, COLLIDING_TOP)) { // hit the ceiling
|
||||||
hitAndReflectY() //hitAndForciblyReflectY()
|
hitAndReflectY() //hitAndForciblyReflectY()
|
||||||
grounded = false
|
//grounded = false
|
||||||
}
|
}
|
||||||
else if (isTouchingSide(hitbox, COLLIDING_BOTTOM)) { // actor hit something on its bottom
|
else if (isTouchingSide(hitbox, COLLIDING_BOTTOM)) { // actor hit something on its bottom
|
||||||
hitAndReflectY()
|
hitAndReflectY()
|
||||||
grounded = true
|
grounded = true
|
||||||
}
|
}
|
||||||
else { // the actor is not grounded at all
|
else { // the actor is not grounded at all
|
||||||
grounded = false
|
//grounded = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// or was moving upward?
|
// or was moving upward?
|
||||||
@@ -653,77 +653,89 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
|
|
||||||
|
|
||||||
// collision not found
|
// collision not found
|
||||||
|
var collisionNotFound = false
|
||||||
if (ccdTick == ccdSteps) {
|
if (ccdTick == ccdSteps) {
|
||||||
hitbox.translate(externalForce)
|
hitbox.translate(externalForce)
|
||||||
println("no collision; endX = ${hitbox.endPointX}")
|
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
|
(1..binaryBranchingMax).forEach { _ ->
|
||||||
// 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 { _ ->
|
bmid = (low + high) / 2.0
|
||||||
|
|
||||||
bmid = (low + high) / 2.0
|
simulationHitbox.reassign(hitbox)
|
||||||
|
simulationHitbox.translate(getBacktrackDelta(bmid))
|
||||||
|
|
||||||
simulationHitbox.reassign(hitbox)
|
print("bmid = $bmid, new endY: ${simulationHitbox.endPointY}")
|
||||||
simulationHitbox.translate(getBacktrackDelta(bmid))
|
|
||||||
|
|
||||||
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
|
||||||
// set new mid
|
print(", going back\n")
|
||||||
if (isColliding(simulationHitbox)) { //COLLIDING_EXTRA_SIZE: doing trick so that final pos would be x.99800000 instead of y.0000000
|
high = bmid
|
||||||
print(", going back\n")
|
}
|
||||||
high = bmid
|
else {
|
||||||
}
|
print(", going forth\n")
|
||||||
else {
|
low = bmid
|
||||||
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
|
// 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
|
externalForce.x *= -elasticity
|
||||||
if (this is Controllable) walkX *= -elasticity
|
//if (this is Controllable) walkX *= -elasticity
|
||||||
|
|
||||||
//println("$this\t${externalForce.x}")
|
//println("$this\t${externalForce.x}")
|
||||||
}
|
}
|
||||||
@@ -760,7 +772,7 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
private fun hitAndReflectY() {
|
private fun hitAndReflectY() {
|
||||||
println("** reflY **")
|
println("** reflY **")
|
||||||
externalForce.y *= -elasticity
|
externalForce.y *= -elasticity
|
||||||
if (this is Controllable) walkY *= -elasticity
|
//if (this is Controllable) walkY *= -elasticity
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transient private val CEILING_HIT_ELASTICITY = 0.3
|
@Transient private val CEILING_HIT_ELASTICITY = 0.3
|
||||||
@@ -843,28 +855,28 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (option == COLLIDING_TOP) {
|
if (option == COLLIDING_TOP) {
|
||||||
x1 = hitbox.posX - A_PIXEL
|
x1 = hitbox.posX
|
||||||
x2 = hitbox.endPointX
|
x2 = hitbox.endPointX - A_PIXEL
|
||||||
y1 = hitbox.posY - A_PIXEL - A_PIXEL
|
y1 = hitbox.posY - A_PIXEL - A_PIXEL
|
||||||
y2 = y1
|
y2 = y1
|
||||||
}
|
}
|
||||||
else if (option == COLLIDING_BOTTOM) {
|
else if (option == COLLIDING_BOTTOM) {
|
||||||
x1 = hitbox.posX - A_PIXEL
|
x1 = hitbox.posX
|
||||||
x2 = hitbox.endPointX
|
x2 = hitbox.endPointX - A_PIXEL
|
||||||
y1 = hitbox.endPointY + A_PIXEL
|
y1 = hitbox.endPointY
|
||||||
y2 = y1
|
y2 = y1
|
||||||
}
|
}
|
||||||
else if (option == COLLIDING_LEFT) {
|
else if (option == COLLIDING_LEFT) {
|
||||||
x1 = hitbox.posX - A_PIXEL
|
x1 = hitbox.posX - A_PIXEL
|
||||||
x2 = x1
|
x2 = x1
|
||||||
y1 = hitbox.posY - A_PIXEL
|
y1 = hitbox.posY
|
||||||
y2 = hitbox.endPointY
|
y2 = hitbox.endPointY - A_PIXEL
|
||||||
}
|
}
|
||||||
else if (option == COLLIDING_RIGHT) {
|
else if (option == COLLIDING_RIGHT) {
|
||||||
x1 = hitbox.endPointX
|
x1 = hitbox.endPointX
|
||||||
x2 = x1
|
x2 = x1
|
||||||
y1 = hitbox.posY - A_PIXEL
|
y1 = hitbox.posY
|
||||||
y2 = hitbox.endPointY
|
y2 = hitbox.endPointY - A_PIXEL
|
||||||
}
|
}
|
||||||
else throw IllegalArgumentException()
|
else throw IllegalArgumentException()
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import net.torvald.terrarum.worlddrawer.FeaturesDrawer
|
|||||||
import net.torvald.terrarum.Terrarum
|
import net.torvald.terrarum.Terrarum
|
||||||
import net.torvald.terrarum.blendNormal
|
import net.torvald.terrarum.blendNormal
|
||||||
import net.torvald.terrarum.blendScreen
|
import net.torvald.terrarum.blendScreen
|
||||||
|
import net.torvald.terrarum.gameactors.ActorWithPhysics
|
||||||
import net.torvald.terrarum.worlddrawer.WorldCamera
|
import net.torvald.terrarum.worlddrawer.WorldCamera
|
||||||
import org.newdawn.slick.Color
|
import org.newdawn.slick.Color
|
||||||
import org.newdawn.slick.GameContainer
|
import org.newdawn.slick.GameContainer
|
||||||
@@ -43,14 +44,14 @@ class BasicDebugInfoWindow : UICanvas {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun update(gc: GameContainer, delta: Int) {
|
override fun update(gc: GameContainer, delta: Int) {
|
||||||
val player = Terrarum.ingame!!.player
|
val player = Terrarum.ingame!!.player!!
|
||||||
val hitbox = player?.hitbox
|
val hitbox = player.hitbox
|
||||||
|
|
||||||
xdelta = hitbox?.pointedX ?: 0 - prevPlayerX
|
xdelta = hitbox.pointedX - prevPlayerX
|
||||||
ydelta = hitbox?.pointedY ?: 0 - prevPlayerY
|
ydelta = hitbox.pointedY - prevPlayerY
|
||||||
|
|
||||||
prevPlayerX = hitbox?.pointedX ?: 0.0
|
prevPlayerX = hitbox.pointedX
|
||||||
prevPlayerY = hitbox?.pointedY ?: 0.0
|
prevPlayerY = hitbox.pointedY
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun render(gc: GameContainer, g: Graphics) {
|
override fun render(gc: GameContainer, g: Graphics) {
|
||||||
@@ -85,8 +86,8 @@ class BasicDebugInfoWindow : UICanvas {
|
|||||||
+ (hitbox?.endPointY?.div(FeaturesDrawer.TILE_SIZE))?.toInt().toString()
|
+ (hitbox?.endPointY?.div(FeaturesDrawer.TILE_SIZE))?.toInt().toString()
|
||||||
+ ")")
|
+ ")")
|
||||||
|
|
||||||
printLine(g, 3, "veloX reported $ccG${player?.moveDelta?.x}")
|
printLine(g, 3, "veloX reported $ccG${player?.externalForce?.x} ${player?.controllerMoveDelta?.x}")
|
||||||
printLine(g, 4, "veloY reported $ccG${player?.moveDelta?.y}")
|
printLine(g, 4, "veloY reported $ccG${player?.externalForce?.y} ${player?.controllerMoveDelta?.y}")
|
||||||
|
|
||||||
printLineColumn(g, 2, 3, "veloX measured $ccG${xdelta}")
|
printLineColumn(g, 2, 3, "veloX measured $ccG${xdelta}")
|
||||||
printLineColumn(g, 2, 4, "veloY measured $ccG${ydelta}")
|
printLineColumn(g, 2, 4, "veloY measured $ccG${ydelta}")
|
||||||
@@ -98,10 +99,14 @@ class BasicDebugInfoWindow : UICanvas {
|
|||||||
if (player != null) {
|
if (player != null) {
|
||||||
printLine(g, 7,
|
printLine(g, 7,
|
||||||
"walled ${if (player.walledLeft) "$ccR" else "$ccG"}L" +
|
"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"
|
"${if (player.walledRight) "$ccR" else "$ccG"}R"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//printLine(g, 7, "jump $ccG${player.jumpAcc}")
|
//printLine(g, 7, "jump $ccG${player.jumpAcc}")
|
||||||
|
|
||||||
val lightVal: String
|
val lightVal: String
|
||||||
|
|||||||
Reference in New Issue
Block a user