mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-18 14:34:04 +09:00
actorwithbody splitted in favour of new particle type
Former-commit-id: 121bd069d0a9eeef60f5ecb085a11a93c4b4a84d Former-commit-id: 539b4b6916e808c01298190cf347e928f61fe62e
This commit is contained in:
@@ -64,4 +64,9 @@ abstract class Actor(val renderOrder: ActorOrder) : Comparable<Actor>, Runnable
|
||||
|
||||
}
|
||||
|
||||
enum class ActorOrder { BEHIND, MIDDLE, MIDTOP, FRONT }
|
||||
enum class ActorOrder {
|
||||
BEHIND, // tapestries, some particles (obstructed by terrain)
|
||||
MIDDLE, // actors
|
||||
MIDTOP, // bullets, thrown items
|
||||
FRONT // fake tiles
|
||||
}
|
||||
@@ -361,7 +361,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
|
||||
* this code base, ACCELERATION must be changed (in other words, we must deal with JERK) accordingly
|
||||
* to the FRICTION.
|
||||
*
|
||||
* So I'm adding walkX/Y and getting the ActorWithBody.setNewNextHitbox to use the velocity value of
|
||||
* So I'm adding walkX/Y and getting the ActorWithSprite.setNewNextHitbox to use the velocity value of
|
||||
* walkX/Y + velocity, which is stored in variable moveDelta.
|
||||
*
|
||||
* Be warned.
|
||||
|
||||
14
src/net/torvald/terrarum/gameactors/ActorVisible.kt
Normal file
14
src/net/torvald/terrarum/gameactors/ActorVisible.kt
Normal file
@@ -0,0 +1,14 @@
|
||||
package net.torvald.terrarum.gameactors
|
||||
|
||||
import org.newdawn.slick.GameContainer
|
||||
import org.newdawn.slick.Graphics
|
||||
|
||||
/**
|
||||
* Created by SKYHi14 on 2017-01-21.
|
||||
*/
|
||||
abstract class ActorVisible(renderOrder: ActorOrder) : Actor(renderOrder) {
|
||||
open val hitbox = Hitbox(0.0, 0.0, 0.0, 0.0)
|
||||
override abstract fun update(gc: GameContainer, delta: Int)
|
||||
abstract fun drawBody(g: Graphics)
|
||||
abstract fun drawGlow(g: Graphics)
|
||||
}
|
||||
@@ -7,21 +7,29 @@ import net.torvald.terrarum.gameworld.GameWorld
|
||||
import net.torvald.terrarum.mapdrawer.FeaturesDrawer
|
||||
import net.torvald.terrarum.tileproperties.TileCodex
|
||||
import net.torvald.spriteanimation.SpriteAnimation
|
||||
import net.torvald.terrarum.gamecontroller.Key
|
||||
import net.torvald.terrarum.gamecontroller.KeyToggler
|
||||
import net.torvald.terrarum.mapdrawer.FeaturesDrawer.TILE_SIZE
|
||||
import net.torvald.terrarum.tileproperties.Tile
|
||||
import net.torvald.terrarum.tileproperties.TileProp
|
||||
import org.dyn4j.Epsilon
|
||||
import org.dyn4j.geometry.Vector2
|
||||
import org.newdawn.slick.Color
|
||||
import org.newdawn.slick.GameContainer
|
||||
import org.newdawn.slick.Graphics
|
||||
import org.newdawn.slick.Image
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Base class for every actor that has physical (or echo) body. This includes furnishings, paintings, gadgets, etc.
|
||||
* Base class for every actor that has animated sprites. This includes furnishings, paintings, gadgets, etc.
|
||||
* Also has all the physics
|
||||
*
|
||||
* @param renderOrder Rendering order (BEHIND, MIDDLE, MIDTOP, FRONT)
|
||||
* @param physics
|
||||
*
|
||||
* Created by minjaesong on 16-01-13.
|
||||
*/
|
||||
open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) {
|
||||
open class ActorWithSprite(renderOrder: ActorOrder, physics: Boolean = true) : ActorVisible(renderOrder) {
|
||||
|
||||
/** !! ActorValue macros are on the very bottom of the source !! **/
|
||||
|
||||
@@ -38,14 +46,12 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) {
|
||||
protected var hitboxTranslateY: Double = 0.0// relative to spritePosY
|
||||
protected var baseHitboxW: Int = 0
|
||||
protected var baseHitboxH: Int = 0
|
||||
protected var baseSpriteWidth: Int = 0
|
||||
protected var baseSpriteHeight: Int = 0
|
||||
/**
|
||||
* * Position: top-left point
|
||||
* * Unit: pixel
|
||||
* !! external class should not hitbox.set(); use setHitboxDimension() and setPosition()
|
||||
*/
|
||||
val hitbox = Hitbox(0.0, 0.0, 0.0, 0.0) // Hitbox is implemented using Double;
|
||||
override val hitbox = Hitbox(0.0, 0.0, 0.0, 0.0) // Hitbox is implemented using Double;
|
||||
@Transient val nextHitbox = Hitbox(0.0, 0.0, 0.0, 0.0) // 52 mantissas ought to be enough for anybody...
|
||||
|
||||
val tilewiseHitbox: Hitbox
|
||||
@@ -100,7 +106,10 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) {
|
||||
get() = (actorValue.getAsDouble(AVKey.SCALE) ?: 1.0) *
|
||||
(actorValue.getAsDouble(AVKey.SCALEBUFF) ?: 1.0)
|
||||
set(value) {
|
||||
val scaleDelta = value - scale
|
||||
actorValue[AVKey.SCALE] = value / (actorValue.getAsDouble(AVKey.SCALEBUFF) ?: 1.0)
|
||||
// reposition
|
||||
translatePosition(-baseHitboxW * scaleDelta / 2, -baseHitboxH * scaleDelta)
|
||||
}
|
||||
@Transient val MASS_LOWEST = 0.1 // Kilograms
|
||||
/** Apparent mass. Use "avBaseMass" for base mass */
|
||||
@@ -110,7 +119,7 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) {
|
||||
if (value <= 0)
|
||||
throw IllegalArgumentException("mass cannot be less than or equal to zero.")
|
||||
else if (value < MASS_LOWEST) {
|
||||
println("[ActorWithBody] input too small; using $MASS_LOWEST instead.")
|
||||
println("[ActorWithSprite] input too small; using $MASS_LOWEST instead.")
|
||||
actorValue[AVKey.BASEMASS] = MASS_LOWEST
|
||||
}
|
||||
|
||||
@@ -123,7 +132,7 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) {
|
||||
if (value < 0)
|
||||
throw IllegalArgumentException("invalid elasticity value $value; valid elasticity value is [0, 1].")
|
||||
else if (value >= ELASTICITY_MAX) {
|
||||
println("[ActorWithBody] Elasticity were capped to $ELASTICITY_MAX.")
|
||||
println("[ActorWithSprite] Elasticity were capped to $ELASTICITY_MAX.")
|
||||
field = ELASTICITY_MAX
|
||||
}
|
||||
else
|
||||
@@ -149,7 +158,7 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) {
|
||||
var density = 1000.0
|
||||
set(value) {
|
||||
if (value < 0)
|
||||
throw IllegalArgumentException("[ActorWithBody] $value: density cannot be negative.")
|
||||
throw IllegalArgumentException("[ActorWithSprite] $value: density cannot be negative.")
|
||||
|
||||
field = value
|
||||
}
|
||||
@@ -164,7 +173,7 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) {
|
||||
/** Default to 'true' */
|
||||
var isVisible = true
|
||||
/** Default to 'true' */
|
||||
var isUpdate = true
|
||||
var isUpdate = physics
|
||||
var isNoSubjectToGrav = false
|
||||
var isNoCollideWorld = false
|
||||
var isNoSubjectToFluidResistance = false
|
||||
@@ -177,19 +186,6 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) {
|
||||
*/
|
||||
@Volatile var isChronostasis = false
|
||||
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
|
||||
@Transient private val METER = 24.0
|
||||
/**
|
||||
* [m / s^2] * SI_TO_GAME_ACC -> [px / InternalFrame^2]
|
||||
*/
|
||||
@Transient private val SI_TO_GAME_ACC = METER / (Terrarum.TARGET_FPS * Terrarum.TARGET_FPS).toDouble()
|
||||
/**
|
||||
* [m / s] * SI_TO_GAME_VEL -> [px / InternalFrame]
|
||||
*/
|
||||
@Transient private val SI_TO_GAME_VEL = METER / Terrarum.TARGET_FPS
|
||||
/**
|
||||
* Gravitational Constant G. Load from gameworld.
|
||||
* [m / s^2]
|
||||
@@ -203,7 +199,7 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) {
|
||||
get() = actorValue.getAsDouble(AVKey.DRAGCOEFF) ?: DRAG_COEFF_DEFAULT
|
||||
set(value) {
|
||||
if (value < 0)
|
||||
throw IllegalArgumentException("[ActorWithBody] drag coefficient cannot be negative.")
|
||||
throw IllegalArgumentException("[ActorWithSprite] drag coefficient cannot be negative.")
|
||||
actorValue[AVKey.DRAGCOEFF] = value
|
||||
}
|
||||
|
||||
@@ -260,23 +256,33 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) {
|
||||
// some initialiser goes here...
|
||||
}
|
||||
|
||||
fun makeNewSprite(w: Int, h: Int) {
|
||||
sprite = SpriteAnimation(this)
|
||||
sprite!!.setDimension(w, h)
|
||||
fun makeNewSprite(w: Int, h: Int, image: Image) {
|
||||
sprite = SpriteAnimation(this, w, h)
|
||||
sprite!!.setSpriteImage(image)
|
||||
}
|
||||
|
||||
fun makeNewSpriteGlow(w: Int, h: Int) {
|
||||
spriteGlow = SpriteAnimation(this)
|
||||
spriteGlow!!.setDimension(w, h)
|
||||
fun makeNewSprite(w: Int, h: Int, imageref: String) {
|
||||
sprite = SpriteAnimation(this, w, h)
|
||||
sprite!!.setSpriteImage(imageref)
|
||||
}
|
||||
|
||||
fun makeNewSpriteGlow(w: Int, h: Int, image: Image) {
|
||||
spriteGlow = SpriteAnimation(this, w, h)
|
||||
spriteGlow!!.setSpriteImage(image)
|
||||
}
|
||||
|
||||
fun makeNewSpriteGlow(w: Int, h: Int, imageref: String) {
|
||||
spriteGlow = SpriteAnimation(this, w, h)
|
||||
spriteGlow!!.setSpriteImage(imageref)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param w
|
||||
* @param h
|
||||
* @param tx positive: translate drawn sprite to LEFT.
|
||||
* @param ty positive: translate drawn sprite to DOWN.
|
||||
* @see ActorWithBody.drawBody
|
||||
* @see ActorWithBody.drawGlow
|
||||
* @param tx positive: translate sprite to LEFT.
|
||||
* @param ty positive: translate sprite to DOWN.
|
||||
* @see ActorWithSprite.drawBody
|
||||
* @see ActorWithSprite.drawGlow
|
||||
*/
|
||||
fun setHitboxDimension(w: Int, h: Int, tx: Int, ty: Int) {
|
||||
baseHitboxH = h
|
||||
@@ -296,18 +302,23 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) {
|
||||
*/
|
||||
fun setPosition(x: Double, y: Double) {
|
||||
hitbox.setFromWidthHeight(
|
||||
x - (baseHitboxW / 2 - hitboxTranslateX) * (1 - scale),
|
||||
y - (baseHitboxH - hitboxTranslateY) * (1 - scale),
|
||||
x - (baseHitboxW / 2 - hitboxTranslateX) * scale,
|
||||
y - (baseHitboxH - hitboxTranslateY) * scale,
|
||||
baseHitboxW * scale,
|
||||
baseHitboxH * scale)
|
||||
|
||||
nextHitbox.setFromWidthHeight(
|
||||
x - (baseHitboxW / 2 - hitboxTranslateX) * (1 - scale),
|
||||
y - (baseHitboxH - hitboxTranslateY) * (1 - scale),
|
||||
x - (baseHitboxW / 2 - hitboxTranslateX) * scale,
|
||||
y - (baseHitboxH - hitboxTranslateY) * scale,
|
||||
baseHitboxW * scale,
|
||||
baseHitboxH * scale)
|
||||
}
|
||||
|
||||
private fun translatePosition(dx: Double, dy: Double) {
|
||||
hitbox.translate(dx, dy)
|
||||
nextHitbox.translate(dx, dy)
|
||||
}
|
||||
|
||||
val centrePosVector: Vector2
|
||||
get() = Vector2(hitbox.centeredX, hitbox.centeredY)
|
||||
val centrePosPoint: Point2d
|
||||
@@ -344,12 +355,6 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) {
|
||||
isNoSubjectToFluidResistance = isPlayerNoClip
|
||||
}
|
||||
|
||||
// set sprite dimension vars if there IS sprite for the actor
|
||||
if (sprite != null) {
|
||||
baseSpriteHeight = sprite!!.height
|
||||
baseSpriteWidth = sprite!!.width
|
||||
}
|
||||
|
||||
/**
|
||||
* Actual physics thing (altering velocity) starts from here
|
||||
*/
|
||||
@@ -987,50 +992,64 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) {
|
||||
|
||||
private fun updateHitbox() = hitbox.reassign(nextHitbox)
|
||||
|
||||
open fun drawGlow(g: Graphics) {
|
||||
override open fun drawGlow(g: Graphics) {
|
||||
if (isVisible && spriteGlow != null) {
|
||||
blendLightenOnly()
|
||||
|
||||
if (!sprite!!.flippedHorizontal()) {
|
||||
spriteGlow!!.render(g,
|
||||
(hitbox.posX - hitboxTranslateX * scale).toFloat(),
|
||||
(hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(),
|
||||
(hitbox.posY + hitboxTranslateY * scale).toFloat(),
|
||||
(scale).toFloat()
|
||||
)
|
||||
// Q&D fix for Roundworld anomaly
|
||||
spriteGlow!!.render(g,
|
||||
(hitbox.posX - hitboxTranslateX * scale).toFloat() + world.width * TILE_SIZE,
|
||||
(hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(),
|
||||
(hitbox.posY + hitboxTranslateY * scale).toFloat(),
|
||||
(scale).toFloat()
|
||||
)
|
||||
spriteGlow!!.render(g,
|
||||
(hitbox.posX - hitboxTranslateX * scale).toFloat() - world.width * TILE_SIZE,
|
||||
(hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(),
|
||||
(hitbox.posY + hitboxTranslateY * scale).toFloat(),
|
||||
(scale).toFloat()
|
||||
)
|
||||
}
|
||||
else {
|
||||
spriteGlow!!.render(g,
|
||||
(hitbox.posX - scale).toFloat(),
|
||||
(hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(),
|
||||
(hitbox.posY + hitboxTranslateY * scale).toFloat(),
|
||||
(scale).toFloat()
|
||||
)
|
||||
// Q&D fix for Roundworld anomaly
|
||||
spriteGlow!!.render(g,
|
||||
(hitbox.posX - scale).toFloat() + world.width * TILE_SIZE,
|
||||
(hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(),
|
||||
(hitbox.posY + hitboxTranslateY * scale).toFloat(),
|
||||
(scale).toFloat()
|
||||
)
|
||||
spriteGlow!!.render(g,
|
||||
(hitbox.posX - scale).toFloat() - world.width * TILE_SIZE,
|
||||
(hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(),
|
||||
(hitbox.posY + hitboxTranslateY * scale).toFloat(),
|
||||
(scale).toFloat()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// debug hitbox
|
||||
if (KeyToggler.isOn(Key.F11)) {
|
||||
g.color = Color(1f, 0f, 1f, 1f)
|
||||
blendNormal()
|
||||
g.lineWidth = 1f
|
||||
g.drawRect(
|
||||
hitbox.posX.toFloat(),
|
||||
hitbox.posY.toFloat(),
|
||||
hitbox.width.toFloat(),
|
||||
hitbox.height.toFloat()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
open fun drawBody(g: Graphics) {
|
||||
override open fun drawBody(g: Graphics) {
|
||||
if (isVisible && sprite != null) {
|
||||
|
||||
|
||||
@@ -1043,36 +1062,36 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) {
|
||||
if (!sprite!!.flippedHorizontal()) {
|
||||
sprite!!.render(g,
|
||||
(hitbox.posX - hitboxTranslateX * scale).toFloat(),
|
||||
(hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(),
|
||||
(hitbox.posY + hitboxTranslateY * scale).toFloat(),
|
||||
(scale).toFloat()
|
||||
)
|
||||
// Q&D fix for Roundworld anomaly
|
||||
sprite!!.render(g,
|
||||
(hitbox.posX - hitboxTranslateX * scale).toFloat() + world.width * TILE_SIZE,
|
||||
(hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(),
|
||||
(hitbox.posY + hitboxTranslateY * scale).toFloat(),
|
||||
(scale).toFloat()
|
||||
)
|
||||
sprite!!.render(g,
|
||||
(hitbox.posX - hitboxTranslateX * scale).toFloat() - world.width * TILE_SIZE,
|
||||
(hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(),
|
||||
(hitbox.posY + hitboxTranslateY * scale).toFloat(),
|
||||
(scale).toFloat()
|
||||
)
|
||||
}
|
||||
else {
|
||||
sprite!!.render(g,
|
||||
(hitbox.posX - scale).toFloat(),
|
||||
(hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(),
|
||||
(hitbox.posY + hitboxTranslateY * scale).toFloat(),
|
||||
(scale).toFloat()
|
||||
)
|
||||
// Q&D fix for Roundworld anomaly
|
||||
sprite!!.render(g,
|
||||
(hitbox.posX - scale).toFloat() + world.width * TILE_SIZE,
|
||||
(hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(),
|
||||
(hitbox.posY + hitboxTranslateY * scale).toFloat(),
|
||||
(scale).toFloat()
|
||||
)
|
||||
sprite!!.render(g,
|
||||
(hitbox.posX - scale).toFloat() - world.width * TILE_SIZE,
|
||||
(hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(),
|
||||
(hitbox.posY + hitboxTranslateY * scale).toFloat(),
|
||||
(scale).toFloat()
|
||||
)
|
||||
}
|
||||
@@ -1129,9 +1148,9 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) {
|
||||
|
||||
// warnings
|
||||
if (sprite == null && isVisible)
|
||||
println("[ActorWithBody] Caution: actor ${this.javaClass.simpleName} is echo but the sprite was not set.")
|
||||
println("[ActorWithSprite] Caution: actor ${this.javaClass.simpleName} is echo but the sprite was not set.")
|
||||
else if (sprite != null && !isVisible)
|
||||
println("[ActorWithBody] Caution: actor ${this.javaClass.simpleName} is invisible but the sprite was given.")
|
||||
println("[ActorWithSprite] Caution: actor ${this.javaClass.simpleName} is invisible but the sprite was given.")
|
||||
|
||||
assertPrinted = true
|
||||
}
|
||||
@@ -1190,13 +1209,30 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) {
|
||||
|
||||
companion object {
|
||||
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
|
||||
@Transient private val METER = 24.0
|
||||
/**
|
||||
* [m / s^2] * SI_TO_GAME_ACC -> [px / InternalFrame^2]
|
||||
*/
|
||||
@Transient val SI_TO_GAME_ACC = METER / (Terrarum.TARGET_FPS * Terrarum.TARGET_FPS).toDouble()
|
||||
/**
|
||||
* [m / s] * SI_TO_GAME_VEL -> [px / InternalFrame]
|
||||
*/
|
||||
@Transient val SI_TO_GAME_VEL = METER / Terrarum.TARGET_FPS
|
||||
|
||||
/**
|
||||
* Enumerations that exported to JSON
|
||||
*/
|
||||
@Transient const val COLLISION_NOCOLLIDE = 0
|
||||
@Transient const val COLLISION_KINEMATIC = 1 // does not displaced by external forces when collided, but it still can move (e.g. player, elevator)
|
||||
@Transient const val COLLISION_DYNAMIC = 2 // displaced by external forces
|
||||
@Transient const val COLLISION_STATIC = 3 // does not displaced by external forces, target of collision (e.g. nonmoving static obj)
|
||||
/** does not displaced by external forces when collided, but it still can move (e.g. player, elevator) */
|
||||
@Transient const val COLLISION_KINEMATIC = 1
|
||||
/** displaced by external forces */
|
||||
@Transient const val COLLISION_DYNAMIC = 2
|
||||
/** does not displaced by external forces, target of collision (e.g. nonmoving static obj) */
|
||||
@Transient const val COLLISION_STATIC = 3
|
||||
@Transient const val COLLISION_KNOCKBACK_GIVER = 4 // mobs
|
||||
@Transient const val COLLISION_KNOCKBACK_TAKER = 5 // benevolent NPCs
|
||||
@Transient const val BLEND_NORMAL = 4
|
||||
@@ -18,8 +18,8 @@ object CreatureBuilder {
|
||||
* @Param jsonFileName with extension
|
||||
*/
|
||||
@Throws(IOException::class, SlickException::class)
|
||||
operator fun invoke(jsonFileName: String): ActorWithBody {
|
||||
val actor = ActorWithBody(ActorOrder.MIDDLE)
|
||||
operator fun invoke(jsonFileName: String): ActorWithSprite {
|
||||
val actor = ActorWithSprite(ActorOrder.MIDDLE)
|
||||
InjectCreatureRaw(actor.actorValue, jsonFileName)
|
||||
|
||||
return actor
|
||||
|
||||
@@ -9,7 +9,7 @@ import org.newdawn.slick.Graphics
|
||||
/**
|
||||
* Created by minjaesong on 16-03-15.
|
||||
*/
|
||||
class DroppedItem(private val item: InventoryItem) : ActorWithBody(ActorOrder.MIDTOP) {
|
||||
class DroppedItem(private val item: InventoryItem) : ActorWithSprite(ActorOrder.MIDTOP) {
|
||||
|
||||
init {
|
||||
if (item.id >= ItemCodex.ITEM_COUNT_MAX)
|
||||
|
||||
@@ -5,7 +5,7 @@ import net.torvald.spriteanimation.SpriteAnimation
|
||||
/**
|
||||
* Created by minjaesong on 16-06-17.
|
||||
*/
|
||||
open class FixtureBase : ActorWithBody(ActorOrder.BEHIND) {
|
||||
open class FixtureBase(physics: Boolean = true) : ActorWithSprite(ActorOrder.BEHIND, physics) {
|
||||
/**
|
||||
* 0: Open
|
||||
* 1: Blocked
|
||||
|
||||
@@ -25,8 +25,7 @@ class FixtureTikiTorch : FixtureBase(), Luminous {
|
||||
lightBoxList = ArrayList(1)
|
||||
lightBoxList.add(Hitbox(3.0, 0.0, 4.0, 3.0))
|
||||
|
||||
makeNewSprite(10, 27)
|
||||
sprite!!.setSpriteImage("assets/graphics/sprites/fixtures/tiki_torch.tga")
|
||||
makeNewSprite(10, 27, "assets/graphics/sprites/fixtures/tiki_torch.tga")
|
||||
sprite!!.setDelay(200)
|
||||
sprite!!.setRowsAndFrames(1, 1)
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import org.newdawn.slick.Input
|
||||
*
|
||||
* Created by minjaesong on 16-10-10.
|
||||
*/
|
||||
open class HistoricalFigure(val born: GameDate, val dead: GameDate? = null) : ActorWithBody(ActorOrder.MIDDLE) {
|
||||
open class HistoricalFigure(val born: GameDate, val dead: GameDate? = null) : ActorWithSprite(ActorOrder.MIDDLE) {
|
||||
|
||||
init {
|
||||
this.actorValue["_bornyear"] = born.year
|
||||
|
||||
@@ -31,7 +31,7 @@ open class HumanoidNPC(override val scriptPath: String, born: GameDate) : ActorH
|
||||
private val aiLuaAPI: AILuaAPI
|
||||
|
||||
companion object {
|
||||
val DEFAULT_COLLISION_TYPE = ActorWithBody.COLLISION_DYNAMIC
|
||||
val DEFAULT_COLLISION_TYPE = ActorWithSprite.COLLISION_DYNAMIC
|
||||
}
|
||||
|
||||
init {
|
||||
|
||||
68
src/net/torvald/terrarum/gameactors/ParticleBase.kt
Normal file
68
src/net/torvald/terrarum/gameactors/ParticleBase.kt
Normal file
@@ -0,0 +1,68 @@
|
||||
package net.torvald.terrarum.gameactors
|
||||
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.gameactors.ActorWithSprite.Companion.SI_TO_GAME_ACC
|
||||
import net.torvald.terrarum.mapdrawer.FeaturesDrawer.TILE_SIZE
|
||||
import net.torvald.terrarum.tileproperties.Tile
|
||||
import net.torvald.terrarum.tileproperties.TileCodex
|
||||
import org.dyn4j.geometry.Vector2
|
||||
import org.newdawn.slick.GameContainer
|
||||
import org.newdawn.slick.Graphics
|
||||
import org.newdawn.slick.Image
|
||||
|
||||
/**
|
||||
* Actors with static sprites and very simple physics
|
||||
*
|
||||
* Created by SKYHi14 on 2017-01-20.
|
||||
*/
|
||||
open class ParticleBase(renderOrder: ActorOrder, maxLifeTime: Int? = null) : ActorVisible(renderOrder), Projectile {
|
||||
|
||||
override var actorValue = ActorValue()
|
||||
override @Volatile var flagDespawn = false
|
||||
|
||||
override fun run() {
|
||||
TODO("not implemented")
|
||||
}
|
||||
|
||||
var isNoSubjectToGrav = false
|
||||
var dragCoefficient = 3.0
|
||||
|
||||
private val lifetimeMax = maxLifeTime ?: 5000
|
||||
private var lifetimeCounter = 0
|
||||
|
||||
open val velocity = Vector2(0.0, 0.0)
|
||||
|
||||
open lateinit var image: Image
|
||||
|
||||
init {
|
||||
|
||||
}
|
||||
|
||||
override fun update(gc: GameContainer, delta: Int) {
|
||||
lifetimeCounter += delta
|
||||
if (velocity.isZero || lifetimeCounter >= lifetimeMax ||
|
||||
// simple stuck check
|
||||
TileCodex[Terrarum.ingame.world.getTileFromTerrain(
|
||||
hitbox.pointedX.div(TILE_SIZE).floorInt(),
|
||||
hitbox.pointedY.div(TILE_SIZE).floorInt()
|
||||
) ?: Tile.STONE].isSolid) {
|
||||
flagDespawn = true
|
||||
}
|
||||
|
||||
// gravity, winds, etc. (external forces)
|
||||
if (!isNoSubjectToGrav) {
|
||||
velocity += Terrarum.ingame.world.gravitation / dragCoefficient * SI_TO_GAME_ACC
|
||||
}
|
||||
|
||||
|
||||
// combine external forces
|
||||
hitbox.translate(velocity)
|
||||
}
|
||||
|
||||
override fun drawBody(g: Graphics) {
|
||||
g.drawImage(image, hitbox.centeredX.toFloat(), hitbox.centeredY.toFloat())
|
||||
}
|
||||
|
||||
override fun drawGlow(g: Graphics) {
|
||||
}
|
||||
}
|
||||
24
src/net/torvald/terrarum/gameactors/ParticleTestRain.kt
Normal file
24
src/net/torvald/terrarum/gameactors/ParticleTestRain.kt
Normal file
@@ -0,0 +1,24 @@
|
||||
package net.torvald.terrarum.gameactors
|
||||
|
||||
import org.dyn4j.geometry.Vector2
|
||||
import org.newdawn.slick.Image
|
||||
|
||||
/**
|
||||
* Created by SKYHi14 on 2017-01-20.
|
||||
*/
|
||||
class ParticleTestRain(posX: Double, posY: Double) : ParticleBase(ActorOrder.BEHIND, 6000) {
|
||||
|
||||
init {
|
||||
image = Image("./assets/graphics/weathers/raindrop.tga")
|
||||
val w = image.width.toDouble()
|
||||
val h = image.height.toDouble()
|
||||
hitbox.setFromWidthHeight(
|
||||
posX - w.times(0.5),
|
||||
posY - h.times(0.5),
|
||||
w, h
|
||||
)
|
||||
|
||||
velocity.y = 16.0
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,7 +10,7 @@ import org.newdawn.slick.Graphics
|
||||
/**
|
||||
* Created by minjaesong on 16-03-05.
|
||||
*/
|
||||
class PhysTestBall : ActorWithBody(ActorOrder.MIDDLE) {
|
||||
class PhysTestBall : ActorWithSprite(ActorOrder.MIDDLE) {
|
||||
|
||||
private var color = Color.orange
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import net.torvald.terrarum.mapdrawer.FeaturesDrawer
|
||||
*/
|
||||
object PlayerBuilderCynthia {
|
||||
|
||||
operator fun invoke(): ActorWithBody {
|
||||
operator fun invoke(): ActorWithSprite {
|
||||
//val p: Player = Player(GameDate(100, 143)) // random value thrown
|
||||
val p: HumanoidNPC = HumanoidNPC("/net/torvald/terrarum/gameactors/ai/scripts/PokemonNPCAI.lua",
|
||||
GameDate(100, 143)) // random value thrown
|
||||
@@ -19,8 +19,7 @@ object PlayerBuilderCynthia {
|
||||
p.actorValue[AVKey.NAME] = "Cynthia"
|
||||
|
||||
|
||||
p.makeNewSprite(26, 42)
|
||||
p.sprite!!.setSpriteImage("assets/graphics/sprites/test_player_2.tga")
|
||||
p.makeNewSprite(26, 42, "assets/graphics/sprites/test_player_2.tga")
|
||||
p.sprite!!.setDelay(200)
|
||||
p.sprite!!.setRowsAndFrames(1, 1)
|
||||
|
||||
|
||||
@@ -26,13 +26,11 @@ object PlayerBuilderSigrid {
|
||||
|
||||
p.referenceID = 0x51621D // the only constant of this procedural universe
|
||||
|
||||
p.makeNewSprite(28, 51)
|
||||
p.sprite!!.setSpriteImage("assets/graphics/sprites/test_player.tga")
|
||||
p.makeNewSprite(28, 51, "assets/graphics/sprites/test_player.tga")
|
||||
p.sprite!!.setDelay(200)
|
||||
p.sprite!!.setRowsAndFrames(1, 1)
|
||||
|
||||
p.makeNewSpriteGlow(28, 51)
|
||||
p.spriteGlow!!.setSpriteImage("assets/graphics/sprites/test_player_glow.tga")
|
||||
p.makeNewSpriteGlow(28, 51, "assets/graphics/sprites/test_player_glow.tga")
|
||||
p.spriteGlow!!.setDelay(200)
|
||||
p.spriteGlow!!.setRowsAndFrames(1, 1)
|
||||
|
||||
@@ -66,7 +64,7 @@ object PlayerBuilderSigrid {
|
||||
//p.actorValue["__selectedtile"] = 147 // test code; replace with <tile_item>.primaryUse(gc, delta)
|
||||
p.actorValue["__aimhelper"] = true // TODO when you'll gonna implement it?
|
||||
|
||||
p.setHitboxDimension(15, p.actorValue.getAsInt(AVKey.BASEHEIGHT)!!, 10, 0)
|
||||
p.setHitboxDimension(15, p.actorValue.getAsInt(AVKey.BASEHEIGHT)!!, 11, -2) // FIXME offsetY of -2: Have no idea about the error; it's just supposed to be zero
|
||||
|
||||
p.inventory = ActorInventory(0x7FFFFFFF, true)
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ import net.torvald.colourutil.CIELabUtil.darkerLab
|
||||
import net.torvald.point.Point2d
|
||||
import net.torvald.spriteanimation.SpriteAnimation
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.tileproperties.Tile
|
||||
import net.torvald.terrarum.tileproperties.TileCodex
|
||||
import org.dyn4j.geometry.Vector2
|
||||
import org.newdawn.slick.Color
|
||||
import org.newdawn.slick.GameContainer
|
||||
@@ -15,11 +17,13 @@ import java.util.*
|
||||
*
|
||||
* Created by minjaesong on 16-08-29.
|
||||
*/
|
||||
|
||||
// TODO simplified, lightweight physics (does not call PhysicsSolver)
|
||||
open class ProjectileSimple(
|
||||
private val type: Int,
|
||||
fromPoint: Vector2, // projected coord
|
||||
toPoint: Vector2 // arriving coord
|
||||
) : ActorWithBody(ActorOrder.MIDTOP), Luminous, Projectile {
|
||||
) : ActorWithSprite(ActorOrder.MIDTOP), Luminous, Projectile {
|
||||
|
||||
val damage: Int
|
||||
val displayColour: Color
|
||||
@@ -69,7 +73,12 @@ open class ProjectileSimple(
|
||||
override fun update(gc: GameContainer, delta: Int) {
|
||||
// hit something and despawn
|
||||
lifetimeCounter += delta
|
||||
if ((ccdCollided || grounded) || lifetimeCounter >= lifetimeMax) flagDespawn()
|
||||
if (ccdCollided || grounded || lifetimeCounter >= lifetimeMax ||
|
||||
// stuck check
|
||||
TileCodex[Terrarum.ingame.world.getTileFromTerrain(feetPosTile[0], feetPosTile[1]) ?: Tile.STONE].isSolid
|
||||
) {
|
||||
flagDespawn()
|
||||
}
|
||||
|
||||
posPre.set(centrePosPoint)
|
||||
|
||||
|
||||
@@ -10,13 +10,14 @@ import org.newdawn.slick.Image
|
||||
/**
|
||||
* Created by SKYHi14 on 2017-01-07.
|
||||
*/
|
||||
class TapestryObject(val image: Image, val artName: String, val artAuthor: String) : FixtureBase() {
|
||||
class TapestryObject(val image: Image, val artName: String, val artAuthor: String) : FixtureBase(physics = false) {
|
||||
|
||||
// physics = false only speeds up for ~2 frames with 50 tapestries
|
||||
|
||||
init {
|
||||
makeNewSprite(image.width, image.height)
|
||||
image.filter = Image.FILTER_NEAREST
|
||||
makeNewSprite(image.width, image.height, image)
|
||||
setHitboxDimension(image.width, image.height, 0, 0)
|
||||
sprite!!.setSpriteImage(image)
|
||||
isNoSubjectToGrav = true
|
||||
setPosition(Terrarum.appgc.mouseX, Terrarum.appgc.mouseY)
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package net.torvald.terrarum.gameactors
|
||||
/**
|
||||
* Created by minjaesong on 16-04-26.
|
||||
*/
|
||||
class WeaponSwung(val itemID: Int) : ActorWithBody(ActorOrder.MIDTOP), Luminous {
|
||||
class WeaponSwung(val itemID: Int) : ActorWithSprite(ActorOrder.MIDTOP), Luminous {
|
||||
// just let the solver use AABB; it's cheap but works just enough
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,7 @@ package net.torvald.terrarum.gameactors.ai
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.gameactors.AIControlled
|
||||
import net.torvald.terrarum.gameactors.AVKey
|
||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||
import net.torvald.terrarum.gameactors.ActorWithSprite
|
||||
import net.torvald.terrarum.mapdrawer.LightmapRenderer
|
||||
import net.torvald.terrarum.tileproperties.Tile
|
||||
import net.torvald.terrarum.tileproperties.TileCodex
|
||||
@@ -14,7 +14,7 @@ import org.luaj.vm2.lib.ZeroArgFunction
|
||||
/**
|
||||
* Created by minjaesong on 16-10-24.
|
||||
*/
|
||||
internal class AILuaAPI(g: Globals, actor: ActorWithBody) {
|
||||
internal class AILuaAPI(g: Globals, actor: ActorWithSprite) {
|
||||
|
||||
// FIXME when actor jumps, the actor releases left/right stick
|
||||
|
||||
@@ -42,6 +42,7 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) {
|
||||
g["ai"]["getNearbyTiles"] = GetNearbyTiles(actor)
|
||||
g["ai"]["getFloorsHeight"] = GetFloorsHeight(actor)
|
||||
g["ai"]["getCeilingsHeight"] = GetCeilingsHeight(actor)
|
||||
g["ai"]["getLedgesHeight"] = GetLedgesHeight(actor)
|
||||
|
||||
g["game"] = LuaValue.tableOf()
|
||||
g["game"]["version"] = GameVersion()
|
||||
@@ -50,9 +51,9 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) {
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Reads arbitrary ActorWithBody and returns its information as Lua table
|
||||
* Reads arbitrary ActorWithSprite and returns its information as Lua table
|
||||
*/
|
||||
fun composeActorObject(actor: ActorWithBody): LuaTable {
|
||||
fun composeActorObject(actor: ActorWithSprite): LuaTable {
|
||||
val t: LuaTable = LuaTable()
|
||||
|
||||
t["name"] = actor.actorValue.getAsString(AVKey.NAME).toLua()
|
||||
@@ -94,7 +95,7 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) {
|
||||
operator fun LuaTable.set(index: Int, value: Int) { this[index] = value.toLua() }
|
||||
}
|
||||
|
||||
class GetSelfActorInfo(val actor: ActorWithBody) : ZeroArgFunction() {
|
||||
class GetSelfActorInfo(val actor: ActorWithSprite) : ZeroArgFunction() {
|
||||
override fun call(): LuaValue {
|
||||
return composeActorObject(actor)
|
||||
}
|
||||
@@ -130,13 +131,13 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) {
|
||||
}
|
||||
}
|
||||
|
||||
class GetX(val actor: ActorWithBody) : ZeroArgFunction() {
|
||||
class GetX(val actor: ActorWithSprite) : ZeroArgFunction() {
|
||||
override fun call(): LuaValue {
|
||||
return LuaValue.valueOf(actor.hitbox.centeredX)
|
||||
}
|
||||
}
|
||||
|
||||
class GetY(val actor: ActorWithBody) : ZeroArgFunction() {
|
||||
class GetY(val actor: ActorWithSprite) : ZeroArgFunction() {
|
||||
override fun call(): LuaValue {
|
||||
return LuaValue.valueOf(actor.hitbox.centeredY)
|
||||
}
|
||||
@@ -219,7 +220,7 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) {
|
||||
}
|
||||
}
|
||||
|
||||
class GetNearbyTiles(val actor: ActorWithBody) : OneArgFunction() {
|
||||
class GetNearbyTiles(val actor: ActorWithSprite) : OneArgFunction() {
|
||||
/** @param radius
|
||||
*
|
||||
* 3 will return 7x7 array, 0 will return 1x1, 1 will return 3x3
|
||||
@@ -261,7 +262,7 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) {
|
||||
}
|
||||
}
|
||||
|
||||
class GetFloorsHeight(val actor: ActorWithBody) : OneArgFunction() {
|
||||
class GetFloorsHeight(val actor: ActorWithSprite) : OneArgFunction() {
|
||||
/** @param radius
|
||||
*
|
||||
* 3 will return len:7 array, 0 will return len:1, 1 will return len:3
|
||||
@@ -304,14 +305,13 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) {
|
||||
}
|
||||
}
|
||||
|
||||
class GetCeilingsHeight(val actor: ActorWithBody) : OneArgFunction() {
|
||||
/** @param radius
|
||||
class GetCeilingsHeight(val actor: ActorWithSprite) : OneArgFunction() {
|
||||
/** @param arg radius
|
||||
*
|
||||
* 3 will return 7x7 array, 0 will return 1x1, 1 will return 3x3
|
||||
*
|
||||
* Index: [-3] .. [0] .. [3] for radius
|
||||
* Return value: floor height
|
||||
* (-1): tile you can stand on
|
||||
* 0: body tile (legs area)
|
||||
* 1: body tile (may be vary depend on the size of the actor)
|
||||
* 2+: tiles up there
|
||||
@@ -348,6 +348,48 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) {
|
||||
}
|
||||
}
|
||||
|
||||
class GetLedgesHeight(val actor: ActorWithSprite) : OneArgFunction() {
|
||||
/** @param arg radius
|
||||
* ==
|
||||
* <- (non-solid found)
|
||||
* ==
|
||||
* ==
|
||||
* ==
|
||||
* == @ -> ledge height: 4
|
||||
* =================
|
||||
*/
|
||||
override fun call(arg: LuaValue): LuaValue {
|
||||
val radius = arg.checkint()
|
||||
|
||||
val searchUpLimit = 12
|
||||
|
||||
if (radius < 0) {
|
||||
return LuaValue.NONE
|
||||
}
|
||||
else if (radius > 8) {
|
||||
throw IllegalArgumentException("Radius too large -- must be 8 or less")
|
||||
}
|
||||
else {
|
||||
val luatable = LuaTable()
|
||||
val feetTilePos = actor.feetPosTile
|
||||
for (x in feetTilePos[0] - radius..feetTilePos[0] + radius) {
|
||||
// search up
|
||||
var searchUpCounter = 0
|
||||
while (true) {
|
||||
val tile = Terrarum.ingame.world.getTileFromTerrain(x, feetTilePos[1] - searchUpCounter) ?: Tile.STONE
|
||||
if (!TileCodex[tile].isSolid || searchUpCounter >= searchUpLimit) {
|
||||
luatable[x - feetTilePos[0]] = searchUpCounter
|
||||
break
|
||||
}
|
||||
searchUpCounter++
|
||||
}
|
||||
}
|
||||
|
||||
return luatable
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -20,11 +20,11 @@ function generateCountMax()
|
||||
end
|
||||
|
||||
function moveToDirection(delta)
|
||||
local tiles = ai.getNearbyTiles(1)
|
||||
local pits = ai.getFloorsHeight(2)
|
||||
local ledges = ai.getLedgesHeight(1)
|
||||
|
||||
if moveMode == "left" then
|
||||
if bit32.band(bit32.bor(tiles[0][-1], tiles[-1][-1]), 1) == 1 then
|
||||
if pits[-1] == 1 then
|
||||
ai.moveLeft(0.8)
|
||||
if ledges[-1] <= jumpheight then -- no futile jumps
|
||||
ai.jump()
|
||||
@@ -33,7 +33,7 @@ function moveToDirection(delta)
|
||||
ai.moveLeft(0.5)
|
||||
end
|
||||
elseif moveMode == "right" then
|
||||
if bit32.band(bit32.bor(tiles[0][1], tiles[-1][1]), 1) == 1 then
|
||||
if pits[1] == 1 then
|
||||
ai.moveRight(0.8)
|
||||
if ledges[1] <= jumpheight then -- no futile jumps
|
||||
ai.jump()
|
||||
|
||||
@@ -2,7 +2,7 @@ package net.torvald.terrarum.gameactors.physicssolver
|
||||
|
||||
import com.jme3.math.FastMath
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||
import net.torvald.terrarum.gameactors.ActorWithSprite
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
@@ -20,9 +20,9 @@ object CollisionSolver {
|
||||
private val collListX = ArrayList<CollisionMarkings>(COLL_LIST_SIZE)
|
||||
private val collListY = ArrayList<CollisionMarkings>(COLL_LIST_SIZE)
|
||||
|
||||
private val collCandidateX = ArrayList<Pair<ActorWithBody, ActorWithBody>>(COLL_CANDIDATES_SIZE)
|
||||
private val collCandidateY = ArrayList<Pair<ActorWithBody, ActorWithBody>>(COLL_CANDIDATES_SIZE)
|
||||
private var collCandidates = ArrayList<Pair<ActorWithBody, ActorWithBody>>(COLL_FINAL_CANDIDATES_SIZE)
|
||||
private val collCandidateX = ArrayList<Pair<ActorWithSprite, ActorWithSprite>>(COLL_CANDIDATES_SIZE)
|
||||
private val collCandidateY = ArrayList<Pair<ActorWithSprite, ActorWithSprite>>(COLL_CANDIDATES_SIZE)
|
||||
private var collCandidates = ArrayList<Pair<ActorWithSprite, ActorWithSprite>>(COLL_FINAL_CANDIDATES_SIZE)
|
||||
|
||||
private val collCandidateStack = Stack<CollisionMarkings>()
|
||||
|
||||
@@ -40,7 +40,7 @@ object CollisionSolver {
|
||||
|
||||
// mark list x
|
||||
Terrarum.ingame.actorContainer.forEach { it ->
|
||||
if (it is ActorWithBody) {
|
||||
if (it is ActorWithSprite) {
|
||||
collListX.add(CollisionMarkings(it.hitbox.hitboxStart.x, STARTPOINT, it))
|
||||
collListX.add(CollisionMarkings(it.hitbox.hitboxEnd.x, ENDPOINT, it))
|
||||
}
|
||||
@@ -73,7 +73,7 @@ object CollisionSolver {
|
||||
|
||||
// mark list y
|
||||
Terrarum.ingame.actorContainer.forEach { it ->
|
||||
if (it is ActorWithBody) {
|
||||
if (it is ActorWithSprite) {
|
||||
collListY.add(CollisionMarkings(it.hitbox.hitboxStart.y, STARTPOINT, it))
|
||||
collListY.add(CollisionMarkings(it.hitbox.hitboxEnd.y, ENDPOINT, it))
|
||||
}
|
||||
@@ -89,7 +89,7 @@ object CollisionSolver {
|
||||
else if (it.kind == ENDPOINT) {
|
||||
val mark_this = it
|
||||
val mark_other = collCandidateStack.pop()
|
||||
val collCandidate: Pair<ActorWithBody, ActorWithBody>
|
||||
val collCandidate: Pair<ActorWithSprite, ActorWithSprite>
|
||||
// make sure actor with lower ID comes first
|
||||
if (mark_this.actor < mark_other.actor)
|
||||
collCandidate = Pair(mark_this.actor, mark_other.actor)
|
||||
@@ -137,7 +137,7 @@ object CollisionSolver {
|
||||
return indexOfEqFn(this, other) >= 0
|
||||
}
|
||||
|
||||
private fun solveCollision(a: ActorWithBody, b: ActorWithBody) {
|
||||
private fun solveCollision(a: ActorWithSprite, b: ActorWithSprite) {
|
||||
// some of the Pair(a, b) are either duplicates or erroneously reported.
|
||||
// e.g. (A, B), (B, C) and then (A, C);
|
||||
// in some situation (A, C) will not making any contact with each other
|
||||
@@ -170,11 +170,11 @@ object CollisionSolver {
|
||||
}
|
||||
}
|
||||
|
||||
private infix fun ActorWithBody.makesCollisionWith(other: ActorWithBody) =
|
||||
this.collisionType != ActorWithBody.COLLISION_NOCOLLIDE &&
|
||||
other.collisionType != ActorWithBody.COLLISION_NOCOLLIDE
|
||||
private infix fun ActorWithSprite.makesCollisionWith(other: ActorWithSprite) =
|
||||
this.collisionType != ActorWithSprite.COLLISION_NOCOLLIDE &&
|
||||
other.collisionType != ActorWithSprite.COLLISION_NOCOLLIDE
|
||||
|
||||
private infix fun ActorWithBody.isCollidingWith(other: ActorWithBody): Boolean {
|
||||
private infix fun ActorWithSprite.isCollidingWith(other: ActorWithSprite): Boolean {
|
||||
val ax = this.hitbox.centeredX
|
||||
val ay = this.hitbox.centeredY
|
||||
val bx = other.hitbox.centeredX
|
||||
@@ -205,7 +205,7 @@ object CollisionSolver {
|
||||
data class CollisionMarkings(
|
||||
val pos: Double,
|
||||
val kind: Int,
|
||||
val actor: ActorWithBody
|
||||
val actor: ActorWithSprite
|
||||
)
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package net.torvald.terrarum.gameactors.physicssolver
|
||||
|
||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||
import net.torvald.terrarum.gameactors.ActorWithSprite
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 16-05-01.
|
||||
@@ -11,7 +11,7 @@ object VelocitySolver {
|
||||
|
||||
}
|
||||
|
||||
private fun applyGravity(actor: ActorWithBody) {
|
||||
private fun applyGravity(actor: ActorWithSprite) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user