mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-14 04:24:05 +09:00
limitedly successful attempt to create a title screen
This commit is contained in:
363
src/net/torvald/terrarum/TitleScreen.kt
Normal file
363
src/net/torvald/terrarum/TitleScreen.kt
Normal file
@@ -0,0 +1,363 @@
|
||||
package net.torvald.terrarum
|
||||
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.Input
|
||||
import com.badlogic.gdx.Screen
|
||||
import com.badlogic.gdx.graphics.*
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
||||
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||
import net.torvald.terrarum.gameactors.Hitbox
|
||||
import net.torvald.terrarum.gamecontroller.KeyToggler
|
||||
import net.torvald.terrarum.gameworld.GameWorld
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.serialise.ReadLayerData
|
||||
import net.torvald.terrarum.ui.UICanvas
|
||||
import net.torvald.terrarum.ui.UIHandler
|
||||
import net.torvald.terrarum.ui.UIStartMenu
|
||||
import net.torvald.terrarum.weather.WeatherMixer
|
||||
import net.torvald.terrarum.worlddrawer.BlocksDrawer
|
||||
import net.torvald.terrarum.worlddrawer.FeaturesDrawer
|
||||
import net.torvald.terrarum.worlddrawer.LightmapRenderer
|
||||
import net.torvald.terrarum.worlddrawer.WorldCamera
|
||||
import java.io.FileInputStream
|
||||
|
||||
class TitleScreen(val batch: SpriteBatch) : Screen {
|
||||
|
||||
var camera = OrthographicCamera(Terrarum.WIDTH.toFloat(), Terrarum.HEIGHT.toFloat())
|
||||
|
||||
// invert Y
|
||||
fun initViewPort(width: Int, height: Int) {
|
||||
//val width = if (width % 1 == 1) width + 1 else width
|
||||
//val height = if (height % 1 == 1) height + 1 else width
|
||||
|
||||
// Set Y to point downwards
|
||||
camera.setToOrtho(true, width.toFloat(), height.toFloat())
|
||||
|
||||
// Update camera matrix
|
||||
camera.update()
|
||||
|
||||
// Set viewport to restrict drawing
|
||||
Gdx.gl20.glViewport(0, 0, width, height)
|
||||
}
|
||||
|
||||
|
||||
private var loadDone = false
|
||||
|
||||
private lateinit var demoWorld: GameWorld
|
||||
private val cameraPlayer = object : ActorWithBody(RenderOrder.BEHIND) {
|
||||
override fun drawBody(batch: SpriteBatch) { }
|
||||
override fun drawGlow(batch: SpriteBatch) { }
|
||||
override fun dispose() { }
|
||||
override fun onActorValueChange(key: String, value: Any?) { }
|
||||
override fun run() { }
|
||||
|
||||
override fun update(delta: Float) {
|
||||
// camera walk?
|
||||
}
|
||||
}
|
||||
|
||||
private val gradWhiteTop = Color(0xf8f8f8ff.toInt())
|
||||
private val gradWhiteBottom = Color(0xd8d8d8ff.toInt())
|
||||
|
||||
private val lightFBOformat = Pixmap.Format.RGB888
|
||||
var lightmapFboA = FrameBuffer(lightFBOformat, Terrarum.WIDTH.div(Ingame.lightmapDownsample.toInt()), Terrarum.HEIGHT.div(Ingame.lightmapDownsample.toInt()), false)
|
||||
var lightmapFboB = FrameBuffer(lightFBOformat, Terrarum.WIDTH.div(Ingame.lightmapDownsample.toInt()), Terrarum.HEIGHT.div(Ingame.lightmapDownsample.toInt()), false)
|
||||
|
||||
lateinit var logo: TextureRegion
|
||||
|
||||
|
||||
private lateinit var uiMenu: UIHandler
|
||||
|
||||
private fun loadThingsWhileIntroIsVisible() {
|
||||
demoWorld = ReadLayerData(FileInputStream(ModMgr.getFile("basegame", "demoworld")))
|
||||
|
||||
cameraPlayer.hitbox.setPosition(
|
||||
demoWorld.spawnX * FeaturesDrawer.TILE_SIZE.toDouble(),
|
||||
demoWorld.spawnY * FeaturesDrawer.TILE_SIZE.toDouble()
|
||||
)
|
||||
cameraPlayer.hitbox.setDimension(2.0, 2.0)
|
||||
|
||||
demoWorld.time.timeDelta = 45
|
||||
|
||||
|
||||
LightmapRenderer.world = demoWorld
|
||||
BlocksDrawer.world = demoWorld
|
||||
FeaturesDrawer.world = demoWorld
|
||||
|
||||
|
||||
uiMenu = UIHandler(UIStartMenu())
|
||||
uiMenu.setPosition(0, UIStartMenu.menubarOffY)
|
||||
uiMenu.setAsOpen()
|
||||
|
||||
|
||||
loadDone = true
|
||||
}
|
||||
|
||||
|
||||
override fun hide() {
|
||||
}
|
||||
|
||||
override fun show() {
|
||||
initViewPort(Terrarum.WIDTH, Terrarum.HEIGHT)
|
||||
|
||||
logo = TextureRegion(Texture(Gdx.files.internal("assets/graphics/logo_placeholder.tga")))
|
||||
logo.flip(false, true)
|
||||
}
|
||||
|
||||
private var blurWriteBuffer = lightmapFboA
|
||||
private var blurReadBuffer = lightmapFboB
|
||||
|
||||
private val minimumIntroTime = 1.0f
|
||||
private var deltaCounter = 0f
|
||||
|
||||
override fun render(delta: Float) {
|
||||
Gdx.gl.glClearColor(.094f, .094f, .094f, 0f)
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
||||
|
||||
if (!loadDone || deltaCounter < minimumIntroTime) {
|
||||
// draw load screen
|
||||
Terrarum.shaderBayerSkyboxFill.begin()
|
||||
Terrarum.shaderBayerSkyboxFill.setUniformMatrix("u_projTrans", camera.combined)
|
||||
Terrarum.shaderBayerSkyboxFill.setUniformf("topColor", gradWhiteTop.r, gradWhiteTop.g, gradWhiteTop.b)
|
||||
Terrarum.shaderBayerSkyboxFill.setUniformf("bottomColor", gradWhiteBottom.r, gradWhiteBottom.g, gradWhiteBottom.b)
|
||||
Terrarum.fullscreenQuad.render(Terrarum.shaderBayerSkyboxFill, GL20.GL_TRIANGLES)
|
||||
Terrarum.shaderBayerSkyboxFill.end()
|
||||
|
||||
batch.inUse {
|
||||
batch.color = Color.WHITE
|
||||
blendNormal()
|
||||
batch.shader = null
|
||||
|
||||
|
||||
setCameraPosition(0f, 0f)
|
||||
batch.draw(logo, (Terrarum.WIDTH - logo.regionWidth) / 2f, (Terrarum.HEIGHT - logo.regionHeight) / 2f)
|
||||
}
|
||||
|
||||
if (!loadDone) {
|
||||
loadThingsWhileIntroIsVisible()
|
||||
}
|
||||
}
|
||||
else {
|
||||
//if (Terrarum.GLOBAL_RENDER_TIMER % 2 == 1) {
|
||||
LightmapRenderer.fireRecalculateEvent()
|
||||
//}
|
||||
|
||||
|
||||
cameraPlayer.hitbox.setPosition(1024 * 16.0, 340 * 16.0)
|
||||
|
||||
|
||||
demoWorld.updateWorldTime(delta)
|
||||
WeatherMixer.update(delta, cameraPlayer)
|
||||
cameraPlayer.update(delta)
|
||||
// worldcamera update AFTER cameraplayer in this case; the other way is just an exception for actual ingame SFX
|
||||
WorldCamera.update(demoWorld, cameraPlayer)
|
||||
|
||||
|
||||
// update UIs //
|
||||
uiMenu.update(delta)
|
||||
|
||||
|
||||
// render and blur lightmap
|
||||
//processBlur(LightmapRenderer.DRAW_FOR_RGB)
|
||||
|
||||
// render world
|
||||
batch.inUse {
|
||||
batch.shader = null
|
||||
camera.position.set(WorldCamera.gdxCamX, WorldCamera.gdxCamY, 0f) // make camara work
|
||||
camera.update()
|
||||
batch.projectionMatrix = camera.combined
|
||||
batch.color = Color.WHITE
|
||||
blendNormal()
|
||||
|
||||
|
||||
|
||||
renderDemoWorld()
|
||||
|
||||
renderMenus()
|
||||
|
||||
renderOverlayTexts()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
deltaCounter += delta
|
||||
}
|
||||
|
||||
private fun renderDemoWorld() {
|
||||
// draw skybox //
|
||||
|
||||
setCameraPosition(0f, 0f)
|
||||
batch.color = Color.WHITE
|
||||
blendNormal()
|
||||
WeatherMixer.render(camera, demoWorld)
|
||||
|
||||
|
||||
// draw tiles //
|
||||
|
||||
// using custom code for camera; this is obscure and tricky
|
||||
camera.position.set(WorldCamera.gdxCamX, WorldCamera.gdxCamY, 0f) // make camara work
|
||||
camera.update()
|
||||
batch.projectionMatrix = camera.combined
|
||||
batch.shader = null
|
||||
|
||||
blendNormal()
|
||||
BlocksDrawer.renderWall(batch)
|
||||
BlocksDrawer.renderTerrain(batch)
|
||||
BlocksDrawer.renderFront(batch, false)
|
||||
FeaturesDrawer.drawEnvOverlay(batch)
|
||||
}
|
||||
|
||||
private fun renderMenus() {
|
||||
setCameraPosition(0f, 0f)
|
||||
blendNormal()
|
||||
batch.shader = null
|
||||
|
||||
|
||||
uiMenu.render(batch, camera)
|
||||
}
|
||||
|
||||
private fun renderOverlayTexts() {
|
||||
setCameraPosition(0f, 0f)
|
||||
blendNormal()
|
||||
batch.shader = null
|
||||
|
||||
batch.color = Color.LIGHT_GRAY
|
||||
|
||||
val COPYTING = arrayOf(
|
||||
COPYRIGHT_DATE_NAME,
|
||||
Lang["COPYRIGHT_GNU_GPL_3"]
|
||||
)
|
||||
|
||||
COPYTING.forEachIndexed { index, s ->
|
||||
val textWidth = Terrarum.fontGame.getWidth(s)
|
||||
Terrarum.fontGame.draw(batch, s,
|
||||
Terrarum.WIDTH - textWidth - 1f - 0.667f,
|
||||
Terrarum.HEIGHT - Terrarum.fontGame.lineHeight * (COPYTING.size - index) - 1f
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun pause() {
|
||||
}
|
||||
|
||||
override fun resume() {
|
||||
}
|
||||
|
||||
override fun resize(width: Int, height: Int) {
|
||||
// Set up viewport when window is resized
|
||||
initViewPort(width, height)
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
logo.texture.dispose()
|
||||
lightmapFboA.dispose()
|
||||
lightmapFboB.dispose()
|
||||
|
||||
uiMenu.dispose()
|
||||
}
|
||||
|
||||
fun setCameraPosition(newX: Float, newY: Float) {
|
||||
Ingame.setCameraPosition(batch, camera, newX, newY)
|
||||
}
|
||||
|
||||
|
||||
fun processBlur(mode: Int) {
|
||||
val blurIterations = 5 // ideally, 4 * radius; must be even/odd number -- odd/even number will flip the image
|
||||
val blurRadius = 4f / Ingame.lightmapDownsample // (5, 4f); using low numbers for pixel-y aesthetics
|
||||
|
||||
blurWriteBuffer = lightmapFboA
|
||||
blurReadBuffer = lightmapFboB
|
||||
|
||||
|
||||
lightmapFboA.inAction(null, null) {
|
||||
Gdx.gl.glClearColor(0f, 0f, 0f, 0f)
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
||||
}
|
||||
lightmapFboB.inAction(null, null) {
|
||||
Gdx.gl.glClearColor(0f, 0f, 0f, 0f)
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
||||
}
|
||||
|
||||
|
||||
if (mode == LightmapRenderer.DRAW_FOR_RGB) {
|
||||
// initialise readBuffer with untreated lightmap
|
||||
blurReadBuffer.inAction(camera, batch) {
|
||||
batch.inUse {
|
||||
// using custom code for camera; this is obscure and tricky
|
||||
camera.position.set(
|
||||
(WorldCamera.gdxCamX / Ingame.lightmapDownsample).round(),
|
||||
(WorldCamera.gdxCamY / Ingame.lightmapDownsample).round(),
|
||||
0f
|
||||
) // make camara work
|
||||
camera.update()
|
||||
batch.projectionMatrix = camera.combined
|
||||
|
||||
|
||||
blendNormal()
|
||||
batch.color = Color.WHITE
|
||||
LightmapRenderer.draw(batch, LightmapRenderer.DRAW_FOR_RGB)
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// initialise readBuffer with untreated lightmap
|
||||
blurReadBuffer.inAction(camera, batch) {
|
||||
batch.inUse {
|
||||
// using custom code for camera; this is obscure and tricky
|
||||
camera.position.set(
|
||||
(WorldCamera.gdxCamX / Ingame.lightmapDownsample).round(),
|
||||
(WorldCamera.gdxCamY / Ingame.lightmapDownsample).round(),
|
||||
0f
|
||||
) // make camara work
|
||||
camera.update()
|
||||
batch.projectionMatrix = camera.combined
|
||||
|
||||
|
||||
blendNormal()
|
||||
batch.color = Color.WHITE
|
||||
LightmapRenderer.draw(batch, LightmapRenderer.DRAW_FOR_ALPHA)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (i in 0 until blurIterations) {
|
||||
blurWriteBuffer.inAction(camera, batch) {
|
||||
|
||||
batch.inUse {
|
||||
val texture = blurReadBuffer.colorBufferTexture
|
||||
|
||||
texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
|
||||
|
||||
|
||||
batch.shader = Terrarum.shaderBlur
|
||||
batch.shader.setUniformf("iResolution",
|
||||
blurWriteBuffer.width.toFloat(), blurWriteBuffer.height.toFloat())
|
||||
batch.shader.setUniformf("flip", 1f)
|
||||
if (i % 2 == 0)
|
||||
batch.shader.setUniformf("direction", blurRadius, 0f)
|
||||
else
|
||||
batch.shader.setUniformf("direction", 0f, blurRadius)
|
||||
|
||||
|
||||
batch.color = Color.WHITE
|
||||
batch.draw(texture, 0f, 0f)
|
||||
|
||||
|
||||
// swap
|
||||
val t = blurWriteBuffer
|
||||
blurWriteBuffer = blurReadBuffer
|
||||
blurReadBuffer = t
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user