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
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 441 B After Width: | Height: | Size: 441 B |
|
Before Width: | Height: | Size: 878 B After Width: | Height: | Size: 878 B |
|
Before Width: | Height: | Size: 305 B After Width: | Height: | Size: 305 B |
|
Before Width: | Height: | Size: 102 B After Width: | Height: | Size: 102 B |
|
Before Width: | Height: | Size: 902 B After Width: | Height: | Size: 902 B |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 19 KiB |
15
src/net/torvald/terrarum/ENVIRON.md
Normal 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.
|
||||
@@ -94,7 +94,7 @@ constructor() : BasicGameState() {
|
||||
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())
|
||||
|
||||
TilePropCodex()
|
||||
|
||||
@@ -20,6 +20,7 @@ object AVKey {
|
||||
const val ENCUMBRANCE = "encumbrance"
|
||||
const val LUMINOSITY = "luminosity"
|
||||
const val PHYSIQUEMULT = "physique$MULT"
|
||||
const val DRAGCOEFF = "dragcoeff"
|
||||
|
||||
const val NAME = "name"
|
||||
|
||||
|
||||
@@ -35,13 +35,13 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
||||
* veloY += 3.0
|
||||
* +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
|
||||
get() = velocity.x
|
||||
set(value) { velocity.x = value }
|
||||
get() = positioningDelta.x
|
||||
private set(value) { positioningDelta.x = value }
|
||||
var veloY: Double
|
||||
get() = velocity.y
|
||||
set(value) { velocity.y = value }
|
||||
get() = positioningDelta.y
|
||||
private set(value) { positioningDelta.y = value }
|
||||
@Transient private val VELO_HARD_LIMIT = 10000.0
|
||||
|
||||
var grounded = false
|
||||
@@ -92,14 +92,14 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
||||
set(value) {
|
||||
if (value < 0)
|
||||
throw IllegalArgumentException("[ActorWithBody] Invalid elasticity value: $value; valid elasticity value is [0, 1].")
|
||||
else if (value > 1) {
|
||||
println("[ActorWithBody] Elasticity were capped to 1.")
|
||||
else if (value >= ELASTICITY_MAX) {
|
||||
println("[ActorWithBody] Elasticity were capped to $ELASTICITY_MAX.")
|
||||
field = ELASTICITY_MAX
|
||||
}
|
||||
else
|
||||
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
|
||||
|
||||
/**
|
||||
@@ -119,7 +119,15 @@ 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 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_RIGHT = 1
|
||||
@@ -158,7 +166,7 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
||||
@Transient private var posAdjustX = 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 DYNAMIC = 2
|
||||
@@ -168,6 +176,10 @@ 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 {
|
||||
|
||||
}
|
||||
@@ -230,9 +242,6 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
||||
baseSpriteWidth = sprite!!.width
|
||||
}
|
||||
|
||||
// copy gravitational constant from the map the actor is in
|
||||
gravitation = map.gravitation
|
||||
|
||||
/**
|
||||
* Actual physics thing (altering velocity) starts from here
|
||||
*/
|
||||
@@ -242,6 +251,8 @@ 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
|
||||
@@ -290,18 +301,19 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
||||
* W = mass * G (9.8 [m/s^2])
|
||||
*/
|
||||
val W: Vector2 = gravitation * mass
|
||||
/**
|
||||
* Area
|
||||
*/
|
||||
val A: Double = scale * scale
|
||||
/**
|
||||
* Drag of atmosphere
|
||||
* D = Cd (drag coefficient) * 0.5 * rho (density) * V^2 (velocity) * A (area)
|
||||
*/
|
||||
// TODO replace 1.292 with fluid tile density
|
||||
val A: Double = scale * scale
|
||||
val D: Vector2 = velocity.copy().toVector() * DRAG_COEFF * 0.5 * 1.292 * A
|
||||
val D: Vector2 = (gravityDelta + movementDelta) * DRAG_COEFF * 0.5 * A * tileDensityFluid.toDouble()
|
||||
|
||||
//veloY += (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
|
||||
adjustHitBottom()
|
||||
veloY = 0.0 // reset veloY, simulating normal force
|
||||
elasticReflectY()
|
||||
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
|
||||
elasticReflectY()
|
||||
gravityDelta.zero()
|
||||
hitAndReflectY()
|
||||
grounded = true
|
||||
}
|
||||
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
|
||||
adjustHitTop()
|
||||
veloY = 0.0 // reset veloY, simulating normal force
|
||||
elasticReflectY()
|
||||
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
|
||||
hitAndReflectY() // reflect on ceiling, for reversed gravity
|
||||
}
|
||||
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
|
||||
adjustHitRight()
|
||||
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
|
||||
// the actor is touching the wall
|
||||
veloX = 0.0 // reset veloX, simulating normal force
|
||||
elasticReflectX()
|
||||
hitAndReflectX()
|
||||
}
|
||||
else {
|
||||
}
|
||||
@@ -425,12 +439,12 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
||||
// the actor is embedded to the wall
|
||||
adjustHitLeft()
|
||||
veloX = 0.0 // reset veloX, simulating normal force
|
||||
elasticReflectX()
|
||||
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()
|
||||
hitAndReflectX()
|
||||
}
|
||||
else {
|
||||
}
|
||||
@@ -503,14 +517,10 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
||||
if (!isNoCollideWorld) {
|
||||
// axis Y
|
||||
if (veloY >= 0) { // check downward
|
||||
if (isColliding(CONTACT_AREA_BOTTOM)) { // the ground has dug into the body
|
||||
veloY = 0.0 // reset veloY, simulating normal force
|
||||
elasticReflectY()
|
||||
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
|
||||
elasticReflectY()
|
||||
if (isColliding(CONTACT_AREA_BOTTOM) || isColliding(CONTACT_AREA_BOTTOM, 0, 1)) {
|
||||
// the actor is hitting the ground
|
||||
//veloY = 0.0 // reset veloY, simulating normal force
|
||||
hitAndReflectY()
|
||||
grounded = true
|
||||
}
|
||||
else { // the actor is not grounded at all
|
||||
@@ -519,43 +529,32 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
||||
}
|
||||
else if (veloY < 0) { // check upward
|
||||
grounded = false
|
||||
if (isColliding(CONTACT_AREA_TOP)) { // the ceiling has dug into the body
|
||||
veloY = 0.0 // reset veloY, simulating normal force
|
||||
elasticReflectY()
|
||||
}
|
||||
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
|
||||
if (isColliding(CONTACT_AREA_TOP) || isColliding(CONTACT_AREA_TOP, 0, -1)) {
|
||||
// the actor is hitting the ceiling
|
||||
//veloY = 0.0 // reset veloY, simulating normal force
|
||||
hitAndReflectY()
|
||||
}
|
||||
else { // the actor is not grounded at all
|
||||
}
|
||||
}
|
||||
// axis X
|
||||
if (veloX >= 0.5) { // check right
|
||||
if (isColliding(CONTACT_AREA_RIGHT) && !isColliding(CONTACT_AREA_LEFT)) {
|
||||
// the actor is embedded to the wall
|
||||
veloX = 0.0 // reset veloX, simulating normal force
|
||||
elasticReflectX()
|
||||
}
|
||||
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()
|
||||
if ((isColliding(CONTACT_AREA_RIGHT) && !isColliding(CONTACT_AREA_LEFT))
|
||||
|| (isColliding(CONTACT_AREA_RIGHT, 1, 0) && !isColliding(CONTACT_AREA_LEFT, 0, -1))) {
|
||||
// the actor is hitting the right wall
|
||||
//veloX = 0.0 // reset veloX, simulating normal force
|
||||
hitAndReflectX()
|
||||
}
|
||||
else {
|
||||
}
|
||||
}
|
||||
else if (veloX <= -0.5) { // check left
|
||||
// System.out.println("collidingleft");
|
||||
if (isColliding(CONTACT_AREA_LEFT) && !isColliding(CONTACT_AREA_RIGHT)) {
|
||||
// the actor is embedded to the wall
|
||||
veloX = 0.0 // reset veloX, simulating normal force
|
||||
elasticReflectX()
|
||||
}
|
||||
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()
|
||||
if ((isColliding(CONTACT_AREA_LEFT) && !isColliding(CONTACT_AREA_RIGHT))
|
||||
|| (isColliding(CONTACT_AREA_LEFT, -1, 0) && !isColliding(CONTACT_AREA_RIGHT, 1, 0))) {
|
||||
// the actor is hitting the left wall
|
||||
//veloX = 0.0 // reset veloX, simulating normal force
|
||||
hitAndReflectX()
|
||||
}
|
||||
else {
|
||||
}
|
||||
@@ -565,17 +564,22 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
||||
}
|
||||
}
|
||||
|
||||
private fun elasticReflectX() {
|
||||
if (veloX != 0.0 && (veloX * elasticity).abs() > 0.5) {
|
||||
private fun hitAndReflectX() {
|
||||
if ((veloX * elasticity).abs() > SLEEP_THRE) {
|
||||
veloX = -veloX * elasticity
|
||||
|
||||
}
|
||||
else {
|
||||
veloX = 0.0
|
||||
}
|
||||
}
|
||||
|
||||
private fun elasticReflectY() {
|
||||
if (veloY != 0.0 && (veloY * elasticity).abs() > 0.5) {
|
||||
private fun hitAndReflectY() {
|
||||
if ((veloY * elasticity).abs() > SLEEP_THRE) {
|
||||
veloY = -veloY * elasticity
|
||||
}
|
||||
else {
|
||||
veloY = 0.0
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
* @return
|
||||
*/
|
||||
private val tileFriction: Int
|
||||
internal val tileFriction: Int
|
||||
get() {
|
||||
var friction = 0
|
||||
|
||||
//get highest friction
|
||||
// take highest value
|
||||
val tilePosXStart = (hitbox.posX / TSIZE).roundToInt()
|
||||
val tilePosXEnd = (hitbox.hitboxEnd.x / 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
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @return
|
||||
|
||||
@@ -6,6 +6,8 @@ import net.torvald.terrarum.gamecontroller.KeyMap
|
||||
import net.torvald.terrarum.mapdrawer.MapDrawer
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.spriteanimation.SpriteAnimation
|
||||
import org.dyn4j.geometry.ChainedVector2
|
||||
import org.dyn4j.geometry.Vector2
|
||||
import org.lwjgl.input.Controller
|
||||
import org.lwjgl.input.Controllers
|
||||
import org.newdawn.slick.GameContainer
|
||||
@@ -33,8 +35,10 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
|
||||
|
||||
var vehicleRiding: Controllable? = null
|
||||
|
||||
/** how long the jump button has down, in frames */
|
||||
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
|
||||
|
||||
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)
|
||||
*/
|
||||
private fun walkHorizontal(left: Boolean, absAxisVal: Float) {
|
||||
readonly_totalX = veloX +
|
||||
actorValue.getAsDouble(AVKey.ACCEL)!! *
|
||||
readonly_totalX = //veloX +
|
||||
/*actorValue.getAsDouble(AVKey.ACCEL)!! *
|
||||
actorValue.getAsDouble(AVKey.ACCELMULT)!! *
|
||||
Math.sqrt(scale) *
|
||||
applyAccelRealism(walkPowerCounter) *
|
||||
(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) {
|
||||
walkPowerCounter += 1
|
||||
}
|
||||
walkCounter += 1
|
||||
|
||||
// Clamp veloX
|
||||
veloX = absClamp(veloX, actorValue.getAsDouble(AVKey.SPEED)!!
|
||||
* actorValue.getAsDouble(AVKey.SPEEDMULT)!!
|
||||
* Math.sqrt(scale))
|
||||
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}")
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -148,51 +160,35 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
|
||||
* @param absAxisVal (set AXIS_POSMAX if keyboard controlled)
|
||||
*/
|
||||
private fun walkVertical(up: Boolean, absAxisVal: Float) {
|
||||
readonly_totalY = veloY +
|
||||
readonly_totalY =
|
||||
actorValue.getAsDouble(AVKey.ACCEL)!! *
|
||||
actorValue.getAsDouble(AVKey.ACCELMULT)!! *
|
||||
Math.sqrt(scale) *
|
||||
applyAccelRealism(walkPowerCounter) *
|
||||
(if (up) -1 else 1).toFloat() *
|
||||
absAxisVal
|
||||
actorValue.getAsDouble(AVKey.ACCELMULT)!! *
|
||||
Math.sqrt(scale) *
|
||||
applyVelo(walkCounter) *
|
||||
(if (up) -1 else 1).toFloat() *
|
||||
absAxisVal
|
||||
|
||||
veloY = readonly_totalY
|
||||
movementDelta.set(Vector2(0.0, readonly_totalY))
|
||||
|
||||
if (walkPowerCounter < WALK_FRAMES_TO_MAX_ACCEL) {
|
||||
walkPowerCounter += 1
|
||||
}
|
||||
if (walkCounter <= WALK_FRAMES_TO_MAX_ACCEL) walkCounter += 1
|
||||
|
||||
// Clamp veloX
|
||||
veloY = absClamp(veloY, actorValue.getAsDouble(AVKey.SPEED)!!
|
||||
* actorValue.getAsDouble(AVKey.SPEEDMULT)!!
|
||||
* Math.sqrt(scale))
|
||||
movementDelta.y = absClamp(movementDelta.y,
|
||||
actorValue.getAsDouble(AVKey.SPEED)!! *
|
||||
actorValue.getAsDouble(AVKey.SPEEDMULT)!! *
|
||||
Math.sqrt(scale))
|
||||
}
|
||||
|
||||
/**
|
||||
* For realistic accelerating while walking.
|
||||
private fun applyAccel(x: Int): Double {
|
||||
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:
|
||||
|
||||
* a
|
||||
* | ------------
|
||||
* |
|
||||
* |
|
||||
* 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))
|
||||
private fun applyVelo(x: Int): Double {
|
||||
return if (x < WALK_FRAMES_TO_MAX_ACCEL)
|
||||
0.5 - 0.5 * Math.cos(Math.PI * x / WALK_FRAMES_TO_MAX_ACCEL)
|
||||
else 1.0
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
walkPowerCounter = 0
|
||||
walkCounter = 0
|
||||
movementDelta.zero()
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
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() {
|
||||
@@ -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 {
|
||||
return input.isKeyDown(KeyMap.getKeyCode(fn))
|
||||
}
|
||||
|
||||
@@ -127,10 +127,10 @@ object CollisionSolver {
|
||||
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)
|
||||
|
||||
a.veloX = vx_1
|
||||
/*a.veloX = vx_1
|
||||
a.veloY = vy_1
|
||||
b.veloX = vx_2
|
||||
b.veloY = vy_2
|
||||
b.veloY = vy_2*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ constructor(//properties
|
||||
|
||||
//public World physWorld = new World( new Vec2(0, -TerrarumMain.game.gravitationalAccel) );
|
||||
//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)
|
||||
/** RGB in Integer */
|
||||
var globalLight: Int = 0
|
||||
|
||||
@@ -229,8 +229,7 @@ object LightmapRenderer {
|
||||
}
|
||||
// luminous tile on top of air
|
||||
else if (thisWall == AIR && thisTileLuminosity.toInt() > 0) {
|
||||
val darkenSunlight = darkenColoured(sunLight, thisTileOpacity)
|
||||
lightLevelThis = maximiseRGB(darkenSunlight, thisTileLuminosity) // maximise to not exceed 1.0 with normal (<= 1.0) light
|
||||
lightLevelThis = maximiseRGB(sunLight, thisTileLuminosity) // maximise to not exceed 1.0 with normal (<= 1.0) light
|
||||
}
|
||||
// opaque wall and luminous tile
|
||||
else if (thisWall != AIR && thisTileLuminosity.toInt() > 0) {
|
||||
|
||||
@@ -13,12 +13,12 @@ import org.newdawn.slick.*
|
||||
object MapDrawer {
|
||||
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_HIGHEST = 7500
|
||||
|
||||
val ENV_COLTEMP_NOON = 6500
|
||||
val ENV_COLTEMP_NOON = 6500 // 6500 == sRGB White == untouched!
|
||||
|
||||
private var colTemp: Int = 0
|
||||
|
||||
|
||||
@@ -378,7 +378,7 @@ class ChainedVector2 {
|
||||
* *
|
||||
* @return [ChainedVector2] this vector
|
||||
*/
|
||||
operator fun plus(vector: ChainedVector2): ChainedVector2 {
|
||||
fun plus(vector: ChainedVector2): ChainedVector2 {
|
||||
this.x += vector.x
|
||||
this.y += vector.y
|
||||
return this
|
||||
@@ -428,7 +428,7 @@ class ChainedVector2 {
|
||||
* *
|
||||
* @return [ChainedVector2] this vector
|
||||
*/
|
||||
operator fun minus(vector: ChainedVector2): ChainedVector2 {
|
||||
fun minus(vector: ChainedVector2): ChainedVector2 {
|
||||
this.x -= vector.x
|
||||
this.y -= vector.y
|
||||
return this
|
||||
@@ -500,7 +500,7 @@ class ChainedVector2 {
|
||||
* *
|
||||
* @return [ChainedVector2] this vector
|
||||
*/
|
||||
operator fun times(scalar: Double): ChainedVector2 {
|
||||
fun times(scalar: Double): ChainedVector2 {
|
||||
this.x *= scalar
|
||||
this.y *= scalar
|
||||
return this
|
||||
@@ -512,7 +512,7 @@ class ChainedVector2 {
|
||||
* *
|
||||
* @return [ChainedVector2] this vector
|
||||
*/
|
||||
operator fun div(scalar: Double): ChainedVector2 {
|
||||
fun div(scalar: Double): ChainedVector2 {
|
||||
this.x /= scalar
|
||||
this.y /= scalar
|
||||
return this
|
||||
@@ -525,7 +525,7 @@ class ChainedVector2 {
|
||||
* *
|
||||
* @return [ChainedVector2]
|
||||
*/
|
||||
infix fun product(scalar: Double): ChainedVector2 {
|
||||
fun product(scalar: Double): ChainedVector2 {
|
||||
return ChainedVector2(this.x * scalar, this.y * scalar)
|
||||
}
|
||||
|
||||
@@ -536,7 +536,7 @@ class ChainedVector2 {
|
||||
* *
|
||||
* @return double
|
||||
*/
|
||||
infix fun dot(vector: ChainedVector2): Double {
|
||||
fun dot(vector: ChainedVector2): Double {
|
||||
return this.x * vector.x + this.y * vector.y
|
||||
}
|
||||
|
||||
@@ -559,7 +559,7 @@ class ChainedVector2 {
|
||||
* *
|
||||
* @return double
|
||||
*/
|
||||
infix fun cross(vector: ChainedVector2): Double {
|
||||
fun cross(vector: ChainedVector2): Double {
|
||||
return this.x * vector.y - this.y * vector.x
|
||||
}
|
||||
|
||||
@@ -581,7 +581,7 @@ class ChainedVector2 {
|
||||
* *
|
||||
* @return [ChainedVector2]
|
||||
*/
|
||||
infix fun cross(z: Double): ChainedVector2 {
|
||||
fun cross(z: Double): ChainedVector2 {
|
||||
return ChainedVector2(-1.0 * this.y * z, this.x * z)
|
||||
}
|
||||
|
||||
@@ -628,7 +628,7 @@ class ChainedVector2 {
|
||||
* Negates this [ChainedVector2].
|
||||
* @return [ChainedVector2] this vector
|
||||
*/
|
||||
operator fun not() = negate()
|
||||
fun not() = negate()
|
||||
|
||||
/**
|
||||
* Negates this [ChainedVector2].
|
||||
@@ -663,7 +663,7 @@ class ChainedVector2 {
|
||||
* *
|
||||
* @return [ChainedVector2] this vector
|
||||
*/
|
||||
infix fun rotate(theta: Double): ChainedVector2 {
|
||||
fun rotate(theta: Double): ChainedVector2 {
|
||||
val cos = Math.cos(theta)
|
||||
val sin = Math.sin(theta)
|
||||
val x = this.x
|
||||
|
||||
1
work_files/graphics/colourmap/.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.{psd,tga,ogg} filter=lfs diff=lfs merge=lfs -text
|
||||