mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 12:21:52 +09:00
rain megaparticle experiment
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -127,6 +127,8 @@ class Ingame(val batch: SpriteBatch) : Screen {
|
||||
|
||||
private lateinit var uiTooltip: UITooltip
|
||||
|
||||
lateinit var uiCheatMotherfuckerNootNoot: UICheatDetected
|
||||
|
||||
// UI aliases
|
||||
lateinit var uiAliases: ArrayList<UICanvas>
|
||||
private set
|
||||
@@ -288,6 +290,10 @@ class Ingame(val batch: SpriteBatch) : Screen {
|
||||
//FeaturesDrawer.world = this.world
|
||||
|
||||
|
||||
MegaRainGovernor // invoke MegaRain Governor
|
||||
|
||||
|
||||
|
||||
Gdx.input.inputProcessor = ingameController
|
||||
|
||||
|
||||
@@ -361,6 +367,9 @@ class Ingame(val batch: SpriteBatch) : Screen {
|
||||
uiTooltip = UITooltip()
|
||||
|
||||
|
||||
uiCheatMotherfuckerNootNoot = UICheatDetected()
|
||||
|
||||
|
||||
// batch-process uiAliases
|
||||
uiAliases = arrayListOf(
|
||||
// drawn first
|
||||
@@ -378,7 +387,8 @@ class Ingame(val batch: SpriteBatch) : Screen {
|
||||
uiAlasesPausing = arrayListOf(
|
||||
uiInventoryPlayer,
|
||||
//uiInventoryContainer,
|
||||
consoleHandler
|
||||
consoleHandler,
|
||||
uiCheatMotherfuckerNootNoot
|
||||
)
|
||||
uiAlasesPausing.forEach { addUI(it) } // put them all to the UIContainer
|
||||
uiAliases.forEach { addUI(it) } // put them all to the UIContainer
|
||||
@@ -391,6 +401,15 @@ class Ingame(val batch: SpriteBatch) : Screen {
|
||||
|
||||
|
||||
LightmapRenderer.fireRecalculateEvent()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// some sketchy test code here
|
||||
|
||||
|
||||
|
||||
}// END enter
|
||||
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ object LoadScreen : ScreenAdapter() {
|
||||
it.color = Color.WHITE
|
||||
|
||||
|
||||
Terrarum.fontGame.draw(it, textToPrint, (textFbo.width - textWidth) / 2f + 0.33f, 0f) // x 0.33? I dunno but it breaks w/o it
|
||||
Terrarum.fontGame.draw(it, textToPrint, ((textFbo.width - textWidth) / 2).toInt().toFloat(), 0f)
|
||||
|
||||
|
||||
blendMul()
|
||||
@@ -188,6 +188,14 @@ object LoadScreen : ScreenAdapter() {
|
||||
it.projectionMatrix = camera.combined
|
||||
blendNormal()
|
||||
|
||||
|
||||
// almost black background
|
||||
it.color = Color(0x181818ff)
|
||||
it.fillRect(0f, 0f, Terrarum.WIDTH.toFloat(), Terrarum.HEIGHT.toFloat())
|
||||
|
||||
|
||||
it.color = Color.WHITE
|
||||
|
||||
// draw text FBO to screen
|
||||
val textTex = textFbo.colorBufferTexture
|
||||
textTex.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
|
||||
|
||||
@@ -815,6 +815,16 @@ infix fun Color.minus(other: Color) = Color( // don't turn into an operator!
|
||||
|
||||
fun Int.toHex() = this.toLong().and(0xFFFFFFFF).toString(16).padStart(8, '0').toUpperCase()
|
||||
|
||||
fun MutableList<Any>.shuffle() {
|
||||
for (i in this.size - 1 downTo 1) {
|
||||
val rndIndex = (Math.random() * (i + 1)).toInt()
|
||||
|
||||
val t = this[rndIndex]
|
||||
this[rndIndex] = this[i]
|
||||
this[i] = t
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
val ccW = GameFontBase.toColorCode(0xFFFF)
|
||||
val ccY = GameFontBase.toColorCode(0xFE8F)
|
||||
|
||||
@@ -110,8 +110,8 @@ public class TerrarumAppLoader implements ApplicationListener {
|
||||
private SpriteBatch batch;
|
||||
public static TextureRegion logo;
|
||||
|
||||
private Color gradWhiteTop = new Color(0xf8f8f8ff);
|
||||
private Color gradWhiteBottom = new Color(0xd8d8d8ff);
|
||||
private Color gradWhiteTop = new Color(0xd8d8d8ff);
|
||||
private Color gradWhiteBottom = new Color(0xf8f8f8ff);
|
||||
|
||||
public Screen screen;
|
||||
|
||||
@@ -160,7 +160,6 @@ public class TerrarumAppLoader implements ApplicationListener {
|
||||
|
||||
|
||||
logo = new TextureRegion(new Texture(Gdx.files.internal("assets/graphics/logo_placeholder.tga")));
|
||||
logo.flip(false, true);
|
||||
|
||||
|
||||
TextureRegionPack.Companion.setGlobalFlipY(true);
|
||||
|
||||
@@ -11,6 +11,7 @@ import net.torvald.terrarum.itemproperties.Material
|
||||
import net.torvald.terrarum.realestate.LandUtil
|
||||
import net.torvald.terrarum.ui.UIInventoryFull
|
||||
import net.torvald.terrarum.worlddrawer.LightmapRenderer
|
||||
import org.dyn4j.geometry.Vector2
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
@@ -473,30 +474,89 @@ open class ActorHumanoid(
|
||||
isWalkingV = false
|
||||
}
|
||||
|
||||
private fun getJumpAcc(pwr: Double, timedJumpCharge: Double): Double {
|
||||
return pwr * timedJumpCharge * JUMP_ACCELERATION_MOD * Math.sqrt(scale) // positive value
|
||||
}
|
||||
|
||||
private var oldMAX_JUMP_LENGTH = -1 // init
|
||||
private var oldJUMPPOWER = -1.0 // init
|
||||
private var oldJUMPPOWERBUFF = -1.0 // init
|
||||
private var oldScale = -1.0
|
||||
private var oldDragCoefficient = -1.0
|
||||
val jumpAirTime: Double = -1.0
|
||||
get() {
|
||||
// compare all the affecting variables
|
||||
if (oldMAX_JUMP_LENGTH == MAX_JUMP_LENGTH &&
|
||||
oldJUMPPOWER == actorValue.getAsDouble(AVKey.JUMPPOWER)!! &&
|
||||
oldJUMPPOWERBUFF == actorValue.getAsDouble(AVKey.JUMPPOWERBUFF) ?: 1.0 &&
|
||||
oldScale == scale &&
|
||||
oldDragCoefficient == dragCoefficient) {
|
||||
return field
|
||||
}
|
||||
// if variables are changed, get new value, store it and return it
|
||||
else {
|
||||
oldMAX_JUMP_LENGTH = MAX_JUMP_LENGTH
|
||||
oldJUMPPOWER = actorValue.getAsDouble(AVKey.JUMPPOWER)!!
|
||||
oldJUMPPOWERBUFF = actorValue.getAsDouble(AVKey.JUMPPOWERBUFF) ?: 1.0
|
||||
oldScale = scale
|
||||
oldDragCoefficient = dragCoefficient
|
||||
|
||||
|
||||
var frames = 0
|
||||
|
||||
var simYPos = 0.0
|
||||
var forceVec = Vector2(0.0, 0.0)
|
||||
var jmpCtr = 0
|
||||
while (true) {
|
||||
if (jmpCtr < MAX_JUMP_LENGTH) jmpCtr++
|
||||
|
||||
|
||||
val timedJumpCharge = jumpFunc(MAX_JUMP_LENGTH, jmpCtr)
|
||||
forceVec.y -= getJumpAcc(jumpPower, timedJumpCharge)
|
||||
forceVec.y += getDrag(forceVec).y
|
||||
|
||||
simYPos += forceVec.y // ignoring all the fluid drag OTHER THAN THE AIR
|
||||
|
||||
|
||||
if ((simYPos >= 0.0 && frames > 0) || frames >= 1000) break
|
||||
|
||||
|
||||
frames++
|
||||
}
|
||||
|
||||
|
||||
field = frames * (1.0 / Terrarum.TARGET_FPS)
|
||||
// fixme: looks good but return value is wrong -- 2.25 seconds? when I jump it barely goes past 1 sec
|
||||
|
||||
|
||||
return field
|
||||
}
|
||||
}
|
||||
|
||||
private val jumpPower: Double
|
||||
get() = actorValue.getAsDouble(AVKey.JUMPPOWER)!! * (actorValue.getAsDouble(AVKey.JUMPPOWERBUFF) ?: 1.0)
|
||||
|
||||
private fun jumpFunc(len: Int, counter: Int): Double {
|
||||
// linear time mode
|
||||
val init = (len + 1) / 2.0
|
||||
var timedJumpCharge = init - init / len * counter
|
||||
if (timedJumpCharge < 0) timedJumpCharge = 0.0
|
||||
return timedJumpCharge
|
||||
}
|
||||
|
||||
/**
|
||||
* See ./work_files/Jump power by pressing time.gcx
|
||||
*
|
||||
* TODO linear function (play Super Mario Bros. and you'll get what I'm talking about) -- SCRATCH THAT!
|
||||
*/
|
||||
private fun jump() {
|
||||
val len = MAX_JUMP_LENGTH.toFloat()
|
||||
val pwr = actorValue.getAsDouble(AVKey.JUMPPOWER)!! * (actorValue.getAsDouble(AVKey.JUMPPOWERBUFF) ?: 1.0)
|
||||
|
||||
fun jumpFunc(counter: Int): Double {
|
||||
// linear time mode
|
||||
val init = (len + 1) / 2.0
|
||||
var timedJumpCharge = init - init / len * counter
|
||||
if (timedJumpCharge < 0) timedJumpCharge = 0.0
|
||||
return timedJumpCharge
|
||||
}
|
||||
|
||||
if (jumping) {// && jumpable) {
|
||||
// increment jump counter
|
||||
if (jumpCounter < len) jumpCounter += 1
|
||||
if (jumpCounter < MAX_JUMP_LENGTH) jumpCounter += 1
|
||||
|
||||
val timedJumpCharge = jumpFunc(jumpCounter)
|
||||
val timedJumpCharge = jumpFunc(MAX_JUMP_LENGTH, jumpCounter)
|
||||
|
||||
jumpAcc = pwr * timedJumpCharge * JUMP_ACCELERATION_MOD * Math.sqrt(scale) // positive value
|
||||
jumpAcc = getJumpAcc(jumpPower, timedJumpCharge)
|
||||
|
||||
controllerMoveDelta?.y?.let { controllerMoveDelta!!.y -= jumpAcc } // feed negative value to the vector
|
||||
// do not think of resetting this to zero when counter hit the ceiling; that's HOW NOT
|
||||
@@ -510,7 +570,7 @@ open class ActorHumanoid(
|
||||
}*/
|
||||
|
||||
// release "jump key" of AIs
|
||||
if (jumpCounter >= len && !isGamer) {
|
||||
if (jumpCounter >= MAX_JUMP_LENGTH && !isGamer) {
|
||||
isJumpDown = false
|
||||
jumping = false
|
||||
jumpCounter = 0
|
||||
|
||||
@@ -493,6 +493,27 @@ open class ActorWithPhysics(val world: GameWorld, renderOrder: RenderOrder, val
|
||||
}
|
||||
}*/
|
||||
|
||||
fun getDrag(externalForce: Vector2): Vector2 {
|
||||
/**
|
||||
* weight; gravitational force in action
|
||||
* W = mass * G (9.8 [m/s^2])
|
||||
*/
|
||||
val W: Vector2 = gravitation * Terrarum.TARGET_FPS.toDouble()
|
||||
/**
|
||||
* Area
|
||||
*/
|
||||
val A: Double = (scale * baseHitboxW / METER) * (scale * baseHitboxW / METER)
|
||||
/**
|
||||
* Drag of atmosphere
|
||||
* D = Cd (drag coefficient) * 0.5 * rho (density) * V^2 (velocity sqr) * A (area)
|
||||
*/
|
||||
val D: Vector2 = Vector2(externalForce.x.magnSqr(), externalForce.y.magnSqr()) * dragCoefficient * 0.5 * A// * tileDensityFluid.toDouble()
|
||||
|
||||
val V: Vector2 = (W - D) / Terrarum.TARGET_FPS.toDouble() * SI_TO_GAME_ACC
|
||||
|
||||
return V
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply gravitation to the every falling body (unless not levitating)
|
||||
*
|
||||
@@ -502,24 +523,7 @@ open class ActorWithPhysics(val world: GameWorld, renderOrder: RenderOrder, val
|
||||
|
||||
if (!isNoSubjectToGrav && !(gravitation.y > 0 && walledBottom || gravitation.y < 0 && walledTop)) {
|
||||
//if (!isWalled(hitbox, COLLIDING_BOTTOM)) {
|
||||
/**
|
||||
* weight; gravitational force in action
|
||||
* W = mass * G (9.8 [m/s^2])
|
||||
*/
|
||||
val W: Vector2 = gravitation * Terrarum.TARGET_FPS.toDouble()
|
||||
/**
|
||||
* Area
|
||||
*/
|
||||
val A: Double = (scale * baseHitboxW / METER) * (scale * baseHitboxW / METER)
|
||||
/**
|
||||
* Drag of atmosphere
|
||||
* D = Cd (drag coefficient) * 0.5 * rho (density) * V^2 (velocity sqr) * A (area)
|
||||
*/
|
||||
val D: Vector2 = Vector2(externalForce.x.magnSqr(), externalForce.y.magnSqr()) * dragCoefficient * 0.5 * A// * tileDensityFluid.toDouble()
|
||||
|
||||
val V: Vector2 = (W - D) / Terrarum.TARGET_FPS.toDouble() * SI_TO_GAME_ACC
|
||||
|
||||
applyForce(V)
|
||||
applyForce(getDrag(externalForce))
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import org.dyn4j.geometry.Vector2
|
||||
*
|
||||
* Created by minjaesong on 2017-01-20.
|
||||
*/
|
||||
open class ParticleBase(renderOrder: Actor.RenderOrder, maxLifeTime: Second? = null) : Runnable {
|
||||
open class ParticleBase(renderOrder: Actor.RenderOrder, val despawnUponCollision: Boolean, maxLifeTime: Second? = null) : Runnable {
|
||||
|
||||
/** Will NOT actually delete from the CircularArray */
|
||||
@Volatile var flagDespawn = false
|
||||
@@ -41,12 +41,18 @@ open class ParticleBase(renderOrder: Actor.RenderOrder, maxLifeTime: Second? = n
|
||||
fun update(delta: Float) {
|
||||
if (!flagDespawn) {
|
||||
lifetimeCounter += delta
|
||||
if (velocity.isZero || lifetimeCounter >= lifetimeMax ||
|
||||
// simple stuck check
|
||||
BlockCodex[Terrarum.ingame!!.world.getTileFromTerrain(
|
||||
hitbox.canonicalX.div(TILE_SIZE).floorInt(),
|
||||
hitbox.canonicalY.div(TILE_SIZE).floorInt()
|
||||
) ?: Block.STONE].isSolid) {
|
||||
if (despawnUponCollision) {
|
||||
if (velocity.isZero ||
|
||||
// simple stuck check
|
||||
BlockCodex[Terrarum.ingame!!.world.getTileFromTerrain(
|
||||
hitbox.canonicalX.div(TILE_SIZE).floorInt(),
|
||||
hitbox.canonicalY.div(TILE_SIZE).floorInt()
|
||||
) ?: Block.STONE].isSolid) {
|
||||
flagDespawn = true
|
||||
}
|
||||
}
|
||||
|
||||
if (lifetimeCounter >= lifetimeMax) {
|
||||
flagDespawn = true
|
||||
}
|
||||
|
||||
|
||||
107
src/net/torvald/terrarum/gameactors/ParticleMegaRain.kt
Normal file
107
src/net/torvald/terrarum/gameactors/ParticleMegaRain.kt
Normal file
@@ -0,0 +1,107 @@
|
||||
package net.torvald.terrarum.gameactors
|
||||
|
||||
import com.badlogic.gdx.graphics.Pixmap
|
||||
import com.badlogic.gdx.graphics.Texture
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
||||
import net.torvald.random.HQRNG
|
||||
import net.torvald.terrarum.ModMgr
|
||||
import net.torvald.terrarum.Terrarum
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2017-12-18.
|
||||
*/
|
||||
class ParticleMegaRain(posX: Double, posY: Double) : ParticleBase(Actor.RenderOrder.BEHIND, false, 3.2f) {
|
||||
|
||||
init {
|
||||
body = MegaRainGovernor.get()
|
||||
val w = body.regionWidth.toDouble()
|
||||
val h = body.regionHeight.toDouble()
|
||||
hitbox.setFromWidthHeight(
|
||||
posX - w.times(0.5),
|
||||
posY - h.times(0.5),
|
||||
w, h
|
||||
)
|
||||
|
||||
velocity.y = 18.0
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
object MegaRainGovernor {
|
||||
|
||||
private var reseedTimer = 0f
|
||||
var reseedTime: Second = 90f
|
||||
|
||||
private val body = Pixmap(ModMgr.getGdxFile("basegame", "weathers/raindrop.tga"))
|
||||
private lateinit var bodies: Array<TextureRegion>
|
||||
|
||||
private var withdrawCounter = 0
|
||||
|
||||
init {
|
||||
seed()
|
||||
}
|
||||
|
||||
private fun seed() {
|
||||
val w = body.width
|
||||
val h = body.height
|
||||
|
||||
bodies = Array(1024) {
|
||||
val pixmap = Pixmap(Terrarum.WIDTH * 2, Terrarum.HEIGHT / 4, Pixmap.Format.RGBA8888)
|
||||
|
||||
val rng = HQRNG()
|
||||
|
||||
repeat(64) {
|
||||
val rndX = rng.nextInt(pixmap.width - body.width)
|
||||
val rndY = rng.nextInt(pixmap.height - body.height)
|
||||
|
||||
pixmap.drawPixmap(body, rndX, rndY)
|
||||
}
|
||||
|
||||
// return composed (mega)pixmap
|
||||
val region = TextureRegion(Texture(pixmap))
|
||||
region.flip(false, true)
|
||||
|
||||
/*return*/region
|
||||
}
|
||||
|
||||
// randomise
|
||||
bodies.shuffle()
|
||||
}
|
||||
|
||||
fun get(): TextureRegion {
|
||||
if (withdrawCounter >= bodies.size) {
|
||||
withdrawCounter = 0
|
||||
bodies.shuffle()
|
||||
}
|
||||
|
||||
return bodies[withdrawCounter++]
|
||||
}
|
||||
|
||||
@Deprecated("re-seeding freezes the game a little and large enough randomnesses ought to be good")
|
||||
fun update(delta: Float) {
|
||||
if (reseedTimer >= reseedTime) {
|
||||
seed()
|
||||
reseedTimer -= reseedTime
|
||||
}
|
||||
|
||||
reseedTimer += delta
|
||||
}
|
||||
|
||||
fun resize() {
|
||||
seed()
|
||||
withdrawCounter = 0
|
||||
reseedTimer = 0f
|
||||
}
|
||||
|
||||
|
||||
|
||||
fun Array<TextureRegion>.shuffle() {
|
||||
for (i in this.size - 1 downTo 1) {
|
||||
val rndIndex = (Math.random() * (i + 1)).toInt()
|
||||
|
||||
val t = this[rndIndex]
|
||||
this[rndIndex] = this[i]
|
||||
this[i] = t
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import net.torvald.terrarum.ModMgr
|
||||
/**
|
||||
* Created by minjaesong on 2017-01-20.
|
||||
*/
|
||||
class ParticleTestRain(posX: Double, posY: Double) : ParticleBase(Actor.RenderOrder.BEHIND, 6f) {
|
||||
class ParticleTestRain(posX: Double, posY: Double) : ParticleBase(Actor.RenderOrder.BEHIND, true, 6f) {
|
||||
|
||||
init {
|
||||
body = TextureRegion(Texture(ModMgr.getGdxFile("basegame", "weathers/raindrop.tga")))
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.torvald.colourutil.*
|
||||
import net.torvald.random.HQRNG
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||
import net.torvald.terrarum.gameactors.ParticleMegaRain
|
||||
import net.torvald.terrarum.gameactors.ParticleTestRain
|
||||
import net.torvald.terrarum.gamecontroller.KeyToggler
|
||||
import net.torvald.terrarum.gameworld.GameWorld
|
||||
@@ -80,18 +81,19 @@ object WeatherMixer {
|
||||
|
||||
|
||||
// test rain toggled by F2
|
||||
/*if (KeyToggler.isOn(Input.Keys.F2)) {
|
||||
val playerPos = player.centrePosPoint
|
||||
kotlin.repeat(4) {
|
||||
if (KeyToggler.isOn(Input.Keys.F2)) {
|
||||
val playerPosX = player.hitbox.centeredX
|
||||
val playerPosY = player.hitbox.centeredY
|
||||
kotlin.repeat(1) {
|
||||
// 4 seems good
|
||||
val rainParticle = ParticleTestRain(
|
||||
playerPos.x + HQRNG().nextInt(Terrarum.WIDTH) - Terrarum.HALFW,
|
||||
playerPos.y - Terrarum.HALFH
|
||||
val rainParticle = ParticleMegaRain(
|
||||
playerPosX + HQRNG().nextInt(Terrarum.WIDTH) - Terrarum.HALFW,
|
||||
playerPosY - Terrarum.HALFH
|
||||
)
|
||||
Terrarum.ingame!!.addParticle(rainParticle)
|
||||
}
|
||||
globalLightNow.set(getGlobalLightOfTime(world.time.todaySeconds).mul(0.3f, 0.3f, 0.3f, 0.58f))
|
||||
}*/
|
||||
//globalLightNow.set(getGlobalLightOfTime(Terrarum.ingame!!.world.time.todaySeconds).mul(0.3f, 0.3f, 0.3f, 0.58f))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -134,17 +134,16 @@ object BlocksDrawer {
|
||||
|
||||
for (tileID in ITEM_TILES) {
|
||||
|
||||
val tile = tilesTerrain.get((tileID % 16) * 16, (tileID / 16))
|
||||
val tileX = (tileID % 16) * 16
|
||||
val tileY = tileID / 16
|
||||
val tile = tilesTerrain.get(tileX, tileY)
|
||||
|
||||
|
||||
// slow memory copy :\ I'm afraid I can't random-access bytebuffer...
|
||||
for (y in 0..TILE_SIZE - 1) {
|
||||
for (x in 0..TILE_SIZE - 1) {
|
||||
tileItemImgPixMap.pixels.putInt(
|
||||
terrainPixMap.getPixel(
|
||||
tile.regionX + x,
|
||||
tile.regionY + y
|
||||
)
|
||||
)
|
||||
for (scanline in 0 until tileItemImgPixMap.height) {
|
||||
for (x in 0 until TILE_SIZE) {
|
||||
val pixel = terrainPixMap.getPixel(tileX + x, scanline)
|
||||
tileItemImgPixMap.drawPixel(x + TILE_SIZE * (tileID % 16), scanline, pixel)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
BIN
work_files/graphics/fonts/terrarumsansbitmap_ascii_small.psd
LFS
Normal file
BIN
work_files/graphics/fonts/terrarumsansbitmap_ascii_small.psd
LFS
Normal file
Binary file not shown.
Reference in New Issue
Block a user