corrected lighting bug where illuminant in front of the sun can take over the light level of the sun for a tile the illuminant occupies, ActorWithBody phys WIP

Former-commit-id: a1ce45eded6136464d0a2c02227c61ee8f2adcb2
Former-commit-id: e4af5a44eb79b4db85458c9233e43a6117797331
This commit is contained in:
Song Minjae
2016-05-05 17:11:01 +09:00
parent 1350ee0baf
commit 12876a5ce2
19 changed files with 205 additions and 163 deletions

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 441 B

After

Width:  |  Height:  |  Size: 441 B

View File

Before

Width:  |  Height:  |  Size: 878 B

After

Width:  |  Height:  |  Size: 878 B

View File

Before

Width:  |  Height:  |  Size: 305 B

After

Width:  |  Height:  |  Size: 305 B

View File

Before

Width:  |  Height:  |  Size: 102 B

After

Width:  |  Height:  |  Size: 102 B

View File

Before

Width:  |  Height:  |  Size: 902 B

After

Width:  |  Height:  |  Size: 902 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -0,0 +1,15 @@
## Colour overlay ##
Colour overlay is set to 6 500 K as untouched. The value must be
* Increased when:
- Overcast (~ 7 000 K)
- Freezing area (~ 7 500 K)
* Decreased when:
- Tropical area (~ 5 500 K)
## Sunlight ##
Sunlight of the midday must have colour temperature of 5 700 K.

View File

@@ -94,7 +94,7 @@ constructor() : BasicGameState() {
shaderBlurV = Shader.makeShader("./res/blurV.vrt", "./res/blur.frg") shaderBlurV = Shader.makeShader("./res/blurV.vrt", "./res/blur.frg")
GRADIENT_IMAGE = Image("res/graphics/sky_colour.png") GRADIENT_IMAGE = Image("res/graphics/colourmap/sky_colour.png")
skyBox = Rectangle(0f, 0f, Terrarum.WIDTH.toFloat(), Terrarum.HEIGHT.toFloat()) skyBox = Rectangle(0f, 0f, Terrarum.WIDTH.toFloat(), Terrarum.HEIGHT.toFloat())
TilePropCodex() TilePropCodex()

View File

@@ -20,6 +20,7 @@ object AVKey {
const val ENCUMBRANCE = "encumbrance" const val ENCUMBRANCE = "encumbrance"
const val LUMINOSITY = "luminosity" const val LUMINOSITY = "luminosity"
const val PHYSIQUEMULT = "physique$MULT" const val PHYSIQUEMULT = "physique$MULT"
const val DRAGCOEFF = "dragcoeff"
const val NAME = "name" const val NAME = "name"

View File

@@ -35,13 +35,13 @@ 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.
*/ */
val velocity = ChainedVector2(0.0, 0.0) internal val positioningDelta = Vector2(0.0, 0.0)
var veloX: Double var veloX: Double
get() = velocity.x get() = positioningDelta.x
set(value) { velocity.x = value } private set(value) { positioningDelta.x = value }
var veloY: Double var veloY: Double
get() = velocity.y get() = positioningDelta.y
set(value) { velocity.y = value } private set(value) { positioningDelta.y = value }
@Transient private val VELO_HARD_LIMIT = 10000.0 @Transient private val VELO_HARD_LIMIT = 10000.0
var grounded = false var grounded = false
@@ -92,14 +92,14 @@ open class ActorWithBody constructor() : Actor(), Visible {
set(value) { set(value) {
if (value < 0) if (value < 0)
throw IllegalArgumentException("[ActorWithBody] Invalid elasticity value: $value; valid elasticity value is [0, 1].") throw IllegalArgumentException("[ActorWithBody] Invalid elasticity value: $value; valid elasticity value is [0, 1].")
else if (value > 1) { else if (value >= ELASTICITY_MAX) {
println("[ActorWithBody] Elasticity were capped to 1.") println("[ActorWithBody] Elasticity were capped to $ELASTICITY_MAX.")
field = ELASTICITY_MAX field = ELASTICITY_MAX
} }
else else
field = value * ELASTICITY_MAX field = value * ELASTICITY_MAX
} }
@Transient private val ELASTICITY_MAX = 0.993 @Transient private val ELASTICITY_MAX = 0.993 // No perpetual motion!
private var density = 1000.0 private var density = 1000.0
/** /**
@@ -119,7 +119,15 @@ open class ActorWithBody constructor() : Actor(), Visible {
@Transient private val SI_TO_GAME_VEL = METER / Terrarum.TARGET_FPS @Transient private val SI_TO_GAME_VEL = METER / Terrarum.TARGET_FPS
@Transient private var gravitation: Vector2 = map.gravitation @Transient private var gravitation: Vector2 = map.gravitation
@Transient private val DRAG_COEFF = 1.0 @Transient val DRAG_COEFF_DEFAULT = 1.2
/** Drag coeffisient. Parachutes have much higher value than bare body (1.2) */
private var DRAG_COEFF: Double
get() = actorValue.getAsDouble(AVKey.DRAGCOEFF) ?: DRAG_COEFF_DEFAULT
set(value) {
if (value < 0)
throw IllegalArgumentException("[ActorWithBody] drag coefficient cannot be negative.")
actorValue[AVKey.DRAGCOEFF] = value
}
@Transient private val CONTACT_AREA_TOP = 0 @Transient private val CONTACT_AREA_TOP = 0
@Transient private val CONTACT_AREA_RIGHT = 1 @Transient private val CONTACT_AREA_RIGHT = 1
@@ -158,7 +166,7 @@ open class ActorWithBody constructor() : Actor(), Visible {
@Transient private var posAdjustX = 0 @Transient private var posAdjustX = 0
@Transient private var posAdjustY = 0 @Transient private var posAdjustY = 0
@Transient private val BASE_FRICTION = 0.3 @Transient internal val BASE_FRICTION = 0.3
@Transient val KINEMATIC = 1 @Transient val KINEMATIC = 1
@Transient val DYNAMIC = 2 @Transient val DYNAMIC = 2
@@ -168,6 +176,10 @@ open class ActorWithBody constructor() : Actor(), Visible {
private val CCD_THRE = 1.0 private val CCD_THRE = 1.0
private val CCD_TICK = 0.125 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 { init {
} }
@@ -230,9 +242,6 @@ open class ActorWithBody constructor() : Actor(), Visible {
baseSpriteWidth = sprite!!.width baseSpriteWidth = sprite!!.width
} }
// copy gravitational constant from the map the actor is in
gravitation = map.gravitation
/** /**
* Actual physics thing (altering velocity) starts from here * Actual physics thing (altering velocity) starts from here
*/ */
@@ -242,6 +251,8 @@ open class ActorWithBody constructor() : Actor(), Visible {
//applyBuoyancy() //applyBuoyancy()
} }
positioningDelta.set(movementDelta + externalDelta + gravityDelta)
// hard limit velocity // hard limit velocity
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
@@ -290,18 +301,19 @@ open class ActorWithBody constructor() : Actor(), Visible {
* W = mass * G (9.8 [m/s^2]) * W = mass * G (9.8 [m/s^2])
*/ */
val W: Vector2 = gravitation * mass val W: Vector2 = gravitation * mass
/**
* Area
*/
val A: Double = scale * scale
/** /**
* Drag of atmosphere * Drag of atmosphere
* D = Cd (drag coefficient) * 0.5 * rho (density) * V^2 (velocity) * A (area) * D = Cd (drag coefficient) * 0.5 * rho (density) * V^2 (velocity) * A (area)
*/ */
// TODO replace 1.292 with fluid tile density val D: Vector2 = (gravityDelta + movementDelta) * DRAG_COEFF * 0.5 * A * tileDensityFluid.toDouble()
val A: Double = scale * scale
val D: Vector2 = velocity.copy().toVector() * DRAG_COEFF * 0.5 * 1.292 * A
//veloY += (W - D) / mass * SI_TO_GAME_ACC
val V: Vector2 = (W - D) / mass * SI_TO_GAME_ACC val V: Vector2 = (W - D) / mass * SI_TO_GAME_ACC
veloX += V.x
veloY += V.y gravityDelta += V
} }
} }
@@ -335,12 +347,14 @@ open class ActorWithBody constructor() : Actor(), Visible {
if (isColliding(CONTACT_AREA_BOTTOM)) { // the ground has dug into the body if (isColliding(CONTACT_AREA_BOTTOM)) { // the ground has dug into the body
adjustHitBottom() adjustHitBottom()
veloY = 0.0 // reset veloY, simulating normal force veloY = 0.0 // reset veloY, simulating normal force
elasticReflectY() gravityDelta.zero()
hitAndReflectY()
grounded = true grounded = true
} }
else if (isColliding(CONTACT_AREA_BOTTOM, 0, 1)) { // the actor is standing ON the ground else if (isColliding(CONTACT_AREA_BOTTOM, 0, 1)) { // the actor is standing ON the ground
veloY = 0.0 // reset veloY, simulating normal force veloY = 0.0 // reset veloY, simulating normal force
elasticReflectY() gravityDelta.zero()
hitAndReflectY()
grounded = true grounded = true
} }
else { // the actor is not grounded at all else { // the actor is not grounded at all
@@ -352,11 +366,11 @@ open class ActorWithBody constructor() : Actor(), Visible {
if (isColliding(CONTACT_AREA_TOP)) { // the ceiling has dug into the body if (isColliding(CONTACT_AREA_TOP)) { // the ceiling has dug into the body
adjustHitTop() adjustHitTop()
veloY = 0.0 // reset veloY, simulating normal force veloY = 0.0 // reset veloY, simulating normal force
elasticReflectY() hitAndReflectY()
} }
else if (isColliding(CONTACT_AREA_TOP, 0, -1)) { // the actor is touching the ceiling else if (isColliding(CONTACT_AREA_TOP, 0, -1)) { // the actor is touching the ceiling
veloY = 0.0 // reset veloY, simulating normal force veloY = 0.0 // reset veloY, simulating normal force
elasticReflectY() // reflect on ceiling, for reversed gravity hitAndReflectY() // reflect on ceiling, for reversed gravity
} }
else { // the actor is not grounded at all else { // the actor is not grounded at all
} }
@@ -409,12 +423,12 @@ open class ActorWithBody constructor() : Actor(), Visible {
// the actor is embedded to the wall // the actor is embedded to the wall
adjustHitRight() adjustHitRight()
veloX = 0.0 // reset veloX, simulating normal force veloX = 0.0 // reset veloX, simulating normal force
elasticReflectX() hitAndReflectX()
} }
else if (isColliding(CONTACT_AREA_RIGHT, 2, 0) && !isColliding(CONTACT_AREA_LEFT, 0, 0)) { // offset by +1, to fix directional quarks else if (isColliding(CONTACT_AREA_RIGHT, 2, 0) && !isColliding(CONTACT_AREA_LEFT, 0, 0)) { // offset by +1, to fix directional quarks
// the actor is touching the wall // the actor is touching the wall
veloX = 0.0 // reset veloX, simulating normal force veloX = 0.0 // reset veloX, simulating normal force
elasticReflectX() hitAndReflectX()
} }
else { else {
} }
@@ -425,12 +439,12 @@ open class ActorWithBody constructor() : Actor(), Visible {
// the actor is embedded to the wall // the actor is embedded to the wall
adjustHitLeft() adjustHitLeft()
veloX = 0.0 // reset veloX, simulating normal force veloX = 0.0 // reset veloX, simulating normal force
elasticReflectX() hitAndReflectX()
} }
else if (isColliding(CONTACT_AREA_LEFT, -1, 0) && !isColliding(CONTACT_AREA_RIGHT, 1, 0)) { else if (isColliding(CONTACT_AREA_LEFT, -1, 0) && !isColliding(CONTACT_AREA_RIGHT, 1, 0)) {
// the actor is touching the wall // the actor is touching the wall
veloX = 0.0 // reset veloX, simulating normal force veloX = 0.0 // reset veloX, simulating normal force
elasticReflectX() hitAndReflectX()
} }
else { else {
} }
@@ -503,14 +517,10 @@ open class ActorWithBody constructor() : Actor(), Visible {
if (!isNoCollideWorld) { if (!isNoCollideWorld) {
// axis Y // axis Y
if (veloY >= 0) { // check downward if (veloY >= 0) { // check downward
if (isColliding(CONTACT_AREA_BOTTOM)) { // the ground has dug into the body if (isColliding(CONTACT_AREA_BOTTOM) || isColliding(CONTACT_AREA_BOTTOM, 0, 1)) {
veloY = 0.0 // reset veloY, simulating normal force // the actor is hitting the ground
elasticReflectY() //veloY = 0.0 // reset veloY, simulating normal force
grounded = true hitAndReflectY()
}
else if (isColliding(CONTACT_AREA_BOTTOM, 0, 1)) { // the actor is standing ON the ground
veloY = 0.0 // reset veloY, simulating normal force
elasticReflectY()
grounded = true grounded = true
} }
else { // the actor is not grounded at all else { // the actor is not grounded at all
@@ -519,43 +529,32 @@ open class ActorWithBody constructor() : Actor(), Visible {
} }
else if (veloY < 0) { // check upward else if (veloY < 0) { // check upward
grounded = false grounded = false
if (isColliding(CONTACT_AREA_TOP)) { // the ceiling has dug into the body if (isColliding(CONTACT_AREA_TOP) || isColliding(CONTACT_AREA_TOP, 0, -1)) {
veloY = 0.0 // reset veloY, simulating normal force // the actor is hitting the ceiling
elasticReflectY() //veloY = 0.0 // reset veloY, simulating normal force
} hitAndReflectY()
else if (isColliding(CONTACT_AREA_TOP, 0, -1)) { // the actor is touching the ceiling
veloY = 0.0 // reset veloY, simulating normal force
elasticReflectY() // reflect on ceiling, for reversed gravity
} }
else { // the actor is not grounded at all else { // the actor is not grounded at all
} }
} }
// axis X // axis X
if (veloX >= 0.5) { // check right if (veloX >= 0.5) { // check right
if (isColliding(CONTACT_AREA_RIGHT) && !isColliding(CONTACT_AREA_LEFT)) { if ((isColliding(CONTACT_AREA_RIGHT) && !isColliding(CONTACT_AREA_LEFT))
// the actor is embedded to the wall || (isColliding(CONTACT_AREA_RIGHT, 1, 0) && !isColliding(CONTACT_AREA_LEFT, 0, -1))) {
veloX = 0.0 // reset veloX, simulating normal force // the actor is hitting the right wall
elasticReflectX() //veloX = 0.0 // reset veloX, simulating normal force
} hitAndReflectX()
else if (isColliding(CONTACT_AREA_RIGHT, 2, 0) && !isColliding(CONTACT_AREA_LEFT, 0, 0)) { // offset by +1, to fix directional quarks
// the actor is touching the wall
veloX = 0.0 // reset veloX, simulating normal force
elasticReflectX()
} }
else { else {
} }
} }
else if (veloX <= -0.5) { // check left else if (veloX <= -0.5) { // check left
// System.out.println("collidingleft"); // System.out.println("collidingleft");
if (isColliding(CONTACT_AREA_LEFT) && !isColliding(CONTACT_AREA_RIGHT)) { if ((isColliding(CONTACT_AREA_LEFT) && !isColliding(CONTACT_AREA_RIGHT))
// the actor is embedded to the wall || (isColliding(CONTACT_AREA_LEFT, -1, 0) && !isColliding(CONTACT_AREA_RIGHT, 1, 0))) {
veloX = 0.0 // reset veloX, simulating normal force // the actor is hitting the left wall
elasticReflectX() //veloX = 0.0 // reset veloX, simulating normal force
} hitAndReflectX()
else if (isColliding(CONTACT_AREA_LEFT, -1, 0) && !isColliding(CONTACT_AREA_RIGHT, 1, 0)) {
// the actor is touching the wall
veloX = 0.0 // reset veloX, simulating normal force
elasticReflectX()
} }
else { else {
} }
@@ -565,17 +564,22 @@ open class ActorWithBody constructor() : Actor(), Visible {
} }
} }
private fun elasticReflectX() { private fun hitAndReflectX() {
if (veloX != 0.0 && (veloX * elasticity).abs() > 0.5) { if ((veloX * elasticity).abs() > SLEEP_THRE) {
veloX = -veloX * elasticity veloX = -veloX * elasticity
}
else {
veloX = 0.0
} }
} }
private fun elasticReflectY() { private fun hitAndReflectY() {
if (veloY != 0.0 && (veloY * elasticity).abs() > 0.5) { if ((veloY * elasticity).abs() > SLEEP_THRE) {
veloY = -veloY * elasticity veloY = -veloY * elasticity
} }
else {
veloY = 0.0
}
} }
private fun isColliding(side: Int, tx: Int = 0, ty: Int = 0): Boolean = getContactingArea(side, tx, ty) > 1 private fun isColliding(side: Int, tx: Int = 0, ty: Int = 0): Boolean = getContactingArea(side, tx, ty) > 1
@@ -689,11 +693,11 @@ open class ActorWithBody constructor() : Actor(), Visible {
* Get highest friction value from feet tiles. * Get highest friction value from feet tiles.
* @return * @return
*/ */
private val tileFriction: Int internal val tileFriction: Int
get() { get() {
var friction = 0 var friction = 0
//get highest friction // take highest value
val tilePosXStart = (hitbox.posX / TSIZE).roundToInt() val tilePosXStart = (hitbox.posX / TSIZE).roundToInt()
val tilePosXEnd = (hitbox.hitboxEnd.x / TSIZE).roundToInt() val tilePosXEnd = (hitbox.hitboxEnd.x / TSIZE).roundToInt()
val tilePosY = (hitbox.pointedY.plus(1) / TSIZE).roundToInt() val tilePosY = (hitbox.pointedY.plus(1) / TSIZE).roundToInt()
@@ -708,6 +712,30 @@ open class ActorWithBody constructor() : Actor(), Visible {
} }
fun Int.tileFrictionToMult() = this / 16.0 fun Int.tileFrictionToMult() = this / 16.0
/**
* Get highest tile density from occupying tiles, fluid only
*/
private val tileDensityFluid: Int
get() {
var density = 0
// take highest value
val tilePosXStart = (hitbox.posX / TSIZE).roundToInt()
val tilePosXEnd = (hitbox.hitboxEnd.x / TSIZE).roundToInt()
val tilePosYStart = (hitbox.posY / TSIZE).roundToInt()
val tilePosYEnd = (hitbox.hitboxEnd.y / TSIZE).roundToInt()
for (y in tilePosXStart..tilePosYEnd) {
for (x in tilePosXStart..tilePosXEnd) {
val tile = map.getTileFromTerrain(x, y)
val prop = TilePropCodex.getProp(tile)
if (prop.isFluid && prop.density > density)
density = prop.density
}
}
return density
}
/** /**
* Get highest density (specific gravity) value from tiles that the body occupies. * Get highest density (specific gravity) value from tiles that the body occupies.
* @return * @return

View File

@@ -6,6 +6,8 @@ import net.torvald.terrarum.gamecontroller.KeyMap
import net.torvald.terrarum.mapdrawer.MapDrawer import net.torvald.terrarum.mapdrawer.MapDrawer
import net.torvald.terrarum.Terrarum import net.torvald.terrarum.Terrarum
import net.torvald.spriteanimation.SpriteAnimation import net.torvald.spriteanimation.SpriteAnimation
import org.dyn4j.geometry.ChainedVector2
import org.dyn4j.geometry.Vector2
import org.lwjgl.input.Controller import org.lwjgl.input.Controller
import org.lwjgl.input.Controllers import org.lwjgl.input.Controllers
import org.newdawn.slick.GameContainer import org.newdawn.slick.GameContainer
@@ -33,8 +35,10 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
var vehicleRiding: Controllable? = null var vehicleRiding: Controllable? = null
/** how long the jump button has down, in frames */
internal var jumpCounter = 0 internal var jumpCounter = 0
internal var walkPowerCounter = 0 /** how long the walk button has down, in frames */
internal var walkCounter = 0
@Transient private val MAX_JUMP_LENGTH = 17 // use 17; in internal frames @Transient private val MAX_JUMP_LENGTH = 17 // use 17; in internal frames
private var readonly_totalX = 0.0 private var readonly_totalX = 0.0
@@ -115,30 +119,38 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
* @param absAxisVal (set AXIS_POSMAX if keyboard controlled) * @param absAxisVal (set AXIS_POSMAX if keyboard controlled)
*/ */
private fun walkHorizontal(left: Boolean, absAxisVal: Float) { private fun walkHorizontal(left: Boolean, absAxisVal: Float) {
readonly_totalX = veloX + readonly_totalX = //veloX +
actorValue.getAsDouble(AVKey.ACCEL)!! * /*actorValue.getAsDouble(AVKey.ACCEL)!! *
actorValue.getAsDouble(AVKey.ACCELMULT)!! * actorValue.getAsDouble(AVKey.ACCELMULT)!! *
Math.sqrt(scale) * Math.sqrt(scale) *
applyAccelRealism(walkPowerCounter) * applyAccelRealism(walkPowerCounter) *
(if (left) -1 else 1).toFloat() * (if (left) -1 else 1).toFloat() *
absAxisVal absAxisVal*/
actorValue.getAsDouble(AVKey.ACCEL)!! *
actorValue.getAsDouble(AVKey.ACCELMULT)!! *
Math.sqrt(scale) *
applyVelo(walkCounter) *
(if (left) -1 else 1).toFloat() *
absAxisVal
veloX = readonly_totalX // veloX = readonly_totalX
movementDelta += Vector2(readonly_totalX, 0.0)
if (walkPowerCounter < WALK_FRAMES_TO_MAX_ACCEL) { walkCounter += 1
walkPowerCounter += 1
}
// Clamp veloX // Clamp veloX
veloX = absClamp(veloX, actorValue.getAsDouble(AVKey.SPEED)!! movementDelta.x = absClamp(movementDelta.x,
* actorValue.getAsDouble(AVKey.SPEEDMULT)!! actorValue.getAsDouble(AVKey.SPEED)!!
* Math.sqrt(scale)) * actorValue.getAsDouble(AVKey.SPEEDMULT)!!
* Math.sqrt(scale))
// Heading flag // Heading flag
if (left) if (left)
walkHeading = LEFT walkHeading = LEFT
else else
walkHeading = RIGHT walkHeading = RIGHT
println("$walkCounter: ${movementDelta.x}")
} }
/** /**
@@ -148,51 +160,35 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
* @param absAxisVal (set AXIS_POSMAX if keyboard controlled) * @param absAxisVal (set AXIS_POSMAX if keyboard controlled)
*/ */
private fun walkVertical(up: Boolean, absAxisVal: Float) { private fun walkVertical(up: Boolean, absAxisVal: Float) {
readonly_totalY = veloY + readonly_totalY =
actorValue.getAsDouble(AVKey.ACCEL)!! * actorValue.getAsDouble(AVKey.ACCEL)!! *
actorValue.getAsDouble(AVKey.ACCELMULT)!! * actorValue.getAsDouble(AVKey.ACCELMULT)!! *
Math.sqrt(scale) * Math.sqrt(scale) *
applyAccelRealism(walkPowerCounter) * applyVelo(walkCounter) *
(if (up) -1 else 1).toFloat() * (if (up) -1 else 1).toFloat() *
absAxisVal absAxisVal
veloY = readonly_totalY movementDelta.set(Vector2(0.0, readonly_totalY))
if (walkPowerCounter < WALK_FRAMES_TO_MAX_ACCEL) { if (walkCounter <= WALK_FRAMES_TO_MAX_ACCEL) walkCounter += 1
walkPowerCounter += 1
}
// Clamp veloX // Clamp veloX
veloY = absClamp(veloY, actorValue.getAsDouble(AVKey.SPEED)!! movementDelta.y = absClamp(movementDelta.y,
* actorValue.getAsDouble(AVKey.SPEEDMULT)!! actorValue.getAsDouble(AVKey.SPEED)!! *
* Math.sqrt(scale)) actorValue.getAsDouble(AVKey.SPEEDMULT)!! *
Math.sqrt(scale))
} }
/** private fun applyAccel(x: Int): Double {
* For realistic accelerating while walking. return if (x < WALK_FRAMES_TO_MAX_ACCEL)
Math.sin(Math.PI * x / WALK_FRAMES_TO_MAX_ACCEL)
else 0.0
}
* Naïve 'veloX += 3' is actually like: private fun applyVelo(x: Int): Double {
return if (x < WALK_FRAMES_TO_MAX_ACCEL)
* a 0.5 - 0.5 * Math.cos(Math.PI * x / WALK_FRAMES_TO_MAX_ACCEL)
* | ------------ else 1.0
* |
* |
* 0+------············ t
* which is unrealistic, so this method tries to introduce some realism by doing:
* a
* | ------------
* | ---
* | -
* | ---
* 0+----··················· t
* @param x
*/
private fun applyAccelRealism(x: Int): Double {
return 0.5 + 0.5 * -Math.cos(10 * x / (WALK_FRAMES_TO_MAX_ACCEL * Math.PI))
} }
// stops; let the friction kick in by doing nothing to the velocity here // stops; let the friction kick in by doing nothing to the velocity here
@@ -217,7 +213,8 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
//veloX = 0f //veloX = 0f
walkPowerCounter = 0 walkCounter = 0
movementDelta.zero()
} }
// stops; let the friction kick in by doing nothing to the velocity here // stops; let the friction kick in by doing nothing to the velocity here
@@ -243,7 +240,36 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
///veloY = 0f ///veloY = 0f
walkPowerCounter = 0 walkCounter = 0
movementDelta.zero()
}
/**
* See ./work_files/Jump\ power\ by\ pressing\ time.gcx
*/
private fun jump() {
if (jumping) {
val len = MAX_JUMP_LENGTH.toFloat()
val pwr = actorValue.getAsDouble(AVKey.JUMPPOWER)!! * (actorValue.getAsDouble(AVKey.JUMPPOWERMULT) ?: 1.0)
// increment jump counter
if (jumpCounter < len) jumpCounter += 1
// linear time mode
val init = (len + 1) / 2.0
var timedJumpCharge = init - init / len * jumpCounter
if (timedJumpCharge < 0) timedJumpCharge = 0.0
val jumpAcc = pwr * timedJumpCharge * JUMP_ACCELERATION_MOD * Math.sqrt(scale)
movementDelta.y -= jumpAcc
}
// for mob ai:
//super.setVeloY(veloY
// -
// pwr * Math.sqrt(scale)
//);
} }
private fun updateMovementControl() { private fun updateMovementControl() {
@@ -391,34 +417,6 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
} }
/**
* See ./work_files/Jump\ power\ by\ pressing\ time.gcx
*/
private fun jump() {
if (jumping) {
val len = MAX_JUMP_LENGTH.toFloat()
val pwr = actorValue.getAsDouble(AVKey.JUMPPOWER)!! * (actorValue.getAsDouble(AVKey.JUMPPOWERMULT) ?: 1.0)
// increment jump counter
if (jumpCounter < len) jumpCounter += 1
// linear time mode
val init = (len + 1) / 2.0
var timedJumpCharge = init - init / len * jumpCounter
if (timedJumpCharge < 0) timedJumpCharge = 0.0
val jumpAcc = pwr * timedJumpCharge * JUMP_ACCELERATION_MOD * Math.sqrt(scale)
veloY -= jumpAcc
}
// for mob ai:
//super.setVeloY(veloY
// -
// pwr * Math.sqrt(scale)
//);
}
private fun isFuncDown(input: Input, fn: EnumKeyFunc): Boolean { private fun isFuncDown(input: Input, fn: EnumKeyFunc): Boolean {
return input.isKeyDown(KeyMap.getKeyCode(fn)) return input.isKeyDown(KeyMap.getKeyCode(fn))
} }

View File

@@ -127,10 +127,10 @@ object CollisionSolver {
val vy_1 = (uy_2 * (m1 - m2) + 2 * m2 * uy_2) / (m1 + m2) val vy_1 = (uy_2 * (m1 - m2) + 2 * m2 * uy_2) / (m1 + m2)
val vy_2 = (uy_2 * (m2 - m1) + 2 * m1 * uy_1) / (m1 + m2) val vy_2 = (uy_2 * (m2 - m1) + 2 * m1 * uy_1) / (m1 + m2)
a.veloX = vx_1 /*a.veloX = vx_1
a.veloY = vy_1 a.veloY = vy_1
b.veloX = vx_2 b.veloX = vx_2
b.veloY = vy_2 b.veloY = vy_2*/
} }
} }
} }

View File

@@ -32,7 +32,7 @@ constructor(//properties
//public World physWorld = new World( new Vec2(0, -TerrarumMain.game.gravitationalAccel) ); //public World physWorld = new World( new Vec2(0, -TerrarumMain.game.gravitationalAccel) );
//physics //physics
/** \[m / s^2\] */ /** Meter per second squared. Currently only the downward gravity is supported. No reverse gravity :p */
var gravitation: Vector2 = Vector2(0.0, 9.8) var gravitation: Vector2 = Vector2(0.0, 9.8)
/** RGB in Integer */ /** RGB in Integer */
var globalLight: Int = 0 var globalLight: Int = 0

View File

@@ -229,8 +229,7 @@ object LightmapRenderer {
} }
// luminous tile on top of air // luminous tile on top of air
else if (thisWall == AIR && thisTileLuminosity.toInt() > 0) { else if (thisWall == AIR && thisTileLuminosity.toInt() > 0) {
val darkenSunlight = darkenColoured(sunLight, thisTileOpacity) lightLevelThis = maximiseRGB(sunLight, thisTileLuminosity) // maximise to not exceed 1.0 with normal (<= 1.0) light
lightLevelThis = maximiseRGB(darkenSunlight, thisTileLuminosity) // maximise to not exceed 1.0 with normal (<= 1.0) light
} }
// opaque wall and luminous tile // opaque wall and luminous tile
else if (thisWall != AIR && thisTileLuminosity.toInt() > 0) { else if (thisWall != AIR && thisTileLuminosity.toInt() > 0) {

View File

@@ -13,12 +13,12 @@ import org.newdawn.slick.*
object MapDrawer { object MapDrawer {
const val TILE_SIZE = 16 const val TILE_SIZE = 16
private var envOverlayColourmap: Image = Image("./res/graphics/black_body_col_1000_40000_K.png") private var envOverlayColourmap: Image = Image("./res/graphics/colourmap/black_body_col_1000_40000_K.png")
private val ENV_COLTEMP_LOWEST = 5500 private val ENV_COLTEMP_LOWEST = 5500
private val ENV_COLTEMP_HIGHEST = 7500 private val ENV_COLTEMP_HIGHEST = 7500
val ENV_COLTEMP_NOON = 6500 val ENV_COLTEMP_NOON = 6500 // 6500 == sRGB White == untouched!
private var colTemp: Int = 0 private var colTemp: Int = 0

View File

@@ -378,7 +378,7 @@ class ChainedVector2 {
* * * *
* @return [ChainedVector2] this vector * @return [ChainedVector2] this vector
*/ */
operator fun plus(vector: ChainedVector2): ChainedVector2 { fun plus(vector: ChainedVector2): ChainedVector2 {
this.x += vector.x this.x += vector.x
this.y += vector.y this.y += vector.y
return this return this
@@ -428,7 +428,7 @@ class ChainedVector2 {
* * * *
* @return [ChainedVector2] this vector * @return [ChainedVector2] this vector
*/ */
operator fun minus(vector: ChainedVector2): ChainedVector2 { fun minus(vector: ChainedVector2): ChainedVector2 {
this.x -= vector.x this.x -= vector.x
this.y -= vector.y this.y -= vector.y
return this return this
@@ -500,7 +500,7 @@ class ChainedVector2 {
* * * *
* @return [ChainedVector2] this vector * @return [ChainedVector2] this vector
*/ */
operator fun times(scalar: Double): ChainedVector2 { fun times(scalar: Double): ChainedVector2 {
this.x *= scalar this.x *= scalar
this.y *= scalar this.y *= scalar
return this return this
@@ -512,7 +512,7 @@ class ChainedVector2 {
* * * *
* @return [ChainedVector2] this vector * @return [ChainedVector2] this vector
*/ */
operator fun div(scalar: Double): ChainedVector2 { fun div(scalar: Double): ChainedVector2 {
this.x /= scalar this.x /= scalar
this.y /= scalar this.y /= scalar
return this return this
@@ -525,7 +525,7 @@ class ChainedVector2 {
* * * *
* @return [ChainedVector2] * @return [ChainedVector2]
*/ */
infix fun product(scalar: Double): ChainedVector2 { fun product(scalar: Double): ChainedVector2 {
return ChainedVector2(this.x * scalar, this.y * scalar) return ChainedVector2(this.x * scalar, this.y * scalar)
} }
@@ -536,7 +536,7 @@ class ChainedVector2 {
* * * *
* @return double * @return double
*/ */
infix fun dot(vector: ChainedVector2): Double { fun dot(vector: ChainedVector2): Double {
return this.x * vector.x + this.y * vector.y return this.x * vector.x + this.y * vector.y
} }
@@ -559,7 +559,7 @@ class ChainedVector2 {
* * * *
* @return double * @return double
*/ */
infix fun cross(vector: ChainedVector2): Double { fun cross(vector: ChainedVector2): Double {
return this.x * vector.y - this.y * vector.x return this.x * vector.y - this.y * vector.x
} }
@@ -581,7 +581,7 @@ class ChainedVector2 {
* * * *
* @return [ChainedVector2] * @return [ChainedVector2]
*/ */
infix fun cross(z: Double): ChainedVector2 { fun cross(z: Double): ChainedVector2 {
return ChainedVector2(-1.0 * this.y * z, this.x * z) return ChainedVector2(-1.0 * this.y * z, this.x * z)
} }
@@ -628,7 +628,7 @@ class ChainedVector2 {
* Negates this [ChainedVector2]. * Negates this [ChainedVector2].
* @return [ChainedVector2] this vector * @return [ChainedVector2] this vector
*/ */
operator fun not() = negate() fun not() = negate()
/** /**
* Negates this [ChainedVector2]. * Negates this [ChainedVector2].
@@ -663,7 +663,7 @@ class ChainedVector2 {
* * * *
* @return [ChainedVector2] this vector * @return [ChainedVector2] this vector
*/ */
infix fun rotate(theta: Double): ChainedVector2 { fun rotate(theta: Double): ChainedVector2 {
val cos = Math.cos(theta) val cos = Math.cos(theta)
val sin = Math.sin(theta) val sin = Math.sin(theta)
val x = this.x val x = this.x

View File

@@ -0,0 +1 @@
*.{psd,tga,ogg} filter=lfs diff=lfs merge=lfs -text