src/client/client.odin
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
package main
import rl "vendor:raylib"
import "core:time"
import p "../player"
import cm "../common"
SENSITIVITY : f32 : 0.01
SLIGHTLY_DOWN : f32 : -rl.PI/2 + 1e-4
ENTITY_LIMIT : int : 2048
DerivXFloat :: struct {
x: [3]f32,
v: [3]f32,
a: [3]f32,
}
clientEntityDerivX: [dynamic]Maybe(DerivXFloat)
InitClient :: proc() {
clientEntityDerivX = make([dynamic]Maybe(DerivXFloat),256,ENTITY_LIMIT)
debugBoxes = make([dynamic]Maybe(AABox),256,ENTITY_LIMIT)
PlayerInit()
kinematics, ok := p.player^.kinematics[player^.id].?
if !ok do return
simFoward := p.player^.foward
camera = rl.Camera3D{
position = ToFloatVector(kinematics.x) + [3]f32{0.0,2.0,0.0},
fovy = 110.0,
up = [3]f32{0.0,1.0,0.0},
projection = rl.CameraProjection.PERSPECTIVE
}
cameraFoward = ToFloatVector(simFoward)
camera.target = foward^ + cam.position
}
DestroyClient :: proc() {
delete(clientEntityDerivX)
}
ClientUpdate :: proc(clk: ^cm.Clock) {
delta := time.tick_since(clk.lastTick)
CameraControlFPS(&camera, p.player)
MovementControl(&commandBuffer)
ClientKinematicUpdate(delta, &clientEntityDerivX)
Render()
}
ClientKinematicUpdate :: proc(delta: time.Duration, entities: ^[dynamic]Maybe(DerivXFloat)) {
for e,i in entities^ {
eNew, ok := e.?
if !ok do continue
eNew.v += eNew.a * f32(time.duration_seconds(delta))
eNew.x += eNew.v * f32(time.duration_seconds(delta))
entities[i] = eNew
}
}
CameraControlFPS :: proc (cam: ^rl.Camera3D, player: Player) {
kinematics, ok := player.clientKinematics[player.id].?
if !ok do return
delta: rl.Vector2 = rl.GetMouseDelta()
yaw: f32 = -SENSITIVITY*delta.x
pitch: f32 = -SENSITIVITY*delta.y
cameraFoward = rl.Vector3RotateByAxisAngle(cameraFoward,cam.up,yaw)
pitchAxis := rl.Vector3CrossProduct(cameraFoward,cam.up)
newTarget := cam.target-cam.position
newTarget = rl.Vector3RotateByAxisAngle(newTarget,cam.up,yaw)
newTarget = rl.Vector3RotateByAxisAngle(newTarget,pitchAxis,pitch)
cam.position = kinematics.x + [3]f32{0.0,2.0,0.0}
if rl.Vector3DotProduct(newTarget,cameraFoward) <= 0 && newTarget[1] > 0 {
cam.target = cam.position + rl.Vector3RotateByAxisAngle(cameraFoward,pitchAxis,-SLIGHTLY_DOWN)
} else if rl.Vector3DotProduct(newTarget,cameraFoward) <= 0 && newTarget[1] < 0 {
cam.target = cam.position + rl.Vector3RotateByAxisAngle(cameraFoward,pitchAxis,SLIGHTLY_DOWN)
} else {
cam.target = cam.position + newTarget
}
}
MovementControl :: proc(commandBuffer: ^bit_set[Command]) {
if rl.IsKeyDown(rl.KeyboardKey.W) {
commandBuffer^ += {.MOVE_FOWARDS}
}
if rl.IsKeyDown(rl.KeyboardKey.S) {
commandBuffer^ += {.MOVE_BACKWARDS}
}
if rl.IsKeyDown(rl.KeyboardKey.A) {
commandBuffer^ += {.STRAFE_LEFT}
}
if rl.IsKeyDown(rl.KeyboardKey.D) {
commandBuffer^ += {.STRAFE_RIGHT}
}
if rl.IsKeyPressed(rl.KeyboardKey.SPACE) {
commandBuffer^ += {.JUMP}
}
}
|