all repos — engine.git @ 70d5a5f53436c4848616132f2ff47c4036adc224

Unnamed repository; edit this file 'description' to name the repository.

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