rain megaparticle experiment

This commit is contained in:
minjaesong
2017-12-18 20:45:32 +09:00
parent 70504509b9
commit f5fba1e273
16 changed files with 286 additions and 69 deletions

View File

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

View File

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

View File

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

View File

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

View File

@@ -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,16 +474,69 @@ open class ActorHumanoid(
isWalkingV = false
}
/**
* 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)
private fun getJumpAcc(pwr: Double, timedJumpCharge: Double): Double {
return pwr * timedJumpCharge * JUMP_ACCELERATION_MOD * Math.sqrt(scale) // positive value
}
fun jumpFunc(counter: Int): Double {
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
@@ -490,13 +544,19 @@ open class ActorHumanoid(
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() {
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

View File

@@ -493,15 +493,7 @@ open class ActorWithPhysics(val world: GameWorld, renderOrder: RenderOrder, val
}
}*/
/**
* Apply gravitation to the every falling body (unless not levitating)
*
* Apply only if not grounded; normal force is precessed separately.
*/
private fun applyGravitation() {
if (!isNoSubjectToGrav && !(gravitation.y > 0 && walledBottom || gravitation.y < 0 && walledTop)) {
//if (!isWalled(hitbox, COLLIDING_BOTTOM)) {
fun getDrag(externalForce: Vector2): Vector2 {
/**
* weight; gravitational force in action
* W = mass * G (9.8 [m/s^2])
@@ -519,7 +511,19 @@ open class ActorWithPhysics(val world: GameWorld, renderOrder: RenderOrder, val
val V: Vector2 = (W - D) / Terrarum.TARGET_FPS.toDouble() * SI_TO_GAME_ACC
applyForce(V)
return V
}
/**
* Apply gravitation to the every falling body (unless not levitating)
*
* Apply only if not grounded; normal force is precessed separately.
*/
private fun applyGravitation() {
if (!isNoSubjectToGrav && !(gravitation.y > 0 && walledBottom || gravitation.y < 0 && walledTop)) {
//if (!isWalled(hitbox, COLLIDING_BOTTOM)) {
applyForce(getDrag(externalForce))
//}
}
}

View File

@@ -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,7 +41,8 @@ open class ParticleBase(renderOrder: Actor.RenderOrder, maxLifeTime: Second? = n
fun update(delta: Float) {
if (!flagDespawn) {
lifetimeCounter += delta
if (velocity.isZero || lifetimeCounter >= lifetimeMax ||
if (despawnUponCollision) {
if (velocity.isZero ||
// simple stuck check
BlockCodex[Terrarum.ingame!!.world.getTileFromTerrain(
hitbox.canonicalX.div(TILE_SIZE).floorInt(),
@@ -49,6 +50,11 @@ open class ParticleBase(renderOrder: Actor.RenderOrder, maxLifeTime: Second? = n
) ?: Block.STONE].isSolid) {
flagDespawn = true
}
}
if (lifetimeCounter >= lifetimeMax) {
flagDespawn = true
}
// gravity, winds, etc. (external forces)
if (!isNoSubjectToGrav) {

View 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
}
}
}

View File

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

View File

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

View File

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