mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 12:21:52 +09:00
at least it snaps without hacks; adding one important documentaion
This commit is contained in:
@@ -220,6 +220,7 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
@Transient private val COLLIDING_UD = 4
|
@Transient private val COLLIDING_UD = 4
|
||||||
@Transient private val COLLIDING_LR = 5
|
@Transient private val COLLIDING_LR = 5
|
||||||
@Transient private val COLLIDING_ALLSIDE = 6
|
@Transient private val COLLIDING_ALLSIDE = 6
|
||||||
|
@Transient private val COLLIDING_EXTRA_SIZE = 7
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Temporary variables
|
* Temporary variables
|
||||||
@@ -553,7 +554,7 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
*/
|
*/
|
||||||
@Deprecated("It's stupid anyway.") private fun displaceByCCD() {
|
@Deprecated("It's stupid anyway.") private fun displaceByCCD() {
|
||||||
if (!isNoCollideWorld) {
|
if (!isNoCollideWorld) {
|
||||||
if (!isColliding(hitbox, COLLIDING_ALLSIDE))
|
if (!isColliding(hitbox))
|
||||||
return
|
return
|
||||||
|
|
||||||
// do some CCD between hitbox and nextHitbox
|
// do some CCD between hitbox and nextHitbox
|
||||||
@@ -567,7 +568,7 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
//println("deltaMax: $deltaMax")
|
//println("deltaMax: $deltaMax")
|
||||||
//println("ccdDelta: $ccdDelta")
|
//println("ccdDelta: $ccdDelta")
|
||||||
|
|
||||||
while (!ccdDelta.isZero && isColliding(hitbox, COLLIDING_ALLSIDE)) {
|
while (!ccdDelta.isZero && isColliding(hitbox)) {
|
||||||
hitbox.translate(-ccdDelta)
|
hitbox.translate(-ccdDelta)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -614,13 +615,13 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
var ccdTick: Int = ccdSteps // 0..15: collision detected, 16: not
|
var ccdTick: Int = ccdSteps // 0..15: collision detected, 16: not
|
||||||
|
|
||||||
// do CCD first
|
// do CCD first
|
||||||
for (i in 1..ccdSteps) {
|
for (i in 1..ccdSteps) { // start from 1: if you are grounded, CCD of 0 will report as COLLIDING and will not you jump
|
||||||
simulationHitbox.reassign(hitbox)
|
simulationHitbox.reassign(hitbox)
|
||||||
simulationHitbox.translate(getBacktrackDelta(i.toDouble() / ccdSteps))
|
simulationHitbox.translate(getBacktrackDelta(i.toDouble() / ccdSteps))
|
||||||
|
|
||||||
println("ccd $i, endY = ${simulationHitbox.endPointY}")
|
println("ccd $i, endY = ${simulationHitbox.endPointY}")
|
||||||
|
|
||||||
if (isColliding(simulationHitbox)) {
|
if (isColliding(simulationHitbox)) { //COLLIDING_EXTRA_SIZE: doing trick so that final pos would be x.99800000 instead of y.0000000
|
||||||
ccdTick = i
|
ccdTick = i
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -666,7 +667,7 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
// find no-collision point using binary search
|
// find no-collision point using binary search
|
||||||
// trust me, X- and Y-axis must move simultaneously.
|
// trust me, X- and Y-axis must move simultaneously.
|
||||||
//// binary search ////
|
//// binary search ////
|
||||||
if (ccdTick > 1) {
|
if (ccdTick >= 1) {
|
||||||
var low = (ccdTick - 1).toDouble() / ccdSteps
|
var low = (ccdTick - 1).toDouble() / ccdSteps
|
||||||
var high = (ccdTick).toDouble() / ccdSteps
|
var high = (ccdTick).toDouble() / ccdSteps
|
||||||
var bmid: Double
|
var bmid: Double
|
||||||
@@ -681,7 +682,7 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
print("bmid = $bmid, new endY: ${simulationHitbox.endPointY}")
|
print("bmid = $bmid, new endY: ${simulationHitbox.endPointY}")
|
||||||
|
|
||||||
// set new mid
|
// set new mid
|
||||||
if (isColliding(simulationHitbox)) {
|
if (isColliding(simulationHitbox)) { //COLLIDING_EXTRA_SIZE: doing trick so that final pos would be x.99800000 instead of y.0000000
|
||||||
print(", going back\n")
|
print(", going back\n")
|
||||||
high = bmid
|
high = bmid
|
||||||
}
|
}
|
||||||
@@ -804,72 +805,32 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isColliding(hitbox: Hitbox) = isColliding(hitbox, 0)
|
//private fun isColliding(hitbox: Hitbox) = isColliding(hitbox, 0)
|
||||||
|
|
||||||
private fun isColliding(hitbox: Hitbox, option: Int): Boolean {
|
/**
|
||||||
|
* @see /work_files/hitbox_collision_detection_compensation.jpg
|
||||||
|
*/
|
||||||
|
private fun isColliding(hitbox: Hitbox): Boolean {
|
||||||
if (isNoCollideWorld) return false
|
if (isNoCollideWorld) return false
|
||||||
|
|
||||||
// offsets will stretch and shrink detection box according to the argument
|
// offsets will stretch and shrink detection box according to the argument
|
||||||
val x1: Double
|
val x1 = hitbox.posX - A_PIXEL
|
||||||
val x2: Double
|
val x2 = hitbox.posX + hitbox.width
|
||||||
val y1: Double
|
val y1 = hitbox.posY - A_PIXEL
|
||||||
val y2: Double
|
val y2 = hitbox.posY + hitbox.height
|
||||||
if (option == COLLIDING_LR || option == COLLIDING_UD) {
|
|
||||||
val offsetX = if (option == COLLIDING_LR) A_PIXEL else 0.0
|
|
||||||
val offsetY = if (option == COLLIDING_UD) A_PIXEL else 0.0
|
|
||||||
|
|
||||||
x1 = hitbox.posX - offsetX + offsetY
|
|
||||||
x2 = hitbox.posX + offsetX - offsetY + hitbox.width
|
|
||||||
y1 = hitbox.posY + offsetX - offsetY
|
|
||||||
y2 = hitbox.posY - offsetX + offsetY + hitbox.height
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (option == COLLIDING_ALLSIDE) {
|
|
||||||
x1 = hitbox.posX - A_PIXEL
|
|
||||||
x2 = hitbox.posX + A_PIXEL + hitbox.width
|
|
||||||
y1 = hitbox.posY - A_PIXEL
|
|
||||||
y2 = hitbox.posY + A_PIXEL + hitbox.height
|
|
||||||
}
|
|
||||||
else if (option == COLLIDING_LEFT) {
|
|
||||||
x1 = hitbox.posX - A_PIXEL
|
|
||||||
x2 = hitbox.posX - A_PIXEL + hitbox.width
|
|
||||||
y1 = hitbox.posY + A_PIXEL
|
|
||||||
y2 = hitbox.posY - A_PIXEL + hitbox.height
|
|
||||||
}
|
|
||||||
else if (option == COLLIDING_RIGHT) {
|
|
||||||
x1 = hitbox.posX + A_PIXEL
|
|
||||||
x2 = hitbox.posX + A_PIXEL + hitbox.width
|
|
||||||
y1 = hitbox.posY + A_PIXEL
|
|
||||||
y2 = hitbox.posY - A_PIXEL + hitbox.height
|
|
||||||
}
|
|
||||||
else if (option == COLLIDING_TOP) {
|
|
||||||
x1 = hitbox.posX + A_PIXEL
|
|
||||||
x2 = hitbox.posX - A_PIXEL + hitbox.width
|
|
||||||
y1 = hitbox.posY - A_PIXEL
|
|
||||||
y2 = hitbox.posY - A_PIXEL + hitbox.height
|
|
||||||
}
|
|
||||||
else if (option == COLLIDING_BOTTOM) {
|
|
||||||
x1 = hitbox.posX + A_PIXEL
|
|
||||||
x2 = hitbox.posX - A_PIXEL + hitbox.width
|
|
||||||
y1 = hitbox.posY + A_PIXEL
|
|
||||||
y2 = hitbox.posY + A_PIXEL + hitbox.height
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
x1 = hitbox.posX
|
|
||||||
x2 = hitbox.posX + hitbox.width
|
|
||||||
y1 = hitbox.posY
|
|
||||||
y2 = hitbox.posY + hitbox.height
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val txStart = x1.plus(1.0).div(TILE_SIZE).floorInt() // plus(1.0) : adjusting for yet another anomaly
|
val txStart = x1.div(TILE_SIZE).floorInt() // plus(1.0) : adjusting for yet another anomaly
|
||||||
val txEnd = x2.plus(1.0).div(TILE_SIZE).floorInt()
|
val txEnd = x2.div(TILE_SIZE).floorInt()
|
||||||
val tyStart = y1.plus(1.0).div(TILE_SIZE).floorInt()
|
val tyStart = y1.div(TILE_SIZE).floorInt()
|
||||||
val tyEnd = y2.plus(1.0).div(TILE_SIZE).floorInt()
|
val tyEnd = y2.div(TILE_SIZE).floorInt()
|
||||||
|
|
||||||
return isCollidingInternal(txStart, tyStart, txEnd, tyEnd)
|
return isCollidingInternal(txStart, tyStart, txEnd, tyEnd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see /work_files/hitbox_collision_detection_compensation.jpg
|
||||||
|
*/
|
||||||
private fun isTouchingSide(hitbox: Hitbox, option: Int): Boolean {
|
private fun isTouchingSide(hitbox: Hitbox, option: Int): Boolean {
|
||||||
val x1: Double
|
val x1: Double
|
||||||
val x2: Double
|
val x2: Double
|
||||||
@@ -877,34 +838,34 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
val y2: Double
|
val y2: Double
|
||||||
if (option == COLLIDING_TOP) {
|
if (option == COLLIDING_TOP) {
|
||||||
x1 = hitbox.posX
|
x1 = hitbox.posX
|
||||||
x2 = hitbox.endPointX
|
x2 = hitbox.endPointX - A_PIXEL
|
||||||
y1 = hitbox.posY - A_PIXEL
|
y1 = hitbox.posY - A_PIXEL
|
||||||
y2 = y1
|
y2 = y1
|
||||||
}
|
}
|
||||||
else if (option == COLLIDING_BOTTOM) {
|
else if (option == COLLIDING_BOTTOM) {
|
||||||
x1 = hitbox.posX
|
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
|
y1 = hitbox.posY
|
||||||
y2 = hitbox.endPointY
|
y2 = hitbox.endPointY - A_PIXEL
|
||||||
}
|
}
|
||||||
else if (option == COLLIDING_RIGHT) {
|
else if (option == COLLIDING_RIGHT) {
|
||||||
x1 = hitbox.endPointX + A_PIXEL
|
x1 = hitbox.endPointX
|
||||||
x2 = x1
|
x2 = x1
|
||||||
y1 = hitbox.posY
|
y1 = hitbox.posY
|
||||||
y2 = hitbox.endPointY
|
y2 = hitbox.endPointY - A_PIXEL
|
||||||
}
|
}
|
||||||
else throw IllegalArgumentException()
|
else throw IllegalArgumentException()
|
||||||
|
|
||||||
val txStart = x1.plus(1.0).div(TILE_SIZE).floorInt()
|
val txStart = x1.div(TILE_SIZE).floorInt()
|
||||||
val txEnd = x2.plus(1.0).div(TILE_SIZE).floorInt()
|
val txEnd = x2.div(TILE_SIZE).floorInt()
|
||||||
val tyStart = y1.plus(1.0).div(TILE_SIZE).floorInt()
|
val tyStart = y1.div(TILE_SIZE).floorInt()
|
||||||
val tyEnd = y2.plus(1.0).div(TILE_SIZE).floorInt()
|
val tyEnd = y2.div(TILE_SIZE).floorInt()
|
||||||
|
|
||||||
return isCollidingInternal(txStart, tyStart, txEnd, tyEnd)
|
return isCollidingInternal(txStart, tyStart, txEnd, tyEnd)
|
||||||
}
|
}
|
||||||
@@ -941,10 +902,10 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
}
|
}
|
||||||
else throw IllegalArgumentException()
|
else throw IllegalArgumentException()
|
||||||
|
|
||||||
val txStart = x1.plus(1.0).div(TILE_SIZE).floorInt()
|
val txStart = x1.div(TILE_SIZE).floorInt()
|
||||||
val txEnd = x2.plus(1.0).div(TILE_SIZE).floorInt()
|
val txEnd = x2.div(TILE_SIZE).floorInt()
|
||||||
val tyStart = y1.plus(1.0).div(TILE_SIZE).floorInt()
|
val tyStart = y1.div(TILE_SIZE).floorInt()
|
||||||
val tyEnd = y2.plus(1.0).div(TILE_SIZE).floorInt()
|
val tyEnd = y2.div(TILE_SIZE).floorInt()
|
||||||
|
|
||||||
return isCollidingInternal(txStart, tyStart, txEnd, tyEnd)
|
return isCollidingInternal(txStart, tyStart, txEnd, tyEnd)
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
work_files/hitbox_collision_detection_compensation.jpg
Normal file
BIN
work_files/hitbox_collision_detection_compensation.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 MiB |
Reference in New Issue
Block a user