aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/kotlin')
-rw-r--r--src/main/kotlin/Camera.kt4
-rw-r--r--src/main/kotlin/CameraController.kt15
-rw-r--r--src/main/kotlin/Minimap.kt11
-rw-r--r--src/main/kotlin/RaycastContext.kt1
-rw-r--r--src/main/kotlin/Raycaster.kt17
-rw-r--r--src/main/kotlin/Renderer.kt10
-rw-r--r--src/main/kotlin/Ui.kt58
-rw-r--r--src/main/kotlin/main.kt8
8 files changed, 90 insertions, 34 deletions
diff --git a/src/main/kotlin/Camera.kt b/src/main/kotlin/Camera.kt
index 4eb8d43..3c2e582 100644
--- a/src/main/kotlin/Camera.kt
+++ b/src/main/kotlin/Camera.kt
@@ -1,6 +1,6 @@
data class Camera(
- val fov: Int,
+ var fov: Int,
var xPos: Double,
var yPos: Double,
- var rotation: Double
+ var rotation: Double,
) \ No newline at end of file
diff --git a/src/main/kotlin/CameraController.kt b/src/main/kotlin/CameraController.kt
index 436b34b..510f1a0 100644
--- a/src/main/kotlin/CameraController.kt
+++ b/src/main/kotlin/CameraController.kt
@@ -1,4 +1,5 @@
import kotlinx.browser.document
+import org.w3c.dom.HTMLButtonElement
class CameraController(
private val camera: Camera,
@@ -8,18 +9,20 @@ class CameraController(
) {
init {
- document.onkeydown = { inputHandler(it.code) }
+ document.onkeydown = { keyHandler(it.code) }
+ (document.getElementById("up") as HTMLButtonElement).onclick = { moveForward() }
+ (document.getElementById("down") as HTMLButtonElement).onclick = { moveBack() }
+ (document.getElementById("left") as HTMLButtonElement).onclick = { rotateAntiClockwise() }
+ (document.getElementById("right") as HTMLButtonElement).onclick = { rotateClockwise() }
}
- private fun inputHandler(code: String) {
+ private fun keyHandler(code: String) {
when (code) {
"KeyW" -> moveForward()
"KeyS" -> moveBack()
"KeyA" -> rotateAntiClockwise()
"KeyD" -> rotateClockwise()
}
- afterInput()
- console.log("x: ${camera.xPos} y: ${camera.yPos} r: ${camera.rotation}")
}
private fun moveForward() {
@@ -27,6 +30,7 @@ class CameraController(
val cameraSin = camera.rotation.sine() * moveSpeed
camera.xPos += cameraCos
camera.yPos += cameraSin
+ afterInput()
}
private fun moveBack() {
@@ -34,14 +38,17 @@ class CameraController(
val cameraSin = camera.rotation.sine() * moveSpeed
camera.xPos -= cameraCos
camera.yPos -= cameraSin
+ afterInput()
}
private fun rotateClockwise() {
camera.rotation += rotateSpeed
+ afterInput()
}
private fun rotateAntiClockwise() {
camera.rotation -= rotateSpeed
+ afterInput()
}
} \ No newline at end of file
diff --git a/src/main/kotlin/Minimap.kt b/src/main/kotlin/Minimap.kt
index 34862e0..7cbc892 100644
--- a/src/main/kotlin/Minimap.kt
+++ b/src/main/kotlin/Minimap.kt
@@ -3,26 +3,21 @@ import org.w3c.dom.CanvasRenderingContext2D
import org.w3c.dom.HTMLCanvasElement
class Minimap(private val map: Map) {
- private val scale = 20
+ private val scale = 15
- private val canvas = (document.createElement("canvas") as HTMLCanvasElement)
+ private val canvas = (document.getElementById("minimap") as HTMLCanvasElement)
.apply {
width = map.width * scale
height = map.height * scale
- id = "minimap"
}
private val context = canvas.getContext("2d") as CanvasRenderingContext2D
- init {
- document.body!!.appendChild(canvas)
- }
-
private fun drawMap() {
for (y in 0 until map.height) {
for (x in 0 until map.width) {
val wall = map.data[y][x]
if (wall > 0) {
- context.fillStyle = "#000000"
+ context.fillStyle = "#202020"
context.fillRect((x * scale).toDouble(), (y * scale).toDouble(), scale.toDouble(), scale.toDouble())
}
}
diff --git a/src/main/kotlin/RaycastContext.kt b/src/main/kotlin/RaycastContext.kt
index 808f3c4..2f8ec9c 100644
--- a/src/main/kotlin/RaycastContext.kt
+++ b/src/main/kotlin/RaycastContext.kt
@@ -1,4 +1,5 @@
data class RaycastContext(
+ val raycastOptions: RaycastOptions,
val renderer: Renderer,
val textureManager: TextureManager,
val camera: Camera,
diff --git a/src/main/kotlin/Raycaster.kt b/src/main/kotlin/Raycaster.kt
index ff2cc24..04b4d6f 100644
--- a/src/main/kotlin/Raycaster.kt
+++ b/src/main/kotlin/Raycaster.kt
@@ -1,11 +1,16 @@
import kotlin.js.Date
import kotlin.math.pow
-class Raycaster(private val stepPrecision: Int) {
+data class RaycastOptions(
+ var fixFisheye: Boolean,
+ var stepPrecision: Int
+)
+
+class Raycaster {
fun raycast(raycastContext: RaycastContext) {
val raycastStartMs = Date().getTime()
- val (renderer, textureManager, camera, map, _) = raycastContext
+ val (options, renderer, textureManager, camera, map, _) = raycastContext
val viewportWidth = renderer.viewportWidth
val viewportHeight = renderer.viewportHeight
@@ -20,8 +25,8 @@ class Raycaster(private val stepPrecision: Int) {
var objectTypeHit: Int
do {
- rayX += raySweepAngle.cosine() / stepPrecision
- rayY += raySweepAngle.sine() / stepPrecision
+ rayX += raySweepAngle.cosine() / options.stepPrecision
+ rayY += raySweepAngle.sine() / options.stepPrecision
// TODO bounds checking
objectTypeHit = map.data[rayY.toFlooredInt()][rayX.toFlooredInt()]
@@ -31,7 +36,9 @@ class Raycaster(private val stepPrecision: Int) {
val textureXIndex = ((texture.width * (rayX + rayY)) % texture.width).toFlooredInt()
var distanceToWall = kotlin.math.sqrt((camera.xPos - rayX).pow(2) + (camera.yPos - rayY).pow(2))
-// distanceToWall *= (raySweepAngle-camera.rotation).cosine()
+ if (options.fixFisheye) {
+ distanceToWall *= (raySweepAngle-camera.rotation).cosine()
+ }
val wallHeight = viewportHeightHalf / distanceToWall
// Ceiling
diff --git a/src/main/kotlin/Renderer.kt b/src/main/kotlin/Renderer.kt
index 3a7111e..49d6b2c 100644
--- a/src/main/kotlin/Renderer.kt
+++ b/src/main/kotlin/Renderer.kt
@@ -4,18 +4,14 @@ import org.w3c.dom.HTMLCanvasElement
class Renderer(val viewportWidth: Int, val viewportHeight: Int, private val outputScale: Int) {
- private val canvas = (document.createElement("canvas") as HTMLCanvasElement)
+ private val canvas = (document.getElementById("render-output") as HTMLCanvasElement)
.apply {
width = viewportWidth * outputScale
height = viewportHeight * outputScale
}
- private val context = canvas.getContext("2d") as CanvasRenderingContext2D
-
- init {
- context.scale(outputScale.toDouble(), outputScale.toDouble())
- document.body!!.appendChild(canvas)
- }
+ private val context = (canvas.getContext("2d") as CanvasRenderingContext2D)
+ .apply { scale(outputScale.toDouble(), outputScale.toDouble()) }
fun drawLine(startX: Double, startY: Double, endX: Double, endY: Double, cssColour: String = "#FF0000") {
context.strokeStyle = cssColour
diff --git a/src/main/kotlin/Ui.kt b/src/main/kotlin/Ui.kt
index e477bec..dd8b0fc 100644
--- a/src/main/kotlin/Ui.kt
+++ b/src/main/kotlin/Ui.kt
@@ -1,23 +1,71 @@
import kotlinx.browser.document
+import kotlinx.dom.removeClass
+import org.w3c.dom.HTMLElement
+import org.w3c.dom.HTMLInputElement
import org.w3c.dom.HTMLSelectElement
-class Ui(private val textureManager: TextureManager, private val afterChange: () -> Unit) {
- private val textureSelect: HTMLSelectElement
+class Ui(private val context: RaycastContext, private val afterChange: () -> Unit) {
+
+ private val textureSelect = registerTextureSetHandler()
+
init {
- textureSelect = registerTextureSetHandler()
+ registerFovInputHandler()
+ registerRaycastPrecisionInputHandler()
+ registerMinimapToggleHandler()
+ registerFisheyeToggleHandler()
}
private fun registerTextureSetHandler(): HTMLSelectElement {
val select = document.getElementById("texture-set") as HTMLSelectElement
select.onchange = {
- textureManager.loadTextures(select.value)
+ context.textureManager.loadTextures(select.value)
afterChange()
}
-
return select
}
+ private fun registerFovInputHandler() {
+ val fov = document.getElementById("fov") as HTMLInputElement
+ val fovValue = document.getElementById("fov-value") as HTMLElement
+ fov.oninput = {
+ context.camera.fov = fov.value.toInt()
+ fovValue.textContent = fov.value
+ afterChange()
+ }
+ }
+
+ private fun registerRaycastPrecisionInputHandler() {
+ val precision = document.getElementById("raycast-precision") as HTMLInputElement
+ val precisionValue = document.getElementById("raycast-precision-value") as HTMLElement
+ precision.oninput = {
+ context.raycastOptions.stepPrecision = precision.value.toInt()
+ precisionValue.textContent = precision.value
+ afterChange()
+ }
+ }
+
+ private fun registerMinimapToggleHandler() {
+ val toggle = document.getElementById("minimap-toggle") as HTMLInputElement
+ val minimap = document.getElementById("minimap") as HTMLElement
+ toggle.onchange = {
+ minimap.hidden = !toggle.checked
+ afterChange()
+ }
+ }
+
+ private fun registerFisheyeToggleHandler() {
+ val fixFisheye = document.getElementById("fisheye-fix") as HTMLInputElement
+ fixFisheye.oninput = {
+ context.raycastOptions.fixFisheye = fixFisheye.checked
+ afterChange()
+ }
+ }
+
fun getSelectedTextureSet(): String {
return textureSelect.value
}
+
+ fun removeLoadingIndicator() {
+ document.getElementById("output-wrapper")?.removeClass("loading")
+ }
} \ No newline at end of file
diff --git a/src/main/kotlin/main.kt b/src/main/kotlin/main.kt
index bc39316..aa69ad2 100644
--- a/src/main/kotlin/main.kt
+++ b/src/main/kotlin/main.kt
@@ -1,4 +1,5 @@
fun main() {
+ val raycastOptions = RaycastOptions(fixFisheye = false, stepPrecision = 32)
val renderer = Renderer(viewportWidth = 320, viewportHeight = 240, outputScale = 3)
val textureManager = TextureManager()
val camera = Camera(
@@ -10,15 +11,15 @@ fun main() {
val map = Map()
val minimap = Minimap(map)
- val context = RaycastContext(renderer, textureManager, camera, map, minimap)
+ val context = RaycastContext(raycastOptions, renderer, textureManager, camera, map, minimap)
- val raycaster = Raycaster(stepPrecision = 32)
+ val raycaster = Raycaster()
CameraController(camera, moveSpeed = 1.0, rotateSpeed = 15) {
paint(raycaster, context)
}
- val ui = Ui(textureManager) {
+ val ui = Ui(context) {
paint(raycaster, context)
}
@@ -26,6 +27,7 @@ fun main() {
// Do an initial paint and wait for input
paint(raycaster, context)
+ ui.removeLoadingIndicator()
}
fun paint(raycaster: Raycaster, raycastContext: RaycastContext) {