From 7d804f24e7bd17bd5c3330a0899c0117e53a811b Mon Sep 17 00:00:00 2001 From: Song Minjae Date: Tue, 26 Apr 2016 14:36:21 +0900 Subject: [PATCH] physics objects (ActorWithBody) will now sleep if ||v|| < 0.5, faction ID is now positive integer (64-bit) only Former-commit-id: 437cff82cf5748c36c5ad72bc43b4fc172b168c8 Former-commit-id: 3ab0500f83da229ec77b85c09ec42fd332ef62ce --- .../terrarum/gameactors/ActorWithBody.kt | 100 ++++++++++++------ .../terrarum/gameactors/CollisionSolver.kt | 17 ++- src/net/torvald/terrarum/gameactors/Hitbox.kt | 4 +- src/net/torvald/terrarum/gameactors/Player.kt | 2 - .../terrarum/gameactors/WeaponSwung.kt | 12 +++ .../terrarum/gameactors/faction/Faction.kt | 7 +- .../torvald/terrarum/mapdrawer/MapCamera.kt | 7 +- .../terrarum/ui/BasicDebugInfoWindow.kt | 4 +- 8 files changed, 104 insertions(+), 49 deletions(-) create mode 100644 src/net/torvald/terrarum/gameactors/WeaponSwung.kt diff --git a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt index cd0777e9d..bc03208cf 100644 --- a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt +++ b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt @@ -31,8 +31,8 @@ open class ActorWithBody constructor() : Actor(), Visible { * veloY += 3.0 * +3.0 is acceleration. You __accumulate__ acceleration to the velocity. */ - var veloX: Float = 0.toFloat() - var veloY: Float = 0.toFloat() + @Volatile var veloX: Float = 0.toFloat() + @Volatile var veloY: Float = 0.toFloat() @Transient private val VELO_HARD_LIMIT = 10000f var grounded = false @@ -132,10 +132,10 @@ open class ActorWithBody constructor() : Actor(), Visible { internal val physSleep: Boolean get() = veloX.abs() < 0.5 && veloY.abs() < 0.5 - private var posAdjustX = 0 - private var posAdjustY = 0 + @Transient private var posAdjustX = 0 + @Transient private var posAdjustY = 0 - private val BASE_FRICTION = 0.3f + @Transient private val BASE_FRICTION = 0.3f init { map = Terrarum.game.map @@ -189,10 +189,11 @@ open class ActorWithBody constructor() : Actor(), Visible { override fun update(gc: GameContainer, delta_t: Int) { if (isUpdate) { - updatePhysicalInfos() /** * Update variables */ + updatePhysicalInfos() + // make NoClip work for player if (this is Player) { isNoSubjectToGrav = isPlayerNoClip @@ -212,6 +213,9 @@ open class ActorWithBody constructor() : Actor(), Visible { // copy gravitational constant from the map the actor is in gravitation = map.gravitation + /** + * Actual physics thing (altering velocity) starts from here + */ // Actors are subject to the gravity and the buoyancy if they are not levitating if (!isNoSubjectToGrav) { applyGravitation() @@ -222,29 +226,31 @@ open class ActorWithBody constructor() : Actor(), Visible { if (veloX > VELO_HARD_LIMIT) veloX = VELO_HARD_LIMIT if (veloY > VELO_HARD_LIMIT) veloY = VELO_HARD_LIMIT - // Set 'next' position (hitbox) to fiddle with - updateNextHitboxFromVelo() + if (!physSleep) { + // Set 'next' position (hitbox) to fiddle with + updateNextHitboxFromVelo() - // if not horizontally moving then ... - //if (Math.abs(veloX) < 0.5) { // fix for special situations (see fig. 1 at the bottom of the source) - // updateVerticalPos(); - // updateHorizontalPos(); - //} - //else { - // compensate for colliding - updateHorizontalCollision() - updateVerticalCollision() + // if not horizontally moving then ... + //if (Math.abs(veloX) < 0.5) { // fix for special situations (see fig. 1 at the bottom of the source) + // updateVerticalPos(); + // updateHorizontalPos(); + //} + //else { + // compensate for colliding + updateHorizontalCollision() + updateVerticalCollision() - setHorizontalFriction() - //} + setHorizontalFriction() + //} - // apply our compensation to actual hitbox - updateHitboxX() - updateHitboxY() + // apply our compensation to actual hitbox + updateHitboxX() + updateHitboxY() - // make sure the actor does not go out of the map - clampNextHitbox() - clampHitbox() + // make sure the actor does not go out of the map + clampNextHitbox() + clampHitbox() + } } } @@ -275,14 +281,14 @@ open class ActorWithBody constructor() : Actor(), Visible { } private fun setHorizontalFriction() { - val friction = BASE_FRICTION * (tileFriction / 16f) // ground frction * !@#$!@#$ // default val: 0.3 + val friction = BASE_FRICTION * tileFriction.tileFrictionToMult() if (veloX < 0) { veloX += friction - if (veloX > 0) veloX = 0f + if (veloX > 0) veloX = 0f // compensate overshoot } else if (veloX > 0) { veloX -= friction - if (veloX < 0) veloX = 0f + if (veloX < 0) veloX = 0f // compensate overshoot } } @@ -580,6 +586,7 @@ open class ActorWithBody constructor() : Actor(), Visible { return friction } + fun Int.tileFrictionToMult() = this / 16f /** * Get highest density (specific gravity) value from tiles that the body occupies. @@ -597,20 +604,43 @@ open class ActorWithBody constructor() : Actor(), Visible { for (y in tilePosYStart..tilePosYEnd) { for (x in tilePosXStart..tilePosXEnd) { val tile = map.getTileFromTerrain(x, y) - if (TilePropCodex.getProp(tile).isFluid) { - val thisFluidDensity = TilePropCodex.getProp(tile).density + val thisFluidDensity = TilePropCodex.getProp(tile).density - if (thisFluidDensity > density) density = thisFluidDensity - } + if (thisFluidDensity > density) density = thisFluidDensity } } return density } - private fun mvmtRstcToMultiplier(movementResistanceValue: Int): Float { - return 1f / (1 + movementResistanceValue / 16f) - } + /** + * Get highest fluid resistance value from tiles that the body occupies. + * @return + */ + private val fluidResistance: Int + get() { + var resistance = 0 + + //get highest fluid density + val tilePosXStart = (nextHitbox.posX / TSIZE).roundToInt() + val tilePosYStart = (nextHitbox.posY / TSIZE).roundToInt() + val tilePosXEnd = (nextHitbox.hitboxEnd.x / TSIZE).roundToInt() + val tilePosYEnd = (nextHitbox.hitboxEnd.y / TSIZE).roundToInt() + for (y in tilePosYStart..tilePosYEnd) { + for (x in tilePosXStart..tilePosXEnd) { + val tile = map.getTileFromTerrain(x, y) + + if (TilePropCodex.getProp(tile).isFluid) { + val thisResistance = TilePropCodex.getProp(tile).movementResistance + + if (thisResistance > resistance) resistance = thisResistance + } + } + } + + return resistance + } + fun Int.resistanceToMult(): Float = 1f / (1 + this / 16f) private fun clampHitbox() { hitbox.setPositionFromPoint( diff --git a/src/net/torvald/terrarum/gameactors/CollisionSolver.kt b/src/net/torvald/terrarum/gameactors/CollisionSolver.kt index 6c9fccc10..a21a5967d 100644 --- a/src/net/torvald/terrarum/gameactors/CollisionSolver.kt +++ b/src/net/torvald/terrarum/gameactors/CollisionSolver.kt @@ -106,10 +106,21 @@ object CollisionSolver { // in some situation (A, C) will not making any contact with each other // we are going to filter them if (a isCollidingWith b) { + // notify collision, but not solve it yet + // (e.g. player vs mob, will pass by but still takes damage) + + // if they actually makes collision (e.g. player vs ball), solve it + if (a makesCollisionWith b) { + + } } } + private infix fun ActorWithBody.makesCollisionWith(other: ActorWithBody): Boolean { + return false + } + private infix fun ActorWithBody.isCollidingWith(other: ActorWithBody): Boolean { val ax = this.hitbox.centeredX val ay = this.hitbox.centeredY @@ -152,6 +163,10 @@ object CollisionSolver { /** * === Some useful physics knowledge === * - * * Momentum = mass × Velocity + * * Momentum = mass × Velocity (p = mv, conserved) + * + * * Force = mass × acceleration (f = ma, conserved) + * + * * F_AB = -F_BA (Lex Tertia, does NOT apply to fictitious force like centrifugal) */ } \ No newline at end of file diff --git a/src/net/torvald/terrarum/gameactors/Hitbox.kt b/src/net/torvald/terrarum/gameactors/Hitbox.kt index 636cb2f71..c6444009b 100644 --- a/src/net/torvald/terrarum/gameactors/Hitbox.kt +++ b/src/net/torvald/terrarum/gameactors/Hitbox.kt @@ -7,9 +7,9 @@ import net.torvald.point.Point2f */ class Hitbox(x1: Float, y1: Float, width: Float, height: Float) { - var hitboxStart: Point2f + @Volatile var hitboxStart: Point2f private set - var hitboxEnd: Point2f + @Volatile var hitboxEnd: Point2f private set var width: Float = 0.toFloat() private set diff --git a/src/net/torvald/terrarum/gameactors/Player.kt b/src/net/torvald/terrarum/gameactors/Player.kt index 2d8808912..5ea25f043 100644 --- a/src/net/torvald/terrarum/gameactors/Player.kt +++ b/src/net/torvald/terrarum/gameactors/Player.kt @@ -55,8 +55,6 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan @Transient private val TSIZE = MapDrawer.TILE_SIZE - private val factionSet = HashSet() - @Transient private val BASE_DENSITY = 1020 /** Must be set by PlayerFactory */ diff --git a/src/net/torvald/terrarum/gameactors/WeaponSwung.kt b/src/net/torvald/terrarum/gameactors/WeaponSwung.kt new file mode 100644 index 000000000..35e22cc45 --- /dev/null +++ b/src/net/torvald/terrarum/gameactors/WeaponSwung.kt @@ -0,0 +1,12 @@ +package net.torvald.terrarum.gameactors + +/** + * Created by minjaesong on 16-04-26. + */ +class WeaponSwung(val itemID: Int) : ActorWithBody() { + // just let the solver use AABB; it's cheap but works just enough + + init { + + } +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/gameactors/faction/Faction.kt b/src/net/torvald/terrarum/gameactors/faction/Faction.kt index df840f103..1ac12ba92 100644 --- a/src/net/torvald/terrarum/gameactors/faction/Faction.kt +++ b/src/net/torvald/terrarum/gameactors/faction/Faction.kt @@ -1,6 +1,7 @@ package net.torvald.terrarum.gameactors.faction import net.torvald.random.HQRNG +import net.torvald.terrarum.Terrarum import java.util.HashSet /** @@ -13,7 +14,7 @@ class Faction(factionName: String) { lateinit var factionNeutral: HashSet lateinit var factionHostile: HashSet lateinit var factionFearful: HashSet - var factionID: Long = HQRNG().nextLong() + var factionID: Long = generateUniqueID() init { this.factionName = factionName @@ -59,4 +60,8 @@ class Faction(factionName: String) { factionFearful.remove(faction) } + fun generateUniqueID(): Long { + fun Long.abs() = if (this < 0) -this else this + return HQRNG().nextLong().abs() // set new ID + } } diff --git a/src/net/torvald/terrarum/mapdrawer/MapCamera.kt b/src/net/torvald/terrarum/mapdrawer/MapCamera.kt index 38b3830b0..a4ca2600f 100644 --- a/src/net/torvald/terrarum/mapdrawer/MapCamera.kt +++ b/src/net/torvald/terrarum/mapdrawer/MapCamera.kt @@ -331,17 +331,13 @@ object MapCamera { tilesetBook[mode].endUse() } - private fun getGrassInfo(x: Int, y: Int, from: Int, to: Int): Int { - return 0 - } - /** * @param x * * * @param y * * - * @return [0-15] 1: up, 2: right, 4: down, 8: left + * @return binary [0-15] 1: up, 2: right, 4: down, 8: left */ private fun getNearbyTilesInfo(x: Int, y: Int, mode: Int, mark: Int?): Int { val nearbyTiles = IntArray(4) @@ -415,7 +411,6 @@ object MapCamera { // has tile on the bottom 3 else 0 } - } private fun drawTile(mode: Int, tilewisePosX: Int, tilewisePosY: Int, sheetX: Int, sheetY: Int) { diff --git a/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt b/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt index 01d2ebfef..2dcbd1332 100644 --- a/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt +++ b/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt @@ -85,8 +85,8 @@ class BasicDebugInfoWindow:UICanvas { + (hitbox.pointedY / MapDrawer.TILE_SIZE).toInt().toString() + ")") - printLine(g, 3, "veloX reported $ccG${player.veloX}") - printLine(g, 4, "veloY reported $ccG${player.veloY}") + printLine(g, 3, "veloX reported $ccG${if (player.physSleep) "(sleep)" else player.veloX}") + printLine(g, 4, "veloY reported $ccG${if (player.physSleep) "(sleep)" else player.veloY}") printLineColumn(g, 2, 3, "veloX measured $ccG${xdelta}") printLineColumn(g, 2, 4, "veloY measured $ccG${ydelta}")