mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-11 19:14:05 +09:00
fixing bug where the hitbox won't change when actor is rescaled, wip issue #34
This commit is contained in:
@@ -130,17 +130,19 @@ class SpriteAnimation(@Transient val parentActor: ActorWBMovable) {
|
|||||||
val region = textureRegion.get(currentFrame, currentRow)
|
val region = textureRegion.get(currentFrame, currentRow)
|
||||||
batch.color = colorFilter
|
batch.color = colorFilter
|
||||||
|
|
||||||
|
val scale = parentActor.scale.toFloat()
|
||||||
|
|
||||||
if (flipHorizontal && flipVertical) {
|
if (flipHorizontal && flipVertical) {
|
||||||
batch.draw(region,
|
batch.draw(region,
|
||||||
FastMath.floor(posX).toFloat() + (2f * parentActor.hitboxTranslateX * parentActor.scale.toFloat() + parentActor.hitbox.width.toFloat()),
|
FastMath.floor(posX).toFloat() + (2f * parentActor.hitboxTranslateX * scale + parentActor.hitbox.width.toFloat()),
|
||||||
FastMath.floor(posY).toFloat() + (2f * parentActor.hitboxTranslateY * parentActor.scale.toFloat() + parentActor.hitbox.height.toFloat()),
|
FastMath.floor(posY).toFloat() + (2f * parentActor.hitboxTranslateY * scale + parentActor.hitbox.height.toFloat()),
|
||||||
-FastMath.floor(cellWidth * scale).toFloat(),
|
-FastMath.floor(cellWidth * scale).toFloat(),
|
||||||
-FastMath.floor(cellHeight * scale).toFloat()
|
-FastMath.floor(cellHeight * scale).toFloat()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
else if (flipHorizontal) {
|
else if (flipHorizontal) {
|
||||||
batch.draw(region,
|
batch.draw(region,
|
||||||
FastMath.floor(posX).toFloat() + (2f * parentActor.hitboxTranslateX * parentActor.scale.toFloat() + parentActor.hitbox.width.toFloat()),
|
FastMath.floor(posX).toFloat() + (2f * parentActor.hitboxTranslateX * scale + scale * parentActor.hitbox.width.toFloat()),
|
||||||
FastMath.floor(posY).toFloat(),
|
FastMath.floor(posY).toFloat(),
|
||||||
-FastMath.floor(cellWidth * scale).toFloat(),
|
-FastMath.floor(cellWidth * scale).toFloat(),
|
||||||
FastMath.floor(cellHeight * scale).toFloat()
|
FastMath.floor(cellHeight * scale).toFloat()
|
||||||
@@ -149,7 +151,7 @@ class SpriteAnimation(@Transient val parentActor: ActorWBMovable) {
|
|||||||
else if (flipVertical) {
|
else if (flipVertical) {
|
||||||
batch.draw(region,
|
batch.draw(region,
|
||||||
FastMath.floor(posX).toFloat(),
|
FastMath.floor(posX).toFloat(),
|
||||||
FastMath.floor(posY).toFloat() + (2f * parentActor.hitboxTranslateY * parentActor.scale.toFloat() + parentActor.hitbox.height.toFloat()),
|
FastMath.floor(posY).toFloat() + (2f * parentActor.hitboxTranslateY * scale + parentActor.hitbox.height.toFloat()),
|
||||||
FastMath.floor(cellWidth * scale).toFloat(),
|
FastMath.floor(cellWidth * scale).toFloat(),
|
||||||
-FastMath.floor(cellHeight * scale).toFloat()
|
-FastMath.floor(cellHeight * scale).toFloat()
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -132,15 +132,15 @@ open class ActorWBMovable(renderOrder: RenderOrder, val immobileBody: Boolean =
|
|||||||
* Physical properties.
|
* Physical properties.
|
||||||
*/
|
*/
|
||||||
/** Apparent scale. Use "avBaseScale" for base scale */
|
/** Apparent scale. Use "avBaseScale" for base scale */
|
||||||
var scale: Double
|
val scale: Double
|
||||||
inline get() = (actorValue.getAsDouble(AVKey.SCALE) ?: 1.0) *
|
inline get() = (actorValue.getAsDouble(AVKey.SCALE) ?: 1.0) *
|
||||||
(actorValue.getAsDouble(AVKey.SCALEBUFF) ?: 1.0)
|
(actorValue.getAsDouble(AVKey.SCALEBUFF) ?: 1.0)
|
||||||
set(value) {
|
/*set(value) {
|
||||||
val scaleDelta = value - scale
|
val scaleDelta = value - scale
|
||||||
actorValue[AVKey.SCALE] = value / (actorValue.getAsDouble(AVKey.SCALEBUFF) ?: 1.0)
|
actorValue[AVKey.SCALE] = value / (actorValue.getAsDouble(AVKey.SCALEBUFF) ?: 1.0)
|
||||||
// reposition
|
// reposition
|
||||||
translatePosition(-baseHitboxW * scaleDelta / 2, -baseHitboxH * scaleDelta)
|
translatePosition(-baseHitboxW * scaleDelta / 2, -baseHitboxH * scaleDelta)
|
||||||
}
|
}*/
|
||||||
@Transient val MASS_LOWEST = 0.1 // Kilograms
|
@Transient val MASS_LOWEST = 0.1 // Kilograms
|
||||||
/** Apparent mass. Use "avBaseMass" for base mass */
|
/** Apparent mass. Use "avBaseMass" for base mass */
|
||||||
val mass: Double
|
val mass: Double
|
||||||
@@ -298,6 +298,8 @@ open class ActorWBMovable(renderOrder: RenderOrder, val immobileBody: Boolean =
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* ONLY FOR INITIAL SETUP
|
||||||
|
*
|
||||||
* @param w
|
* @param w
|
||||||
* @param h
|
* @param h
|
||||||
* @param tx positive: translate sprite to LEFT.
|
* @param tx positive: translate sprite to LEFT.
|
||||||
@@ -318,6 +320,8 @@ open class ActorWBMovable(renderOrder: RenderOrder, val immobileBody: Boolean =
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* ONLY FOR INITIAL SETUP
|
||||||
|
*
|
||||||
* Set hitbox position from bottom-center point
|
* Set hitbox position from bottom-center point
|
||||||
* @param x
|
* @param x
|
||||||
* @param y
|
* @param y
|
||||||
@@ -330,10 +334,6 @@ open class ActorWBMovable(renderOrder: RenderOrder, val immobileBody: Boolean =
|
|||||||
baseHitboxH * scale)
|
baseHitboxH * scale)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translatePosition(dx: Double, dy: Double) {
|
|
||||||
hitbox.translate(dx, dy)
|
|
||||||
}
|
|
||||||
|
|
||||||
// get() methods are moved to update(), too much stray object being created is definitely not good
|
// get() methods are moved to update(), too much stray object being created is definitely not good
|
||||||
val centrePosVector: Vector2 = Vector2(0.0,0.0)
|
val centrePosVector: Vector2 = Vector2(0.0,0.0)
|
||||||
//get() = Vector2(hitbox.centeredX, hitbox.centeredY)
|
//get() = Vector2(hitbox.centeredX, hitbox.centeredY)
|
||||||
@@ -363,6 +363,11 @@ open class ActorWBMovable(renderOrder: RenderOrder, val immobileBody: Boolean =
|
|||||||
|
|
||||||
override fun update(delta: Float) {
|
override fun update(delta: Float) {
|
||||||
|
|
||||||
|
// re-scale hitbox
|
||||||
|
// it's just much better to poll them than use perfectly-timed setter because latter simply cannot exist
|
||||||
|
hitbox.canonicalResize(baseHitboxW * scale, baseHitboxH * scale)
|
||||||
|
|
||||||
|
|
||||||
val oldHitbox = hitbox.clone()
|
val oldHitbox = hitbox.clone()
|
||||||
|
|
||||||
if (isUpdate && !flagDespawn) {
|
if (isUpdate && !flagDespawn) {
|
||||||
|
|||||||
@@ -33,9 +33,21 @@ class Hitbox (x1: Double, y1: Double, width: Double, height: Double, var suppres
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
|
||||||
return "[$hitboxStart - $hitboxEnd]"
|
val startX: Double
|
||||||
}
|
get() = hitboxStart.x
|
||||||
|
val startY: Double
|
||||||
|
get() = hitboxStart.y
|
||||||
|
|
||||||
|
val endX: Double
|
||||||
|
get() = hitboxStart.x + width
|
||||||
|
val endY: Double
|
||||||
|
get() = hitboxStart.y + height
|
||||||
|
|
||||||
|
val centeredX: Double
|
||||||
|
get() = hitboxStart.x + width * 0.5
|
||||||
|
val centeredY: Double
|
||||||
|
get() = hitboxStart.y + height * 0.5
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return bottom-centered point of hitbox.
|
* @return bottom-centered point of hitbox.
|
||||||
@@ -49,11 +61,6 @@ class Hitbox (x1: Double, y1: Double, width: Double, height: Double, var suppres
|
|||||||
inline val canonicalY: Double
|
inline val canonicalY: Double
|
||||||
get() = endY
|
get() = endY
|
||||||
|
|
||||||
val endX: Double
|
|
||||||
get() = hitboxStart.x + width
|
|
||||||
val endY: Double
|
|
||||||
get() = hitboxStart.y + height
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set to the point top left
|
* Set to the point top left
|
||||||
* @param x1
|
* @param x1
|
||||||
@@ -111,34 +118,31 @@ class Hitbox (x1: Double, y1: Double, width: Double, height: Double, var suppres
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For initial setup only. Use CanonicalResize for graceful resizing
|
||||||
|
*/
|
||||||
fun setDimension(w: Double, h: Double): Hitbox {
|
fun setDimension(w: Double, h: Double): Hitbox {
|
||||||
width = w
|
width = w
|
||||||
height = h
|
height = h
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun canonicalResize(w: Double, h: Double): Hitbox {
|
||||||
|
// sx_1 + 0.5w_1 = sx_2 + 0.5w_2 // equals because the final point must not move. sx_1: old start-x, sx_2: new start-x which is what we want
|
||||||
|
// sx_2 = sx_1 + 0.5w_1 - 0.5w_2 // move variables to right-hand side to derive final value sx_2
|
||||||
|
|
||||||
|
hitboxStart.set(
|
||||||
|
startX + 0.5 * width - 0.5 * w,
|
||||||
|
startY + height - h
|
||||||
|
)
|
||||||
|
width = w
|
||||||
|
height = h
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
fun containsPoint(x: Double, y: Double) = (hitboxStart.x - x) in 0.0..width && (hitboxStart.y - y) in 0.0..height
|
fun containsPoint(x: Double, y: Double) = (hitboxStart.x - x) in 0.0..width && (hitboxStart.y - y) in 0.0..height
|
||||||
fun containsPoint(p: Point2d) = containsPoint(p.x, p.y)
|
fun containsPoint(p: Point2d) = containsPoint(p.x, p.y)
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns x value of start point
|
|
||||||
* @return top-left point startX
|
|
||||||
*/
|
|
||||||
val startX: Double
|
|
||||||
get() = hitboxStart.x
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns y value of start point
|
|
||||||
* @return top-left point startY
|
|
||||||
*/
|
|
||||||
val startY: Double
|
|
||||||
get() = hitboxStart.y
|
|
||||||
|
|
||||||
val centeredX: Double
|
|
||||||
get() = hitboxStart.x + width * 0.5
|
|
||||||
|
|
||||||
val centeredY: Double
|
|
||||||
get() = hitboxStart.y + height * 0.5
|
|
||||||
|
|
||||||
infix fun intersects(position: Point2d) =
|
infix fun intersects(position: Point2d) =
|
||||||
(position.x >= startX && position.x <= startX + width) &&
|
(position.x >= startX && position.x <= startX + width) &&
|
||||||
@@ -162,4 +166,8 @@ class Hitbox (x1: Double, y1: Double, width: Double, height: Double, var suppres
|
|||||||
this.width == other.width &&
|
this.width == other.width &&
|
||||||
this.height == other.height
|
this.height == other.height
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return "[$hitboxStart - $hitboxEnd]"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import net.torvald.terrarum.Terrarum
|
|||||||
import net.torvald.terrarum.console.ConsoleCommand
|
import net.torvald.terrarum.console.ConsoleCommand
|
||||||
import net.torvald.terrarum.console.Echo
|
import net.torvald.terrarum.console.Echo
|
||||||
import net.torvald.terrarum.console.EchoError
|
import net.torvald.terrarum.console.EchoError
|
||||||
|
import net.torvald.terrarum.gameactors.AVKey
|
||||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||||
import net.torvald.terrarum.gameactors.ActorWBMovable
|
import net.torvald.terrarum.gameactors.ActorWBMovable
|
||||||
|
|
||||||
@@ -27,7 +28,8 @@ internal object SetScale : ConsoleCommand {
|
|||||||
EchoError("Target is not ActorWBMovable")
|
EchoError("Target is not ActorWBMovable")
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
target.scale = scale
|
target.actorValue[AVKey.SCALE] = scale
|
||||||
|
//target.scale = scale
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (e: NumberFormatException) {
|
catch (e: NumberFormatException) {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package net.torvald.terrarum.modulebasegame.gameactors
|
|||||||
|
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
import net.torvald.terrarum.blockproperties.BlockCodex
|
import net.torvald.terrarum.blockproperties.BlockCodex
|
||||||
|
import net.torvald.terrarum.gameactors.AVKey
|
||||||
import net.torvald.terrarum.gameactors.ActorWBMovable
|
import net.torvald.terrarum.gameactors.ActorWBMovable
|
||||||
import net.torvald.terrarum.gameitem.GameItem
|
import net.torvald.terrarum.gameitem.GameItem
|
||||||
import net.torvald.terrarum.itemproperties.ItemCodex
|
import net.torvald.terrarum.itemproperties.ItemCodex
|
||||||
@@ -22,7 +23,7 @@ open class DroppedItem(private val item: GameItem) : ActorWBMovable(RenderOrder.
|
|||||||
else
|
else
|
||||||
ItemCodex[item.dynamicID]!!.mass
|
ItemCodex[item.dynamicID]!!.mass
|
||||||
|
|
||||||
scale = ItemCodex[item.dynamicID]!!.scale
|
actorValue[AVKey.SCALE] = ItemCodex[item.dynamicID]!!.scale
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun update(delta: Float) {
|
override fun update(delta: Float) {
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ object PlayerBuilderTestSubject1 {
|
|||||||
//p.actorValue[AVKey.LUMA] = 1.93
|
//p.actorValue[AVKey.LUMA] = 1.93
|
||||||
|
|
||||||
p.actorValue[AVKey.AIRJUMPPOINT] = 0
|
p.actorValue[AVKey.AIRJUMPPOINT] = 0
|
||||||
|
p.actorValue[AVKey.SCALE] = 2.0
|
||||||
|
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user