From 1b13535efd4d6dd3a2fa00047dfe678e8ac7aca3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lera=20Elvo=C3=A9?= Date: Sun, 2 Feb 2025 06:14:21 +0300 Subject: [PATCH] split player into its own class file, use udata for state --- data/scripts/classes/player.lua | 41 +++++++++++++++++++ data/scripts/game.lua | 70 +++++---------------------------- data/scripts/trig.lua | 3 -- data/scripts/util.lua | 20 ++++++++++ data/scripts/vector3.lua | 38 +++++++++++++++++- 5 files changed, 108 insertions(+), 64 deletions(-) create mode 100644 data/scripts/classes/player.lua delete mode 100644 data/scripts/trig.lua create mode 100644 data/scripts/util.lua diff --git a/data/scripts/classes/player.lua b/data/scripts/classes/player.lua new file mode 100644 index 0000000..0b5c38c --- /dev/null +++ b/data/scripts/classes/player.lua @@ -0,0 +1,41 @@ +local Vector3 = require "vector3" +local util = require "util" + +-- this is a static class, so no instancing shenanigans needed + +local Player = { + position = Vector3(), + velocity = Vector3(), + + speed = 0.07, + mouse_sensitivity = 0.01, + + yaw = 0, + yaw_speed = 0.05, +} + +function Player:tick(ctx) + input_action{name = "left", control = "A"} + input_action{name = "right", control = "D"} + input_action{name = "forward", control = "W"} + input_action{name = "back", control = "S"} + + local camera_forward = Vector3(draw_camera_from_principal_axes(self).direction) + camera_forward.y = 0 + camera_forward = camera_forward:normalized() + local camera_right = camera_forward:cross(Vector3.UP) + + local forward_input = util.b2n(input_action_pressed{name = "forward"}) - util.b2n(input_action_pressed{name = "back"}) + local strafe_input = util.b2n(input_action_pressed{name = "right"}) - util.b2n(input_action_pressed{name = "left"}) + + local direction = ((camera_forward * forward_input) + (camera_right * strafe_input)):normalized() + self.velocity = direction * self.speed + + if ctx.mouse_capture then + self.yaw = self.yaw + self.mouse_sensitivity * ctx.mouse_movement.x + end + + self.position = self.position + self.velocity +end + +return Player \ No newline at end of file diff --git a/data/scripts/game.lua b/data/scripts/game.lua index b16cb1e..7245b97 100644 --- a/data/scripts/game.lua +++ b/data/scripts/game.lua @@ -1,17 +1,7 @@ local FONT = "fonts/Lunchtype21_Regular.ttf" local Vector3 = require "vector3" -local capture = false - -local head_rotation = 0 -local rotate_speed = 0.05 - -local mouse_sensitivity = 0.01 - -local spd = 0.07 - -local position = Vector3() -local velocity = Vector3() +local player = require "classes.player" local function Vector2(x, y) if y == nil then @@ -20,63 +10,23 @@ local function Vector2(x, y) return {x = x, y = y} end -local function wrap(value, min, max) - local range = max - min - if value == 0 then - return min - end - - local result = value - (range * math.floor((value - min) / range)) - if result == max then - return min - end - - return result -end - -local function b2n(value) - return value and 1 or 0 -end - function game_tick() -- ctx.initialization_needed is true first frame and every time dynamic reload is performed if ctx.initialization_needed then -- ctx.udata persists on reload - ctx.udata = {} - end - ctx.mouse_capture = capture - input_action{name="toggle_mouse", control="ESCAPE"} - - input_action{name = "left", control = "A"} - input_action{name = "right", control = "D"} - input_action{name = "forward", control = "W"} - input_action{name = "back", control = "S"} - - if input_action_just_pressed{name = "toggle_mouse"} then - if not capture then - capture = true - else + ctx.udata = { capture = false - end + } end - - local dir = Vector3(draw_camera_from_principal_axes{position = position, yaw = head_rotation}.direction) - dir.y = 0 - dir = dir:normalized() - - if not capture then - local rot_d = b2n(input_action_pressed{name = "right"}) - b2n(input_action_pressed{name = "left"}) - head_rotation = head_rotation + rot_d * rotate_speed - else - head_rotation = head_rotation + mouse_sensitivity * ctx.mouse_movement.x + ctx.mouse_capture = ctx.udata.capture + input_action{name="toggle_mouse", control="ESCAPE"} + if input_action_just_pressed{name = "toggle_mouse"} then + ctx.udata.capture = not ctx.udata.capture end - local mov_d = b2n(input_action_pressed{name = "forward"}) - b2n(input_action_pressed{name = "back"}) - velocity = dir * spd * mov_d + player:tick(ctx) - position = position + velocity + draw_billboard{position = Vector3(0, 0, 3), size = Vector2(1, 1), texture = "images/duck.png"} - draw_billboard{position = Vector3(5, 0, 0), size = Vector2(1, 1), texture = "images/duck.png"} - - draw_text{position = Vector2(0), string = "vel: " .. tostring(velocity), font = FONT} + draw_text{position = Vector2(0), string = "vel: " .. tostring(player.velocity), font = FONT} end diff --git a/data/scripts/trig.lua b/data/scripts/trig.lua deleted file mode 100644 index 72d5050..0000000 --- a/data/scripts/trig.lua +++ /dev/null @@ -1,3 +0,0 @@ -local M = {} - -return M \ No newline at end of file diff --git a/data/scripts/util.lua b/data/scripts/util.lua new file mode 100644 index 0000000..b70a00a --- /dev/null +++ b/data/scripts/util.lua @@ -0,0 +1,20 @@ +local util = {} + +function util.printt(t) + if type(t) == 'table' then + local s = '{ ' + for k,v in pairs(t) do + if type(k) ~= 'number' then k = '"'..k..'"' end + s = s .. '['..k..'] = ' .. util.print(v) .. ',' + end + return s .. '} ' + else + return tostring(t) + end +end + +function util.b2n(value) + return value and 1 or 0 +end + +return util \ No newline at end of file diff --git a/data/scripts/vector3.lua b/data/scripts/vector3.lua index 7856d4d..6be968a 100644 --- a/data/scripts/vector3.lua +++ b/data/scripts/vector3.lua @@ -135,7 +135,43 @@ end function Vector3:normalized() local length = math.sqrt(self:length_squared()) + if length == 0 then + return Vector3() + end return Vector3(self.x / length, self.y / length, self.z / length) end + +function Vector3:dot(with) + if not is_weak_vector3(with) then + error("Vector3: with must be a Vector3-like table. Returning 0") + return 0 + end + + local v2 = Vector3(with) + return self.x * v2.x + self.y * v2.y + self.z * v2.z +end + +function Vector3:cross(with) + if not is_weak_vector3(with) then + error("Vector3: with must be a Vector3-like table. Returning Vector3()") + return Vector3() + end + local v2 = Vector3(with) + return Vector3 { + self.y * v2.z - self.z * v2.y, + self.z * v2.x - self.x * v2.z, + self.x * v2.y - self.y * v2.x, + } +end + +---- CONSTANTS + +Vector3.UP = Vector3(0, 1, 0) +Vector3.DOWN = -Vector3.UP +Vector3.FORWARD = Vector3(0, 0, -1) +Vector3.BACK = -Vector3.FORWARD +Vector3.RIGHT = Vector3(1, 0, 0) +Vector3.LEFT = -Vector3.RIGHT + ------------------- -return Vector3 \ No newline at end of file +return Vector3