split player into its own class file, use udata for state

This commit is contained in:
Lera Elvoé 2025-02-02 06:14:21 +03:00
parent 35b06ec9db
commit 1b13535efd
Signed by: yagich
SSH Key Fingerprint: SHA256:6xjGb6uA7lAVcULa7byPEN//rQ0wPoG+UzYVMfZnbvc
5 changed files with 108 additions and 64 deletions

View File

@ -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

View File

@ -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

View File

@ -1,3 +0,0 @@
local M = {}
return M

20
data/scripts/util.lua Normal file
View File

@ -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

View File

@ -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
return Vector3