aboutsummaryrefslogtreecommitdiff
path: root/client/scripts/controllable_player.gd
blob: 59f4c3de2d54a5bea80b49acd2275bdfc0151cfa (plain)
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
class_name ControllablePlayer
extends Player


const PLAYER_SPEED: float = 25.;

var facing = Vector2(1, 0)
var velocity_ = Vector2(0, 0)

func _ready():
	var timer = Timer.new()
	timer.one_shot = false
	timer.wait_time = 1. / 25.
	add_child(timer)
	timer.start()
	timer.connect("timeout", func():
		Multiplayer.send_position(Vector2(position.x, position.z), rotation.y)
	)

func _process(delta):
	var input = Vector2(Input.get_axis("left", "right"), Input.get_axis("forward", "backwards")).normalized()
	input = input.rotated(-game.camera.angle_target)
	update(delta, input)
	super(delta)

func update(dt: float, input: Vector2):
	var direction = input.limit_length(1.);
	rotation.y = atan2(self.facing.x, self.facing.y);
	if direction.length() > 0.1:
		self.facing = direction + (self.facing - direction) * exp(-dt * 10.);
	self.velocity_ += direction * dt * PLAYER_SPEED;
	self.position_ += self.velocity_ * dt;
	self.velocity_ = self.velocity_ * exp(-dt * 5.);
	collide(dt);

func collide(dt: float):
	for xo in range(-1,2):
		for yo in range(-1,2):
			var tile = Vector2i(xo, yo) + Vector2i(self.position_);
			if !Multiplayer.get_tile_collision(tile): continue
			tile = Vector2(tile)
			var d = aabb_point_distance(tile, tile + Vector2.ONE, self.position_);
			if d > PLAYER_SIZE: continue
			var h = 0.01;
			var d_sample_x = aabb_point_distance(tile, tile + Vector2.ONE, self.position_ + Vector2(h, 0));
			var d_sample_y = aabb_point_distance(tile, tile + Vector2.ONE, self.position_ + Vector2(0, h));
			var grad = (Vector2(d_sample_x - d, d_sample_y - d)) / h;

			self.position_ += (PLAYER_SIZE - d) * grad;
			self.velocity_ -= grad * grad.dot(self.velocity_)
	
	for player: Player in game.players.values():
		var diff = self.position_ - player.position_
		var d = diff.length()
		if d < 0.01: continue
		if d >= PLAYER_SIZE * 2: continue
		var norm = diff.normalized();
		var f = 100 / (1 + d)
		self.velocity_.x += norm.x * f * dt
		self.velocity_.y += norm.y * f * dt

func aabb_point_distance(min: Vector2, max: Vector2, p: Vector2) -> float:
	return (p - p.clamp(min, max)).length()

func update_position(_new_position: Vector2, _new_rotation: float):
	pass