From cb1390d72fee436ae812d7ad225cc1b38bb420ef Mon Sep 17 00:00:00 2001 From: Song Minjae Date: Fri, 16 Dec 2016 23:57:08 +0900 Subject: [PATCH] added sugar to the Hitbox: Can use both (x1, y1, x2, y2) and (x1, y1, w, h) Former-commit-id: d8d62440493bf1ffe4f15420f85d0973c9de79ed Former-commit-id: c66228059d46a1258257c2c0ceb64da99ecd2871 --- .../terrarum/gameactors/ActorWithBody.kt | 84 ++++++++++--------- src/net/torvald/terrarum/gameactors/Hitbox.kt | 44 +++++----- 2 files changed, 66 insertions(+), 62 deletions(-) diff --git a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt index b629b615c..a18d968f1 100644 --- a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt +++ b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt @@ -190,8 +190,8 @@ open class ActorWithBody : Actor() { actorValue[AVKey.DRAGCOEFF] = value } - @Transient private val UD_COMPENSATOR_MAX = TSIZE - @Transient private val LR_COMPENSATOR_MAX = TSIZE + @Transient private val UD_COMPENSATOR_MAX = TILE_SIZE + @Transient private val LR_COMPENSATOR_MAX = TILE_SIZE /** * Post-hit invincibility, in milliseconds @@ -277,13 +277,13 @@ open class ActorWithBody : Actor() { * @param y */ fun setPosition(x: Double, y: Double) { - hitbox.set( + hitbox.setFromWidthHeight( x - (baseHitboxW / 2 - hitboxTranslateX) * scale, y - (baseHitboxH - hitboxTranslateY) * scale, baseHitboxW * scale, baseHitboxH * scale) - nextHitbox.set( + nextHitbox.setFromWidthHeight( x - (baseHitboxW / 2 - hitboxTranslateX) * scale, y - (baseHitboxH - hitboxTranslateY) * scale, baseHitboxW * scale, @@ -595,10 +595,10 @@ open class ActorWithBody : Actor() { } } - val txStart = x1.div(TSIZE).floorInt() - val txEnd = x2.div(TSIZE).floorInt() - val tyStart = y1.div(TSIZE).floorInt() - val tyEnd = y2.div(TSIZE).floorInt() + val txStart = x1.div(TILE_SIZE).floorInt() + val txEnd = x2.div(TILE_SIZE).floorInt() + val tyStart = y1.div(TILE_SIZE).floorInt() + val tyEnd = y2.div(TILE_SIZE).floorInt() return isCollidingInternal(txStart, tyStart, txEnd, tyEnd) } @@ -634,10 +634,10 @@ open class ActorWithBody : Actor() { } else throw IllegalArgumentException() - val txStart = x1.div(TSIZE).floorInt() - val txEnd = x2.div(TSIZE).floorInt() - val tyStart = y1.div(TSIZE).floorInt() - val tyEnd = y2.div(TSIZE).floorInt() + val txStart = x1.div(TILE_SIZE).floorInt() + val txEnd = x2.div(TILE_SIZE).floorInt() + val tyStart = y1.div(TILE_SIZE).floorInt() + val tyEnd = y2.div(TILE_SIZE).floorInt() return isCollidingInternal(txStart, tyStart, txEnd, tyEnd) } @@ -674,10 +674,10 @@ open class ActorWithBody : Actor() { } else throw IllegalArgumentException() - val txStart = x1.div(TSIZE).roundInt() - val txEnd = x2.div(TSIZE).roundInt() - val tyStart = y1.div(TSIZE).roundInt() - val tyEnd = y2.div(TSIZE).roundInt() + val txStart = x1.div(TILE_SIZE).roundInt() + val txEnd = x2.div(TILE_SIZE).roundInt() + val tyStart = y1.div(TILE_SIZE).roundInt() + val tyEnd = y2.div(TILE_SIZE).roundInt() return isCollidingInternal(txStart, tyStart, txEnd, tyEnd) } @@ -826,17 +826,19 @@ open class ActorWithBody : Actor() { var friction = 0 val frictionCalcHitbox = if (!isWalkingH) - Hitbox(nextHitbox.posX, nextHitbox.posY, - nextHitbox.width + 2.0, nextHitbox.height + 2.0) + Hitbox(nextHitbox.posX, + nextHitbox.posY, + nextHitbox.width + 2.0, + nextHitbox.height + 2.0) // when not walking, enlarge the hitbox for calculation so that // feet tiles are also counted else nextHitbox.clone() // take highest value - val tilePosXStart = (frictionCalcHitbox.posX / TSIZE).floorInt() - val tilePosXEnd = (frictionCalcHitbox.hitboxEnd.x / TSIZE).floorInt() - val tilePosY = (frictionCalcHitbox.pointedY / TSIZE).floorInt() + val tilePosXStart = (frictionCalcHitbox.posX / TILE_SIZE).floorInt() + val tilePosXEnd = (frictionCalcHitbox.hitboxEnd.x / TILE_SIZE).floorInt() + val tilePosY = (frictionCalcHitbox.pointedY / TILE_SIZE).floorInt() for (x in tilePosXStart..tilePosXEnd) { val tile = world.getTileFromTerrain(x, tilePosY) @@ -858,10 +860,10 @@ open class ActorWithBody : Actor() { var density = 0 // take highest value - val tilePosXStart = (hitbox.posX / TSIZE).roundInt() - val tilePosXEnd = (hitbox.hitboxEnd.x / TSIZE).roundInt() - val tilePosYStart = (hitbox.posY / TSIZE).roundInt() - val tilePosYEnd = (hitbox.hitboxEnd.y / TSIZE).roundInt() + val tilePosXStart = (hitbox.posX / TILE_SIZE).roundInt() + val tilePosXEnd = (hitbox.hitboxEnd.x / TILE_SIZE).roundInt() + val tilePosYStart = (hitbox.posY / TILE_SIZE).roundInt() + val tilePosYEnd = (hitbox.hitboxEnd.y / TILE_SIZE).roundInt() for (y in tilePosXStart..tilePosYEnd) { for (x in tilePosXStart..tilePosXEnd) { val tile = world.getTileFromTerrain(x, y) @@ -883,10 +885,10 @@ open class ActorWithBody : Actor() { var density = 0 //get highest fluid density - val tilePosXStart = (nextHitbox.posX / TSIZE).roundInt() - val tilePosYStart = (nextHitbox.posY / TSIZE).roundInt() - val tilePosXEnd = (nextHitbox.hitboxEnd.x / TSIZE).roundInt() - val tilePosYEnd = (nextHitbox.hitboxEnd.y / TSIZE).roundInt() + val tilePosXStart = (nextHitbox.posX / TILE_SIZE).roundInt() + val tilePosYStart = (nextHitbox.posY / TILE_SIZE).roundInt() + val tilePosXEnd = (nextHitbox.hitboxEnd.x / TILE_SIZE).roundInt() + val tilePosYEnd = (nextHitbox.hitboxEnd.y / TILE_SIZE).roundInt() for (y in tilePosYStart..tilePosYEnd) { for (x in tilePosXStart..tilePosXEnd) { val tile = world.getTileFromTerrain(x, y) @@ -900,7 +902,7 @@ open class ActorWithBody : Actor() { } private fun clampHitbox() { - val worldsizePxl = world.width.times(TSIZE) + val worldsizePxl = world.width.times(TILE_SIZE) hitbox.setPositionFromPoint( //clampW(hitbox.pointedX), @@ -915,7 +917,7 @@ open class ActorWithBody : Actor() { } private fun setNewNextHitbox() { - nextHitbox.set( + nextHitbox.setFromWidthHeight( hitbox.posX + moveDelta.x, hitbox.posY + moveDelta.y, baseHitboxW * scale, @@ -978,22 +980,22 @@ open class ActorWithBody : Actor() { } private fun clampW(x: Double): Double = - if (x < TSIZE + nextHitbox.width / 2) { - TSIZE + nextHitbox.width / 2 + if (x < TILE_SIZE + nextHitbox.width / 2) { + TILE_SIZE + nextHitbox.width / 2 } - else if (x >= (world.width * TSIZE).toDouble() - TSIZE.toDouble() - nextHitbox.width / 2) { - (world.width * TSIZE).toDouble() - 1.0 - TSIZE.toDouble() - nextHitbox.width / 2 + else if (x >= (world.width * TILE_SIZE).toDouble() - TILE_SIZE.toDouble() - nextHitbox.width / 2) { + (world.width * TILE_SIZE).toDouble() - 1.0 - TILE_SIZE.toDouble() - nextHitbox.width / 2 } else { x } private fun clampH(y: Double): Double = - if (y < TSIZE + nextHitbox.height) { - TSIZE + nextHitbox.height + if (y < TILE_SIZE + nextHitbox.height) { + TILE_SIZE + nextHitbox.height } - else if (y >= (world.height * TSIZE).toDouble() - TSIZE.toDouble() - nextHitbox.height) { - (world.height * TSIZE).toDouble() - 1.0 - TSIZE.toDouble() - nextHitbox.height + else if (y >= (world.height * TILE_SIZE).toDouble() - TILE_SIZE.toDouble() - nextHitbox.height) { + (world.height * TILE_SIZE).toDouble() - 1.0 - TILE_SIZE.toDouble() - nextHitbox.height } else { y @@ -1010,7 +1012,7 @@ open class ActorWithBody : Actor() { get() = this is Player && this.isNoClip() private val AUTO_CLIMB_RATE: Int - get() = Math.min(TSIZE / 8 * Math.sqrt(scale), TSIZE.toDouble()).toInt() + get() = Math.min(TILE_SIZE / 8 * Math.sqrt(scale), TILE_SIZE.toDouble()).toInt() private fun assertInit() { // errors @@ -1032,7 +1034,7 @@ open class ActorWithBody : Actor() { companion object { - @Transient private val TSIZE = MapDrawer.TILE_SIZE + @Transient private val TILE_SIZE = MapDrawer.TILE_SIZE private fun div16TruncateToMapWidth(x: Int): Int { if (x < 0) diff --git a/src/net/torvald/terrarum/gameactors/Hitbox.kt b/src/net/torvald/terrarum/gameactors/Hitbox.kt index 327a3a877..b24d3d5e4 100644 --- a/src/net/torvald/terrarum/gameactors/Hitbox.kt +++ b/src/net/torvald/terrarum/gameactors/Hitbox.kt @@ -4,24 +4,25 @@ import net.torvald.point.Point2d import org.dyn4j.geometry.Vector2 /** + * Constructor: (top-left position, width, height) + * + * Can also use Hitbox.fromTwoPoints(x1, y1, x2, y2 + * * Created by minjaesong on 16-01-15. */ class Hitbox(x1: Double, y1: Double, width: Double, height: Double) { @Volatile var hitboxStart: Point2d private set - @Volatile var hitboxEnd: Point2d - private set + val hitboxEnd: Point2d + get() = Point2d(hitboxStart.x + width, hitboxStart.y + height) var width: Double = 0.0 private set var height: Double = 0.0 private set - val HALF_PIXEL = 0.5 - init { hitboxStart = Point2d(x1, y1) - hitboxEnd = Point2d(x1 + width, y1 + height) this.width = width this.height = height } @@ -35,7 +36,7 @@ class Hitbox(x1: Double, y1: Double, width: Double, height: Double) { * @return pointX */ val pointedX: Double - get() = hitboxStart.x + width / 2 + get() = centeredX /** * Returns bottom-centered point of hitbox. @@ -56,21 +57,22 @@ class Hitbox(x1: Double, y1: Double, width: Double, height: Double) { * @param width * @param height */ - fun set(x1: Double, y1: Double, width: Double, height: Double): Hitbox { + fun setFromWidthHeight(x1: Double, y1: Double, width: Double, height: Double): Hitbox { hitboxStart = Point2d(x1, y1) - hitboxEnd = Point2d(x1 + width, y1 + height) this.width = width this.height = height return this } - fun reassign(other: Hitbox) = set(other.posX, other.posY, other.width, other.height) + fun setFromTwoPoints(x1: Double, y1: Double, x2: Double, y2: Double): Hitbox { + return setFromWidthHeight(x1, y1, x2 - x1, y2 - y1) + } + fun reassign(other: Hitbox) = setFromTwoPoints(other.posX, other.posY, other.endPointX, other.endPointY) fun translate(x: Double, y: Double) = setPosition(posX + x, posY + y) fun translate(vec: Vector2) = translate(vec.x, vec.y) fun setPosition(x1: Double, y1: Double): Hitbox { hitboxStart = Point2d(x1, y1) - hitboxEnd = Point2d(x1 + width, y1 + height) return this } fun setPosition(vector: Vector2) = setPosition(vector.x, vector.y) @@ -80,7 +82,6 @@ class Hitbox(x1: Double, y1: Double, width: Double, height: Double) { fun setPositionFromPoint(x1: Double, y1: Double): Hitbox { hitboxStart = Point2d(x1 - width / 2, y1 - height) - hitboxEnd = Point2d(hitboxStart.x + width, hitboxStart.y + height) return this } @@ -100,14 +101,6 @@ class Hitbox(x1: Double, y1: Double, width: Double, height: Double) { return this } - /*fun snapToPixel(): Hitbox { - hitboxStart.x = Math.round(hitboxStart.x - HALF_PIXEL).toDouble() - hitboxStart.y = Math.round(hitboxStart.y - HALF_PIXEL).toDouble() - hitboxEnd.x = Math.round(hitboxEnd.x - HALF_PIXEL).toDouble() - hitboxEnd.y = Math.round(hitboxEnd.y - HALF_PIXEL).toDouble() - return this - }*/ - /** * Returns x value of start point * @return top-left point posX @@ -123,12 +116,21 @@ class Hitbox(x1: Double, y1: Double, width: Double, height: Double) { get() = hitboxStart.y val centeredX: Double - get() = (hitboxStart.x + hitboxEnd.x) * 0.5f + get() = (hitboxStart.x + hitboxEnd.x) * 0.5 val centeredY: Double - get() = (hitboxStart.y + hitboxEnd.y) * 0.5f + get() = (hitboxStart.y + hitboxEnd.y) * 0.5 + + fun intersects(position: Point2d) = + (position.x >= posX && position.x <= posX + width) && + (position.y >= posY && position.y <= posY + height) fun toVector(): Vector2 = Vector2(posX, posY) fun clone(): Hitbox = Hitbox(posX, posY, width, height) + + companion object { + fun fromTwoPoints(x1: Double, y1: Double, x2: Double, y2: Double) = + Hitbox(x1, y1, x2 - x1, y2 - y1) + } }