mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-11 19:14:05 +09:00
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
This commit is contained in:
@@ -31,8 +31,8 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
|||||||
* veloY += 3.0
|
* veloY += 3.0
|
||||||
* +3.0 is acceleration. You __accumulate__ acceleration to the velocity.
|
* +3.0 is acceleration. You __accumulate__ acceleration to the velocity.
|
||||||
*/
|
*/
|
||||||
var veloX: Float = 0.toFloat()
|
@Volatile var veloX: Float = 0.toFloat()
|
||||||
var veloY: Float = 0.toFloat()
|
@Volatile var veloY: Float = 0.toFloat()
|
||||||
@Transient private val VELO_HARD_LIMIT = 10000f
|
@Transient private val VELO_HARD_LIMIT = 10000f
|
||||||
|
|
||||||
var grounded = false
|
var grounded = false
|
||||||
@@ -132,10 +132,10 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
|||||||
internal val physSleep: Boolean
|
internal val physSleep: Boolean
|
||||||
get() = veloX.abs() < 0.5 && veloY.abs() < 0.5
|
get() = veloX.abs() < 0.5 && veloY.abs() < 0.5
|
||||||
|
|
||||||
private var posAdjustX = 0
|
@Transient private var posAdjustX = 0
|
||||||
private var posAdjustY = 0
|
@Transient private var posAdjustY = 0
|
||||||
|
|
||||||
private val BASE_FRICTION = 0.3f
|
@Transient private val BASE_FRICTION = 0.3f
|
||||||
|
|
||||||
init {
|
init {
|
||||||
map = Terrarum.game.map
|
map = Terrarum.game.map
|
||||||
@@ -189,10 +189,11 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
|||||||
|
|
||||||
override fun update(gc: GameContainer, delta_t: Int) {
|
override fun update(gc: GameContainer, delta_t: Int) {
|
||||||
if (isUpdate) {
|
if (isUpdate) {
|
||||||
updatePhysicalInfos()
|
|
||||||
/**
|
/**
|
||||||
* Update variables
|
* Update variables
|
||||||
*/
|
*/
|
||||||
|
updatePhysicalInfos()
|
||||||
|
|
||||||
// make NoClip work for player
|
// make NoClip work for player
|
||||||
if (this is Player) {
|
if (this is Player) {
|
||||||
isNoSubjectToGrav = isPlayerNoClip
|
isNoSubjectToGrav = isPlayerNoClip
|
||||||
@@ -212,6 +213,9 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
|||||||
// copy gravitational constant from the map the actor is in
|
// copy gravitational constant from the map the actor is in
|
||||||
gravitation = map.gravitation
|
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
|
// Actors are subject to the gravity and the buoyancy if they are not levitating
|
||||||
if (!isNoSubjectToGrav) {
|
if (!isNoSubjectToGrav) {
|
||||||
applyGravitation()
|
applyGravitation()
|
||||||
@@ -222,29 +226,31 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
|||||||
if (veloX > VELO_HARD_LIMIT) veloX = VELO_HARD_LIMIT
|
if (veloX > VELO_HARD_LIMIT) veloX = VELO_HARD_LIMIT
|
||||||
if (veloY > VELO_HARD_LIMIT) veloY = VELO_HARD_LIMIT
|
if (veloY > VELO_HARD_LIMIT) veloY = VELO_HARD_LIMIT
|
||||||
|
|
||||||
// Set 'next' position (hitbox) to fiddle with
|
if (!physSleep) {
|
||||||
updateNextHitboxFromVelo()
|
// Set 'next' position (hitbox) to fiddle with
|
||||||
|
updateNextHitboxFromVelo()
|
||||||
|
|
||||||
// if not horizontally moving then ...
|
// if not horizontally moving then ...
|
||||||
//if (Math.abs(veloX) < 0.5) { // fix for special situations (see fig. 1 at the bottom of the source)
|
//if (Math.abs(veloX) < 0.5) { // fix for special situations (see fig. 1 at the bottom of the source)
|
||||||
// updateVerticalPos();
|
// updateVerticalPos();
|
||||||
// updateHorizontalPos();
|
// updateHorizontalPos();
|
||||||
//}
|
//}
|
||||||
//else {
|
//else {
|
||||||
// compensate for colliding
|
// compensate for colliding
|
||||||
updateHorizontalCollision()
|
updateHorizontalCollision()
|
||||||
updateVerticalCollision()
|
updateVerticalCollision()
|
||||||
|
|
||||||
setHorizontalFriction()
|
setHorizontalFriction()
|
||||||
//}
|
//}
|
||||||
|
|
||||||
// apply our compensation to actual hitbox
|
// apply our compensation to actual hitbox
|
||||||
updateHitboxX()
|
updateHitboxX()
|
||||||
updateHitboxY()
|
updateHitboxY()
|
||||||
|
|
||||||
// make sure the actor does not go out of the map
|
// make sure the actor does not go out of the map
|
||||||
clampNextHitbox()
|
clampNextHitbox()
|
||||||
clampHitbox()
|
clampHitbox()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,14 +281,14 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setHorizontalFriction() {
|
private fun setHorizontalFriction() {
|
||||||
val friction = BASE_FRICTION * (tileFriction / 16f) // ground frction * !@#$!@#$ // default val: 0.3
|
val friction = BASE_FRICTION * tileFriction.tileFrictionToMult()
|
||||||
if (veloX < 0) {
|
if (veloX < 0) {
|
||||||
veloX += friction
|
veloX += friction
|
||||||
if (veloX > 0) veloX = 0f
|
if (veloX > 0) veloX = 0f // compensate overshoot
|
||||||
}
|
}
|
||||||
else if (veloX > 0) {
|
else if (veloX > 0) {
|
||||||
veloX -= friction
|
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
|
return friction
|
||||||
}
|
}
|
||||||
|
fun Int.tileFrictionToMult() = this / 16f
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get highest density (specific gravity) value from tiles that the body occupies.
|
* 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 (y in tilePosYStart..tilePosYEnd) {
|
||||||
for (x in tilePosXStart..tilePosXEnd) {
|
for (x in tilePosXStart..tilePosXEnd) {
|
||||||
val tile = map.getTileFromTerrain(x, y)
|
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
|
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() {
|
private fun clampHitbox() {
|
||||||
hitbox.setPositionFromPoint(
|
hitbox.setPositionFromPoint(
|
||||||
|
|||||||
@@ -106,10 +106,21 @@ object CollisionSolver {
|
|||||||
// in some situation (A, C) will not making any contact with each other
|
// in some situation (A, C) will not making any contact with each other
|
||||||
// we are going to filter them
|
// we are going to filter them
|
||||||
if (a isCollidingWith b) {
|
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 {
|
private infix fun ActorWithBody.isCollidingWith(other: ActorWithBody): Boolean {
|
||||||
val ax = this.hitbox.centeredX
|
val ax = this.hitbox.centeredX
|
||||||
val ay = this.hitbox.centeredY
|
val ay = this.hitbox.centeredY
|
||||||
@@ -152,6 +163,10 @@ object CollisionSolver {
|
|||||||
/**
|
/**
|
||||||
* === Some useful physics knowledge ===
|
* === 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)
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
@@ -7,9 +7,9 @@ import net.torvald.point.Point2f
|
|||||||
*/
|
*/
|
||||||
class Hitbox(x1: Float, y1: Float, width: Float, height: Float) {
|
class Hitbox(x1: Float, y1: Float, width: Float, height: Float) {
|
||||||
|
|
||||||
var hitboxStart: Point2f
|
@Volatile var hitboxStart: Point2f
|
||||||
private set
|
private set
|
||||||
var hitboxEnd: Point2f
|
@Volatile var hitboxEnd: Point2f
|
||||||
private set
|
private set
|
||||||
var width: Float = 0.toFloat()
|
var width: Float = 0.toFloat()
|
||||||
private set
|
private set
|
||||||
|
|||||||
@@ -55,8 +55,6 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
|
|||||||
|
|
||||||
@Transient private val TSIZE = MapDrawer.TILE_SIZE
|
@Transient private val TSIZE = MapDrawer.TILE_SIZE
|
||||||
|
|
||||||
private val factionSet = HashSet<Faction>()
|
|
||||||
|
|
||||||
@Transient private val BASE_DENSITY = 1020
|
@Transient private val BASE_DENSITY = 1020
|
||||||
|
|
||||||
/** Must be set by PlayerFactory */
|
/** Must be set by PlayerFactory */
|
||||||
|
|||||||
12
src/net/torvald/terrarum/gameactors/WeaponSwung.kt
Normal file
12
src/net/torvald/terrarum/gameactors/WeaponSwung.kt
Normal file
@@ -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 {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package net.torvald.terrarum.gameactors.faction
|
package net.torvald.terrarum.gameactors.faction
|
||||||
|
|
||||||
import net.torvald.random.HQRNG
|
import net.torvald.random.HQRNG
|
||||||
|
import net.torvald.terrarum.Terrarum
|
||||||
import java.util.HashSet
|
import java.util.HashSet
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -13,7 +14,7 @@ class Faction(factionName: String) {
|
|||||||
lateinit var factionNeutral: HashSet<String>
|
lateinit var factionNeutral: HashSet<String>
|
||||||
lateinit var factionHostile: HashSet<String>
|
lateinit var factionHostile: HashSet<String>
|
||||||
lateinit var factionFearful: HashSet<String>
|
lateinit var factionFearful: HashSet<String>
|
||||||
var factionID: Long = HQRNG().nextLong()
|
var factionID: Long = generateUniqueID()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
this.factionName = factionName
|
this.factionName = factionName
|
||||||
@@ -59,4 +60,8 @@ class Faction(factionName: String) {
|
|||||||
factionFearful.remove(faction)
|
factionFearful.remove(faction)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun generateUniqueID(): Long {
|
||||||
|
fun Long.abs() = if (this < 0) -this else this
|
||||||
|
return HQRNG().nextLong().abs() // set new ID
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -331,17 +331,13 @@ object MapCamera {
|
|||||||
tilesetBook[mode].endUse()
|
tilesetBook[mode].endUse()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getGrassInfo(x: Int, y: Int, from: Int, to: Int): Int {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
* @param x
|
* @param x
|
||||||
* *
|
* *
|
||||||
* @param y
|
* @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 {
|
private fun getNearbyTilesInfo(x: Int, y: Int, mode: Int, mark: Int?): Int {
|
||||||
val nearbyTiles = IntArray(4)
|
val nearbyTiles = IntArray(4)
|
||||||
@@ -415,7 +411,6 @@ object MapCamera {
|
|||||||
// has tile on the bottom
|
// has tile on the bottom
|
||||||
3 else 0
|
3 else 0
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun drawTile(mode: Int, tilewisePosX: Int, tilewisePosY: Int, sheetX: Int, sheetY: Int) {
|
private fun drawTile(mode: Int, tilewisePosX: Int, tilewisePosY: Int, sheetX: Int, sheetY: Int) {
|
||||||
|
|||||||
@@ -85,8 +85,8 @@ class BasicDebugInfoWindow:UICanvas {
|
|||||||
+ (hitbox.pointedY / MapDrawer.TILE_SIZE).toInt().toString()
|
+ (hitbox.pointedY / MapDrawer.TILE_SIZE).toInt().toString()
|
||||||
+ ")")
|
+ ")")
|
||||||
|
|
||||||
printLine(g, 3, "veloX reported $ccG${player.veloX}")
|
printLine(g, 3, "veloX reported $ccG${if (player.physSleep) "(sleep)" else player.veloX}")
|
||||||
printLine(g, 4, "veloY reported $ccG${player.veloY}")
|
printLine(g, 4, "veloY reported $ccG${if (player.physSleep) "(sleep)" else player.veloY}")
|
||||||
|
|
||||||
printLineColumn(g, 2, 3, "veloX measured $ccG${xdelta}")
|
printLineColumn(g, 2, 3, "veloX measured $ccG${xdelta}")
|
||||||
printLineColumn(g, 2, 4, "veloY measured $ccG${ydelta}")
|
printLineColumn(g, 2, 4, "veloY measured $ccG${ydelta}")
|
||||||
|
|||||||
Reference in New Issue
Block a user