From 7dd520393c0554475a3b48ac253ce663abc31eb6 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Tue, 22 Aug 2023 00:06:03 +0900 Subject: [PATCH] more clouds --- .../basegame/weathers/WeatherGeneric.json | 14 +++--- .../torvald/terrarum/weather/WeatherMixer.kt | 47 +++++++++++-------- .../torvald/terrarum/weather/WeatherObject.kt | 5 +- .../terrarum/weather/WeatherObjectCloud.kt | 19 ++++++-- 4 files changed, 53 insertions(+), 32 deletions(-) diff --git a/assets/mods/basegame/weathers/WeatherGeneric.json b/assets/mods/basegame/weathers/WeatherGeneric.json index 73311740d..bd3b50e92 100644 --- a/assets/mods/basegame/weathers/WeatherGeneric.json +++ b/assets/mods/basegame/weathers/WeatherGeneric.json @@ -2,17 +2,17 @@ "skyboxGradColourMap": "generic_skybox.tga", "daylightClut": "clut_daylight.tga", "classification": "generic", - "cloudChance": 6, + "cloudChance": 10, "cloudGamma": [0.59, 2.0], - "cloudDriftSpeed": 0.4, + "cloudDriftSpeed": 10.4, "clouds": { - "normal": { - "filename": "cloud_normal.png", - "tw": 1024, "th": 512, "probability": 1.0, "baseScale": 0.4, "scaleVariance": 0.2 - }, "large": { "filename": "cloud_large.png", - "tw": 2048, "th": 1024, "probability": 0.1, "baseScale": 0.26, "scaleVariance": 0.2 + "tw": 2048, "th": 1024, "probability": 0.2, "baseScale": 0.45, "scaleVariance": 0.7 + }, + "normal": { + "filename": "cloud_normal.png", + "tw": 1024, "th": 512, "probability": 1.0, "baseScale": 0.5, "scaleVariance": 0.8 } } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/weather/WeatherMixer.kt b/src/net/torvald/terrarum/weather/WeatherMixer.kt index 7ff251fab..d0176a4c1 100644 --- a/src/net/torvald/terrarum/weather/WeatherMixer.kt +++ b/src/net/torvald/terrarum/weather/WeatherMixer.kt @@ -2,6 +2,7 @@ package net.torvald.terrarum.weather import com.badlogic.gdx.Gdx import com.badlogic.gdx.graphics.* +import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.g2d.TextureRegion import com.badlogic.gdx.math.Vector2 import com.badlogic.gdx.math.Vector3 @@ -192,7 +193,9 @@ internal object WeatherMixer : RNGConsumer { it?.let { it.update(cloudDriftVector, currentWeather.cloudDriftSpeed) - if (it.posX < -1500f || it.posX > App.scr.width + 1500f || it.scale < 1f / 2048f) { + val pjx = it.posX / it.posZ + + if (pjx !in -1500f..App.scr.wf + 1500f || it.scale < 1f / 2048f) { it.flagToDespawn = true } } @@ -211,11 +214,20 @@ internal object WeatherMixer : RNGConsumer { private val scrHscaler = App.scr.height / 720f + /** + * @param range: range of the randomised number + * @param random: random number in the range of `[-1, 1]` + */ + private fun randomPosWithin(range: ClosedFloatingPointRange, random: Float) = + ((range.start + range.endInclusive) / 2f) + random * (range.endInclusive - range.start) / 2f + private fun tryToSpawnCloud(currentWeather: BaseModularWeather) { printdbg(this, "Trying to spawn a cloud... (${cloudsSpawned} / ${clouds.size})") if (cloudsSpawned < clouds.size) { + val flip = Math.random() < 0.5 val rC = Math.random().toFloat() + val rZ = (Math.random() * 3.0 + 1.0).toFloat() // 1..4 val r0 = (Math.random() * 2.0 - 1.0).toFloat() // -1..1 val r1 = (Math.random() * 2.0 - 1.0).toFloat() // -1..1 val r2 = (Math.random() * 2.0 - 1.0).toFloat() // -1..1 @@ -237,15 +249,15 @@ internal object WeatherMixer : RNGConsumer { cloudsToSpawn?.let { cloud -> val scaleVariance = 1f + rT1.absoluteValue * cloud.scaleVariance val cloudScale = cloud.baseScale * (if (rT1 < 0) 1f / scaleVariance else scaleVariance) - val hCloudSize = cloud.spriteSheet.tileW * cloudScale + 1f - val posX = if (cloudDriftVector.x < 0) App.scr.width + hCloudSize else -hCloudSize + val hCloudSize = (cloud.spriteSheet.tileW * cloudScale) + 1f + val posX = if (cloudDriftVector.x < 0) (App.scr.width + hCloudSize) * rZ else -hCloudSize * rZ val posY = when (cloud.category) { - "large" -> (100f + r0 * 80f) * scrHscaler - else -> (150f + r0 * 50f) * scrHscaler + "large" -> randomPosWithin(-10f..120f, r0) * scrHscaler + else -> randomPosWithin(-50f..150f, r0) * scrHscaler // -50..150 } val sheetX = rA % cloud.spriteSheet.horizontalCount val sheetY = rB % cloud.spriteSheet.verticalCount - WeatherObjectCloud(cloud.spriteSheet.get(sheetX, sheetY)).also { + WeatherObjectCloud(cloud.spriteSheet.get(sheetX, sheetY), flip).also { it.scale = cloudScale it.darkness.set(currentWeather.cloudGamma) @@ -255,12 +267,13 @@ internal object WeatherMixer : RNGConsumer { it.posX = posX it.posY = posY + it.posZ = rZ clouds.addAtFreeSpot(it) cloudsSpawned += 1 - printdbg(this, "... Spawning ${cloud.category}($sheetX, $sheetY) cloud at pos ${it.pos}, invGamma ${it.darkness}") + printdbg(this, "... Spawning ${cloud.category}($sheetX, $sheetY) cloud at pos ${it.pos}, scale ${it.scale}, invGamma ${it.darkness}") } } @@ -289,25 +302,21 @@ internal object WeatherMixer : RNGConsumer { */ internal fun render(camera: Camera, batch: FlippingSpriteBatch, world: GameWorld) { drawSkybox(camera, batch, world) + drawClouds(batch) + batch.color = Color.WHITE + } - - - + private fun drawClouds(batch: SpriteBatch) { batch.color = globalLightNow.toGdxColor().also { it.a = 1f } // TODO add cloud-only colour strip on the CLUT batch.shader = shaderClouds - clouds.forEach { - it?.let { - batch.inUse { _ -> - batch.shader.setUniformf("gamma", it.darkness) - it.render(batch, 0f, 0f) // TODO parallax - } + clouds.filterNotNull().sortedByDescending { it.posZ }.forEach { + batch.inUse { _ -> + batch.shader.setUniformf("gamma", it.darkness) + it.render(batch, 0f, 0f) // TODO parallax } } - - - batch.color = Color.WHITE } private val parallaxDomainSize = 400f diff --git a/src/net/torvald/terrarum/weather/WeatherObject.kt b/src/net/torvald/terrarum/weather/WeatherObject.kt index 9bbf7a2a9..2c00cb4db 100644 --- a/src/net/torvald/terrarum/weather/WeatherObject.kt +++ b/src/net/torvald/terrarum/weather/WeatherObject.kt @@ -10,7 +10,7 @@ import com.badlogic.gdx.utils.Disposable abstract class WeatherObject : Disposable { /** vec3(posX, posY, scale) */ - var pos: Vector3 = Vector3() + var pos: Vector3 = Vector3(0f, 0f, 1f) var posX: Float get() = pos.x @@ -18,9 +18,10 @@ abstract class WeatherObject : Disposable { var posY: Float get() = pos.y set(value) { pos.y = value } - var scale: Float + var posZ: Float get() = pos.z set(value) { pos.z = value } + var scale: Float = 1f var flagToDespawn = false diff --git a/src/net/torvald/terrarum/weather/WeatherObjectCloud.kt b/src/net/torvald/terrarum/weather/WeatherObjectCloud.kt index 117efd1a9..1d9259144 100644 --- a/src/net/torvald/terrarum/weather/WeatherObjectCloud.kt +++ b/src/net/torvald/terrarum/weather/WeatherObjectCloud.kt @@ -4,12 +4,13 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.g2d.TextureRegion import com.badlogic.gdx.math.Vector2 import com.badlogic.gdx.math.Vector3 +import net.torvald.terrarum.App import kotlin.math.sign /** * Created by minjaesong on 2023-08-21. */ -class WeatherObjectCloud(private val texture: TextureRegion) : WeatherObject() { +class WeatherObjectCloud(private val texture: TextureRegion, private val flipW: Boolean) : WeatherObject() { /** * To actually utilise this value, your render code must begin the spritebatch per-object, like so: @@ -32,8 +33,8 @@ class WeatherObjectCloud(private val texture: TextureRegion) : WeatherObject() { * Resulting vector: (x + dX, y + dY, scale * dScale) */ fun update(flowVector: Vector3, gait: Float) { - posX += flowVector.x * gait * scale * scale - posY += flowVector.y * gait * scale * scale + posX += flowVector.x * gait * scale + posY += flowVector.y * gait * scale scale *= flowVector.z } @@ -44,8 +45,18 @@ class WeatherObjectCloud(private val texture: TextureRegion) : WeatherObject() { override fun render(batch: SpriteBatch, offsetX: Float, offsetY: Float) { val x = posX + offsetX - texture.regionWidth * scale * 0.5f val y = posY + offsetY - texture.regionHeight * scale + val z = posZ // must be at least 1.0 + val w = App.scr.halfwf + val h = App.scr.halfhf // 50% to the screen height, or 35%? - batch.draw(texture, x, y, texture.regionWidth * scale, texture.regionHeight * scale) + val drawX = (x + w * (z-1)) / z + val drawY = (y + h * (z-1)) / z + val drawScale = scale / z + + if (flipW) + batch.draw(texture, drawX + texture.regionWidth / z, drawY, -texture.regionWidth * drawScale, texture.regionHeight * drawScale) + else + batch.draw(texture, drawX, drawY, texture.regionWidth * drawScale, texture.regionHeight * drawScale) } override fun dispose() { /* cloud texture will be disposed of by the WeatherMixer */ }