Files
CavesOfJolk-libgdx/src/main/kotlin/Game.kt

284 lines
8.9 KiB
Kotlin
Raw Normal View History

2023-08-16 13:10:48 +10:00
package gay.pizza.CavesOfJolk
import com.badlogic.gdx.ApplicationAdapter
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.*
import com.badlogic.gdx.graphics.g2d.BitmapFont
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.g3d.*
2023-08-19 01:38:20 +10:00
import com.badlogic.gdx.graphics.g3d.attributes.*
2023-08-16 13:10:48 +10:00
import com.badlogic.gdx.graphics.g3d.environment.DirectionalLight
2023-08-18 04:48:22 +10:00
import com.badlogic.gdx.graphics.g3d.environment.PointLight
2023-08-18 02:51:54 +10:00
import com.badlogic.gdx.graphics.g3d.model.data.*
2023-08-16 13:10:48 +10:00
import com.badlogic.gdx.graphics.g3d.shaders.DefaultShader
import com.badlogic.gdx.graphics.g3d.utils.ModelBuilder
import com.badlogic.gdx.graphics.g3d.utils.TextureDescriptor
2023-08-19 05:46:29 +10:00
import com.badlogic.gdx.graphics.g3d.utils.TextureProvider.AssetTextureProvider
2023-08-16 13:10:48 +10:00
import com.badlogic.gdx.math.*
2023-08-18 02:51:54 +10:00
import com.badlogic.gdx.utils.Array
2023-08-16 13:10:48 +10:00
import com.badlogic.gdx.utils.ScreenUtils
import gay.pizza.CavesOfJolk.Resources.Companion.assetManager
2023-08-19 06:33:56 +10:00
import ktx.math.times
2023-08-16 13:10:48 +10:00
class Game: ApplicationAdapter()
{
private lateinit var texJolk: Texture
private lateinit var fntComic: BitmapFont
private lateinit var cube: Model
private lateinit var floor: Model
private lateinit var spriteBatch: SpriteBatch
private lateinit var modelBatch: ModelBatch
private lateinit var env: Environment
private lateinit var colin: Colin
private var jolkRot = 0.0f
2023-08-19 01:38:20 +10:00
private var lightTheta = 0.0f
2023-08-16 13:10:48 +10:00
private lateinit var cubeInstance: ModelInstance
private lateinit var floorInstance: ModelInstance
private lateinit var suzanneInstance: ModelInstance
2023-08-19 06:58:55 +10:00
private lateinit var rockBatch: ModelCache
2023-08-16 13:10:48 +10:00
private fun makeCube(texture: Texture): Model
{
val modelBuilder = ModelBuilder()
val size = 2.0f
2023-08-16 16:26:05 +10:00
val material = Material(
ColorAttribute.createDiffuse(XnaColor.White),
TextureAttribute(TextureAttribute.Diffuse,
TextureDescriptor(texture,
Texture.TextureFilter.Linear,
Texture.TextureFilter.Linear,
Texture.TextureWrap.ClampToEdge,
Texture.TextureWrap.ClampToEdge)),
ColorAttribute.createSpecular(XnaColor.Gray),
FloatAttribute.createShininess(20.0f))
2023-08-16 13:10:48 +10:00
val attribs = VertexAttributes.Usage.Position or VertexAttributes.Usage.TextureCoordinates or VertexAttributes.Usage.Normal
return modelBuilder.createBox(size, size, size, material, attribs.toLong())
}
2023-08-20 05:57:33 +10:00
private fun makeFloor(size: Float): Model
2023-08-16 13:10:48 +10:00
{
2023-08-20 05:57:33 +10:00
val texs = size / 4.0f
2023-08-18 02:51:54 +10:00
2023-08-19 05:46:29 +10:00
val vertex = { pos: Vector3, tex: Vector2 ->
val normal = Util.up
val tangent = Util.right
val bitangent = Util.forward
floatArrayOf(
pos.x, pos.y, pos.z,
normal.x, normal.y, normal.z, tangent.x, tangent.y, tangent.z, bitangent.x, bitangent.y, bitangent.z,
tex.x, tex.y)
}
val modelTexture = { modelTextureUsage: Int, textureFilename: String -> ModelTexture().apply {
usage = modelTextureUsage
fileName = textureFilename
}}
return Model(ModelData().apply {
addMesh(ModelMesh().apply {
id = "floormodel"
attributes = arrayOf(VertexAttribute.Position(), VertexAttribute.Normal(), VertexAttribute.Tangent(), VertexAttribute.Binormal(), VertexAttribute.TexCoords(0))
vertices =
vertex(Vector3(0.0f, 0.0f, 0.0f), Vector2(0.0f, texs)) +
vertex(Vector3(size, 0.0f, 0.0f), Vector2(texs, texs)) +
vertex(Vector3(0.0f, 0.0f, -size), Vector2(0.0f, 0.0f)) +
vertex(Vector3(size, 0.0f, -size), Vector2(texs, 0.0f))
parts = arrayOf(ModelMeshPart().apply {
id = "floormesh"
primitiveType = GL20.GL_TRIANGLES
indices = shortArrayOf(
0, 1, 2,
3, 2, 1)
})
})
materials.add(ModelMaterial().apply {
id = "floormat"
diffuse = XnaColor.White
specular = XnaColor.BlanchedAlmond.mix(XnaColor.Black, 0.12f)
shininess = 65.0f
textures = Array()
textures.add(
modelTexture(ModelTexture.USAGE_DIFFUSE, "cobblestone.png"),
modelTexture(ModelTexture.USAGE_NORMAL, "cobblestone_normal.png"),
modelTexture(ModelTexture.USAGE_SPECULAR, "cobblestone_specular.png"))
})
nodes.add(ModelNode().apply {
id = "floornode"
scale = Util.one
parts = arrayOf(ModelNodePart().apply {
meshPartId = "floormesh"
materialId = "floormat"
})
})
}, AssetTextureProvider(assetManager))
2023-08-16 13:10:48 +10:00
}
override fun create()
{
Resources.instance.loadAssets()
assetManager.finishLoading()
texJolk = assetManager.get("jolkmeup.jpg")
fntComic = assetManager.get("Comic Sans MS.ttf")
cube = makeCube(texJolk)
2023-08-20 05:57:33 +10:00
var joeMany = 56.0f
floor = makeFloor(joeMany)
2023-08-16 13:10:48 +10:00
spriteBatch = SpriteBatch()
env = Environment()
2023-08-17 21:17:28 +10:00
env.set(
IntAttribute.createCullFace(GL20.GL_BACK),
2023-08-18 04:48:22 +10:00
ColorAttribute.createAmbientLight(XnaColor.DarkSlateGray.lighten(-0.666)),
2023-08-17 21:17:28 +10:00
ColorAttribute.createFog(XnaColor.CornflowerBlue))
env.set(
CustomIntAttribute.createFogMode(CustomIntAttribute.FogModes.Depth),
CustomIntAttribute.createFogType(CustomIntAttribute.FogTypes.Smooth),
2023-08-18 04:48:22 +10:00
CustomFloatAttribute.createFogNear(1.25f),
CustomFloatAttribute.createFogFar(24.5f))
2023-08-17 21:17:28 +10:00
/*
env.set(
CustomIntAttribute.createFogMode(CustomIntAttribute.FogModes.Distance),
CustomIntAttribute.createFogType(CustomIntAttribute.FogTypes.Exp2),
CustomFloatAttribute.createFogDensity(0.1f))
*/
2023-08-18 02:51:54 +10:00
env.add(DirectionalLight().set(
2023-08-18 04:48:22 +10:00
XnaColor.BlanchedAlmond.lighten(-0.02).mix(XnaColor.LightSlateGray, 0.5f).mix(XnaColor.White, 0.125f),
2023-08-18 02:51:54 +10:00
Vector3(1.0f, -1.0f, -1.0f).nor()))
2023-08-18 04:48:22 +10:00
env.add(PointLight().set(
XnaColor.Green.mix(XnaColor.Gray, 0.5f),
Vector3(3.0f, 0.33f, -5.0f), 2.0f))
env.add(PointLight().set(
XnaColor.Red.mix(XnaColor.Gray, 0.5f),
Vector3(5.5f, 0.33f, -6.0f), 2.0f))
env.add(PointLight().set(
XnaColor.Blue.mix(XnaColor.Gray, 0.5f),
Vector3(4.0f, 0.33f, -7.0f), 2.0f))
2023-08-16 13:10:48 +10:00
2023-08-17 21:17:28 +10:00
val shaderConfig = DefaultShader.Config()
2023-08-16 13:10:48 +10:00
shaderConfig.numDirectionalLights = 1
2023-08-18 04:48:22 +10:00
shaderConfig.numPointLights = 3
2023-08-16 13:10:48 +10:00
shaderConfig.numBones = 0
2023-08-17 21:17:28 +10:00
modelBatch = ModelBatch(CustomDefaultShaderProvider(shaderConfig))
2023-08-16 13:10:48 +10:00
colin = Colin()
cubeInstance = ModelInstance(cube)
floorInstance = ModelInstance(floor)
2023-08-19 06:33:56 +10:00
suzanneInstance = ModelInstance(assetManager.get("suzanne.g3db", Model::class.java))
val rock = assetManager.get("rock.g3db", Model::class.java)
2023-08-20 05:57:33 +10:00
val rand = RandomXS128(69 + 420 + 1919 + 916 + 42 + 1)
2023-08-19 06:33:56 +10:00
val randQuaternion = { rand: RandomXS128 ->
var x: Float
var y: Float
var z: Float
do { x = rand.nextFloat(-1.0f, 1.0f); y = rand.nextFloat(-1.0f, 1.0f); z = x * x + y * y } while (z > 1.0f)
var u: Float
var v: Float
var w: Float
do { u = rand.nextFloat(-1.0f, 1.0f); v = rand.nextFloat(-1.0f, 1.0f); w = u * u + v * v } while (w > 1.0f)
val s = kotlin.math.sqrt((1.0f - z) / w)
Quaternion(x, y, s * u, s * v)
}
2023-08-20 05:57:33 +10:00
val rocks = Array(75) { i->
2023-08-19 06:33:56 +10:00
ModelInstance(rock, Matrix4(
Vector3(
2023-08-20 05:57:33 +10:00
rand.nextFloat(joeMany),
rand.nextFloat(-0.75f, 10.125f),
-rand.nextFloat(joeMany)),
2023-08-19 06:33:56 +10:00
randQuaternion(rand),
2023-08-20 05:57:33 +10:00
Util.one * rand.nextFloat(0.6f, 6.2f)))
2023-08-19 06:33:56 +10:00
}
2023-08-19 06:58:55 +10:00
rockBatch = ModelCache().apply {
begin()
add(rocks.asIterable())
end()
}
2023-08-16 13:10:48 +10:00
suzanneInstance.transform = Matrix4().translate(3.0f, 1.0f, -3.5f)
}
2023-08-16 16:54:45 +10:00
override fun resize(width: Int, height: Int)
{
colin.resize(width, height)
spriteBatch.projectionMatrix.setToOrtho2D(0.0f, 0.0f,
Gdx.graphics.getWidth().toFloat(),
Gdx.graphics.getHeight().toFloat());
}
2023-08-16 13:10:48 +10:00
private fun update(deltaTime: Float)
{
colin.update(deltaTime)
2023-08-19 01:38:20 +10:00
lightTheta += deltaTime
2023-08-16 13:10:48 +10:00
jolkRot += 15.0f * deltaTime
}
override fun render()
{
val deltaTime = Gdx.graphics.deltaTime
update(deltaTime)
2023-08-17 21:17:28 +10:00
ScreenUtils.clear(XnaColor.CornflowerBlue, true)
2023-08-16 13:10:48 +10:00
2023-08-19 01:38:20 +10:00
env.get(PointLightsAttribute.Type)?.let { it as PointLightsAttribute
var thetaa = lightTheta * 6.0f * 0.12f
var thetab = lightTheta * 6.0f * 0.011f
var thetac = lightTheta * 6.0f * 0.056f
for (light in it.lights)
{
val x = 4.0f + 6.0f * MathUtils.cos(thetaa)
val z = -6.0f + 3.0f * MathUtils.sin(thetaa * 2.0f)
val y = 0.33f + 0.33f * MathUtils.sin(thetab)
val i = 3.1f + 1.53f * MathUtils.cos(thetac)
val spacing = 0.5f * MathUtils.PI * (2.0f / 3.0f)
thetaa += spacing
thetab += spacing * 0.98f
thetac += spacing * 0.5566f
light.setPosition(x, y, z)
light.setIntensity(i)
}
}
2023-08-16 13:10:48 +10:00
val jolkPos = Vector3(0.0f, 1.0f + MathUtils.sin(jolkRot * 0.25f) * 0.25f, -4.0f)
val world = Matrix4()
.setTranslation(jolkPos)
.rotateRad(1.0f, 0.0f, 0.0f, jolkRot * 0.25f)
.rotate(0.0f, 1.0f, 0.0f, jolkRot)
.scale(0.25f, 0.25f, 0.25f)
cubeInstance.transform = world
modelBatch.begin(colin.camera)
modelBatch.render(floorInstance, env)
2023-08-19 06:58:55 +10:00
modelBatch.render(rockBatch, env)
2023-08-16 13:10:48 +10:00
modelBatch.render(cubeInstance, env)
modelBatch.render(suzanneInstance, env)
modelBatch.end()
spriteBatch.begin()
colin.draw(spriteBatch)
val textPos = colin.camera.project(jolkPos)
if (textPos.z < 1.0)
fntComic.draw(spriteBatch, "I am filled with jolk", textPos.x, textPos.y)
fntComic.draw(spriteBatch, "${colin.position.x}\n${colin.position.y}", 10.0f, Gdx.graphics.height - 10.0f)
spriteBatch.end()
}
override fun dispose()
{
2023-08-19 06:58:55 +10:00
rockBatch.dispose()
2023-08-16 13:10:48 +10:00
floor.dispose()
cube.dispose()
modelBatch.dispose()
spriteBatch.dispose()
assetManager.dispose()
}
}