mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 12:21:52 +09:00
player now walks again, still stick to wall if key is kept down, but gravity is no longer accumulated (because the walking velocity is now separated)
Former-commit-id: f9394abe6230a4e60f2f7a42e81f7e85264a60c5 Former-commit-id: 1cd5b78c5800aef082d5eeec13a0a0a50ccea35b
This commit is contained in:
@@ -52,7 +52,7 @@ constructor() : BasicGameState() {
|
||||
|
||||
lateinit var consoleHandler: UIHandler
|
||||
lateinit var debugWindow: UIHandler
|
||||
lateinit var notifinator: UIHandler
|
||||
lateinit var notifier: UIHandler
|
||||
|
||||
lateinit internal var player: Player
|
||||
|
||||
@@ -123,10 +123,10 @@ constructor() : BasicGameState() {
|
||||
debugWindow = UIHandler(BasicDebugInfoWindow())
|
||||
debugWindow.setPosition(0, 0)
|
||||
|
||||
notifinator = UIHandler(Notification())
|
||||
notifinator.setPosition(
|
||||
(Terrarum.WIDTH - notifinator.UI.width) / 2, Terrarum.HEIGHT - notifinator.UI.height)
|
||||
notifinator.setVisibility(true)
|
||||
notifier = UIHandler(Notification())
|
||||
notifier.setPosition(
|
||||
(Terrarum.WIDTH - notifier.UI.width) / 2, Terrarum.HEIGHT - notifier.UI.height)
|
||||
notifier.setVisibility(true)
|
||||
|
||||
if (Terrarum.gameConfig.getAsBoolean("smoothlighting") == true)
|
||||
KeyToggler.forceSet(KEY_LIGHTMAP_SMOOTH, true)
|
||||
@@ -164,7 +164,7 @@ constructor() : BasicGameState() {
|
||||
debugWindow.update(gc, delta)
|
||||
|
||||
|
||||
notifinator.update(gc, delta)
|
||||
notifier.update(gc, delta)
|
||||
|
||||
Terrarum.appgc.setVSync(Terrarum.appgc.fps >= Terrarum.VSYNC_TRIGGER_THRESHOLD)
|
||||
}
|
||||
@@ -250,7 +250,7 @@ constructor() : BasicGameState() {
|
||||
uiContainer.forEach { ui -> ui.render(gc, g) }
|
||||
debugWindow.render(gc, g)
|
||||
consoleHandler.render(gc, g)
|
||||
notifinator.render(gc, g)
|
||||
notifier.render(gc, g)
|
||||
}
|
||||
|
||||
private fun getGradientColour(row: Int): Color {
|
||||
@@ -311,20 +311,21 @@ constructor() : BasicGameState() {
|
||||
g.fill(skyBox, skyColourFill)
|
||||
}
|
||||
|
||||
/** Send message to notifier UI and toggle the UI as opened. */
|
||||
fun sendNotification(msg: Array<String>) {
|
||||
(notifinator.UI as Notification).sendNotification(Terrarum.appgc, update_delta, msg)
|
||||
notifinator.setAsOpening()
|
||||
(notifier.UI as Notification).sendNotification(Terrarum.appgc, update_delta, msg)
|
||||
notifier.setAsOpening()
|
||||
}
|
||||
|
||||
fun wakeDormantActors() {
|
||||
// determine whether the inactive actor should be re-active
|
||||
// determine whether the dormant actor should be re-activated
|
||||
var actorContainerSize = actorContainerInactive.size
|
||||
var i = 0
|
||||
while (i < actorContainerSize) { // loop thru actorContainerInactive
|
||||
val actor = actorContainerInactive[i]
|
||||
val actorIndex = i
|
||||
if (actor is Visible && actor.inUpdateRange()) {
|
||||
addActor(actor)
|
||||
addActor(actor) // duplicates are checked here
|
||||
actorContainerInactive.removeAt(actorIndex)
|
||||
actorContainerSize -= 1
|
||||
i-- // array removed 1 elem, so also decrement counter by 1
|
||||
@@ -336,14 +337,14 @@ constructor() : BasicGameState() {
|
||||
fun updateAndInactivateDistantActors(gc: GameContainer, delta: Int) {
|
||||
var actorContainerSize = actorContainer.size
|
||||
var i = 0
|
||||
// determine whether the actor should be active or dormant by its distance from the player
|
||||
// will put dormant actors to list specifically for them
|
||||
// determine whether the actor should be active or dormant by its distance from the player.
|
||||
// If the actor must be dormant, the target actor will be put to the list specifically for them.
|
||||
// if the actor is not to be dormant, update it
|
||||
while (i < actorContainerSize) { // loop thru actorContainer
|
||||
while (i < actorContainerSize) { // loop through the actorContainer
|
||||
val actor = actorContainer[i]
|
||||
val actorIndex = i
|
||||
if (actor is Visible && !actor.inUpdateRange()) {
|
||||
actorContainerInactive.add(actor) // duplicates are checked when the actor is re-activated
|
||||
actorContainerInactive.add(actor) // naïve add; duplicates are checked when the actor is re-activated
|
||||
actorContainer.removeAt(actorIndex)
|
||||
actorContainerSize -= 1
|
||||
i-- // array removed 1 elem, so also decrement counter by 1
|
||||
@@ -359,6 +360,7 @@ constructor() : BasicGameState() {
|
||||
get() = getGradientColour(2).getRGB24().rgb24ExpandToRgb30()
|
||||
|
||||
fun Color.getRGB24(): Int = (this.redByte shl 16) or (this.greenByte shl 8) or (this.blueByte)
|
||||
/** Remap 8-bit value (0.0-1.0) to 10-bit value (0.0-4.0) by prepending two bits of zero for each R, G and B. */
|
||||
fun Int.rgb24ExpandToRgb30(): Int = (this and 0xff) or
|
||||
(this and 0xff00).ushr(8).shl(10) or
|
||||
(this and 0xff0000).ushr(16).shl(20)
|
||||
@@ -382,11 +384,16 @@ constructor() : BasicGameState() {
|
||||
actorContainer.binarySearch(ID) >= 0
|
||||
|
||||
fun removeActor(actor: Actor) = removeActor(actor.referenceID)
|
||||
/**
|
||||
* get index of the actor and delete by the index.
|
||||
* we can do this as the list is guaranteed to be sorted
|
||||
* and only contains unique values.
|
||||
*
|
||||
* Any values behind the index will be automatically pushed to front.
|
||||
* This is how remove function of [java.util.ArrayList] is defined.
|
||||
*/
|
||||
fun removeActor(ID: Int) {
|
||||
if (ID == player.referenceID) throw RuntimeException("Attempted to remove player.")
|
||||
// get index of the actor and delete by the index.
|
||||
// we can do this as the list is guaranteed to be sorted
|
||||
// and only contains unique values
|
||||
val indexToDelete = actorContainer.binarySearch(ID)
|
||||
if (indexToDelete >= 0) actorContainer.removeAt(indexToDelete)
|
||||
}
|
||||
@@ -418,7 +425,6 @@ constructor() : BasicGameState() {
|
||||
}
|
||||
|
||||
private fun insertionSortLastElem(arr: ArrayList<Actor>) {
|
||||
// 'insertion sort' last element
|
||||
var x: Actor
|
||||
var j: Int
|
||||
var index: Int = arr.size - 1
|
||||
|
||||
@@ -35,13 +35,16 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
||||
* veloY += 3.0
|
||||
* +3.0 is acceleration. You __accumulate__ acceleration to the velocity.
|
||||
*/
|
||||
internal val positioningDelta = Vector2(0.0, 0.0)
|
||||
internal val velocity = Vector2(0.0, 0.0)
|
||||
var veloX: Double
|
||||
get() = positioningDelta.x
|
||||
private set(value) { positioningDelta.x = value }
|
||||
get() = velocity.x
|
||||
private set(value) { velocity.x = value }
|
||||
var veloY: Double
|
||||
get() = positioningDelta.y
|
||||
private set(value) { positioningDelta.y = value }
|
||||
get() = velocity.y
|
||||
private set(value) { velocity.y = value }
|
||||
var walkX: Double = 0.0
|
||||
var walkY: Double = 0.0
|
||||
val moveDelta = Vector2(0.0, 0.0)
|
||||
@Transient private val VELO_HARD_LIMIT = 10000.0
|
||||
|
||||
var grounded = false
|
||||
@@ -118,7 +121,7 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
||||
*/
|
||||
@Transient private val SI_TO_GAME_VEL = METER / Terrarum.TARGET_FPS
|
||||
|
||||
@Transient private var gravitation: Vector2 = map.gravitation
|
||||
@Transient private val gravitation: Vector2 = map.gravitation
|
||||
@Transient val DRAG_COEFF_DEFAULT = 1.2
|
||||
/** Drag coeffisient. Parachutes have much higher value than bare body (1.2) */
|
||||
private var DRAG_COEFF: Double
|
||||
@@ -157,8 +160,8 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
||||
|
||||
@Transient private val MASS_DEFAULT: Double = 60.0
|
||||
|
||||
internal val physSleep: Boolean
|
||||
get() = veloX.abs() < 0.5 && veloY.abs() < 0.5
|
||||
internal var physSleep: Boolean = false
|
||||
private set
|
||||
|
||||
/**
|
||||
* for collide-to-world compensation
|
||||
@@ -176,10 +179,6 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
||||
private val CCD_THRE = 1.0
|
||||
private val CCD_TICK = 0.125
|
||||
|
||||
val movementDelta = Vector2(0.0, 0.0)
|
||||
val externalDelta = Vector2(0.0, 0.0)
|
||||
private val gravityDelta = Vector2(0.0 , 0.0)
|
||||
|
||||
init {
|
||||
|
||||
}
|
||||
@@ -226,6 +225,18 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
||||
|
||||
override fun run() = update(Terrarum.appgc, Terrarum.game.DELTA_T)
|
||||
|
||||
/**
|
||||
* Add vector value to the velocity, in the time unit of single frame.
|
||||
*
|
||||
* Since we're adding some value every frame, the value is equivalent to the acceleration.
|
||||
* Find about Newton's second law for the background knowledge.
|
||||
* @param vec : Acceleration in Vector2
|
||||
*/
|
||||
fun applyForce(vec: Vector2) {
|
||||
velocity += vec
|
||||
physSleep = false
|
||||
}
|
||||
|
||||
override fun update(gc: GameContainer, delta_t: Int) {
|
||||
if (isUpdate) {
|
||||
|
||||
@@ -251,12 +262,13 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
||||
//applyBuoyancy()
|
||||
}
|
||||
|
||||
positioningDelta.set(movementDelta + externalDelta + gravityDelta)
|
||||
|
||||
// hard limit velocity
|
||||
if (veloX > VELO_HARD_LIMIT) veloX = VELO_HARD_LIMIT
|
||||
if (veloY > VELO_HARD_LIMIT) veloY = VELO_HARD_LIMIT
|
||||
|
||||
moveDelta.x = veloX + walkX
|
||||
moveDelta.y = veloY + walkY
|
||||
|
||||
if (!physSleep) {
|
||||
// Set 'next' position (hitbox) to fiddle with
|
||||
setNewNextHitbox()
|
||||
@@ -309,16 +321,17 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
||||
* Drag of atmosphere
|
||||
* D = Cd (drag coefficient) * 0.5 * rho (density) * V^2 (velocity) * A (area)
|
||||
*/
|
||||
val D: Vector2 = (gravityDelta + movementDelta) * DRAG_COEFF * 0.5 * A * tileDensityFluid.toDouble()
|
||||
val D: Vector2 = velocity * DRAG_COEFF * 0.5 * A * tileDensityFluid.toDouble()
|
||||
|
||||
val V: Vector2 = (W - D) / mass * SI_TO_GAME_ACC
|
||||
|
||||
gravityDelta += V
|
||||
applyForce(V)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setHorizontalFriction() {
|
||||
val friction = BASE_FRICTION * tileFriction.tileFrictionToMult()
|
||||
|
||||
if (veloX < 0) {
|
||||
veloX += friction
|
||||
if (veloX > 0) veloX = 0.0 // compensate overshoot
|
||||
@@ -327,18 +340,37 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
||||
veloX -= friction
|
||||
if (veloX < 0) veloX = 0.0 // compensate overshoot
|
||||
}
|
||||
|
||||
if (walkX < 0) {
|
||||
walkX += friction
|
||||
if (walkX > 0) walkX = 0.0
|
||||
}
|
||||
else if (walkX > 0) {
|
||||
walkX -= friction
|
||||
if (walkX < 0) walkX = 0.0
|
||||
}
|
||||
}
|
||||
|
||||
private fun setVerticalFriction() {
|
||||
val friction = BASE_FRICTION * tileFriction.tileFrictionToMult()
|
||||
|
||||
if (veloY < 0) {
|
||||
veloY += friction
|
||||
if (veloY > 0) veloY = 0.0 // compensate overshoot
|
||||
if (veloY > 0) veloX = 0.0 // compensate overshoot
|
||||
}
|
||||
else if (veloY > 0) {
|
||||
veloY -= friction
|
||||
if (veloY < 0) veloY = 0.0 // compensate overshoot
|
||||
}
|
||||
|
||||
if (walkY < 0) {
|
||||
walkY += friction
|
||||
if (walkY > 0) walkY = 0.0
|
||||
}
|
||||
else if (walkY > 0) {
|
||||
walkY -= friction
|
||||
if (walkY < 0) walkY = 0.0
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateVerticalCollision() {
|
||||
@@ -347,13 +379,11 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
||||
if (isColliding(CONTACT_AREA_BOTTOM)) { // the ground has dug into the body
|
||||
adjustHitBottom()
|
||||
veloY = 0.0 // reset veloY, simulating normal force
|
||||
gravityDelta.zero()
|
||||
hitAndReflectY()
|
||||
grounded = true
|
||||
}
|
||||
else if (isColliding(CONTACT_AREA_BOTTOM, 0, 1)) { // the actor is standing ON the ground
|
||||
veloY = 0.0 // reset veloY, simulating normal force
|
||||
gravityDelta.zero()
|
||||
hitAndReflectY()
|
||||
grounded = true
|
||||
}
|
||||
@@ -566,7 +596,7 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
||||
|
||||
private fun hitAndReflectX() {
|
||||
if ((veloX * elasticity).abs() > SLEEP_THRE) {
|
||||
veloX = -veloX * elasticity
|
||||
veloX *= -elasticity
|
||||
}
|
||||
else {
|
||||
veloX = 0.0
|
||||
@@ -575,7 +605,7 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
||||
|
||||
private fun hitAndReflectY() {
|
||||
if ((veloY * elasticity).abs() > SLEEP_THRE) {
|
||||
veloY = -veloY * elasticity
|
||||
veloY *= -elasticity
|
||||
}
|
||||
else {
|
||||
veloY = 0.0
|
||||
@@ -774,8 +804,8 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
||||
private fun setNewNextHitbox() {
|
||||
|
||||
nextHitbox.set(
|
||||
(hitbox.posX + veloX)
|
||||
, (hitbox.posY + veloY)
|
||||
(hitbox.posX + moveDelta.x)
|
||||
, (hitbox.posY + moveDelta.y)
|
||||
, (baseHitboxW * scale)
|
||||
, (baseHitboxH * scale)
|
||||
)
|
||||
|
||||
@@ -133,24 +133,19 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
|
||||
(if (left) -1 else 1).toFloat() *
|
||||
absAxisVal
|
||||
|
||||
// veloX = readonly_totalX
|
||||
movementDelta += Vector2(readonly_totalX, 0.0)
|
||||
//applyForce(Vector2(readonly_totalX, 0.0))
|
||||
walkX += readonly_totalX
|
||||
walkX = absClamp(walkX, actorValue.getAsDouble(AVKey.SPEED)!! * actorValue.getAsDouble(AVKey.SPEEDMULT)!!)
|
||||
|
||||
walkCounter += 1
|
||||
|
||||
// Clamp veloX
|
||||
movementDelta.x = absClamp(movementDelta.x,
|
||||
actorValue.getAsDouble(AVKey.SPEED)!!
|
||||
* actorValue.getAsDouble(AVKey.SPEEDMULT)!!
|
||||
* Math.sqrt(scale))
|
||||
|
||||
// Heading flag
|
||||
if (left)
|
||||
walkHeading = LEFT
|
||||
else
|
||||
walkHeading = RIGHT
|
||||
|
||||
println("$walkCounter: ${movementDelta.x}")
|
||||
println("$walkCounter: ${readonly_totalX}")
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -168,15 +163,9 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
|
||||
(if (up) -1 else 1).toFloat() *
|
||||
absAxisVal
|
||||
|
||||
movementDelta.set(Vector2(0.0, readonly_totalY))
|
||||
applyForce(Vector2(0.0, readonly_totalY))
|
||||
|
||||
if (walkCounter <= WALK_FRAMES_TO_MAX_ACCEL) walkCounter += 1
|
||||
|
||||
// Clamp veloX
|
||||
movementDelta.y = absClamp(movementDelta.y,
|
||||
actorValue.getAsDouble(AVKey.SPEED)!! *
|
||||
actorValue.getAsDouble(AVKey.SPEEDMULT)!! *
|
||||
Math.sqrt(scale))
|
||||
}
|
||||
|
||||
private fun applyAccel(x: Int): Double {
|
||||
@@ -214,7 +203,6 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
|
||||
//veloX = 0f
|
||||
|
||||
walkCounter = 0
|
||||
movementDelta.zero()
|
||||
}
|
||||
|
||||
// stops; let the friction kick in by doing nothing to the velocity here
|
||||
@@ -241,7 +229,6 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
|
||||
///veloY = 0f
|
||||
|
||||
walkCounter = 0
|
||||
movementDelta.zero()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -260,9 +247,9 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
|
||||
var timedJumpCharge = init - init / len * jumpCounter
|
||||
if (timedJumpCharge < 0) timedJumpCharge = 0.0
|
||||
|
||||
val jumpAcc = pwr * timedJumpCharge * JUMP_ACCELERATION_MOD * Math.sqrt(scale)
|
||||
val jumpAcc = pwr * timedJumpCharge * JUMP_ACCELERATION_MOD * Math.sqrt(scale) // positive value
|
||||
|
||||
movementDelta.y -= jumpAcc
|
||||
applyForce(Vector2(0.0, -jumpAcc))
|
||||
}
|
||||
|
||||
// for mob ai:
|
||||
|
||||
@@ -85,8 +85,8 @@ class BasicDebugInfoWindow:UICanvas {
|
||||
+ (hitbox.pointedY / MapDrawer.TILE_SIZE).toInt().toString()
|
||||
+ ")")
|
||||
|
||||
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}")
|
||||
printLine(g, 3, "veloX reported $ccG${if (player.physSleep) "(sleep)" else player.moveDelta.x}")
|
||||
printLine(g, 4, "veloY reported $ccG${if (player.physSleep) "(sleep)" else player.moveDelta.y}")
|
||||
|
||||
printLineColumn(g, 2, 3, "veloX measured $ccG${xdelta}")
|
||||
printLineColumn(g, 2, 4, "veloY measured $ccG${ydelta}")
|
||||
|
||||
@@ -542,12 +542,18 @@ class Vector2 {
|
||||
*/
|
||||
operator fun not() = negate()
|
||||
|
||||
/**
|
||||
* Negates this [Vector2].
|
||||
* @return [Vector2] this vector
|
||||
*/
|
||||
operator fun unaryMinus() = negate()
|
||||
|
||||
/**
|
||||
* Negates this [Vector2].
|
||||
* @return [Vector2] this vector
|
||||
*/
|
||||
fun negate(): Vector2 {
|
||||
return Vector2(x * -1.0, y * -1.0)
|
||||
return Vector2(-x, -y)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user