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:
Song Minjae
2016-05-08 01:29:52 +09:00
parent 12876a5ce2
commit 127e6344cf
5 changed files with 94 additions and 65 deletions

View File

@@ -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)
)

View File

@@ -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: