diff options
| author | metamuffin <metamuffin@disroot.org> | 2024-06-22 18:10:07 +0200 | 
|---|---|---|
| committer | metamuffin <metamuffin@disroot.org> | 2024-06-23 19:28:39 +0200 | 
| commit | e366cfdf9133c0da798352c474580d329c6a0f33 (patch) | |
| tree | 1cb97c585cd7c457f3205cacc36cdd183883ac5f /client | |
| parent | 512ea1fce397549e2dd2f2b24adde5bc074b4ad2 (diff) | |
| download | hurrycurry-e366cfdf9133c0da798352c474580d329c6a0f33.tar hurrycurry-e366cfdf9133c0da798352c474580d329c6a0f33.tar.bz2 hurrycurry-e366cfdf9133c0da798352c474580d329c6a0f33.tar.zst | |
player collisions and better movement code
Diffstat (limited to 'client')
| -rw-r--r-- | client/scripts/controllable_player.gd | 122 | ||||
| -rw-r--r-- | client/scripts/game.gd | 7 | ||||
| -rw-r--r-- | client/scripts/map.gd | 4 | ||||
| -rw-r--r-- | client/scripts/multiplayer.gd | 4 | ||||
| -rw-r--r-- | client/scripts/player.gd | 14 | 
5 files changed, 63 insertions, 88 deletions
| diff --git a/client/scripts/controllable_player.gd b/client/scripts/controllable_player.gd index 58ac4401..34ef5859 100644 --- a/client/scripts/controllable_player.gd +++ b/client/scripts/controllable_player.gd @@ -1,11 +1,11 @@  class_name ControllablePlayer  extends Player -@export var map: Node3D -@export var camera: FollowCamera + +const PLAYER_SPEED: float = 25.;  var facing = Vector2(1, 0) -var velocity = Vector2(0, 0) +var velocity_ = Vector2(0, 0)  func _ready():  	var timer = Timer.new() @@ -19,89 +19,49 @@ func _ready():  func _process(delta):  	var input = Vector2(Input.get_axis("left", "right"), Input.get_axis("forward", "backwards")).normalized() -	input = input.rotated(-camera.angle_target) - -	if input.length() > 0.1: -		facing = lerp_vector2_exp(facing, input, delta * 10.) - -	self.rotation.y = -facing.angle() - -	velocity.x += input.x * delta * SPEED -	velocity.y += input.y * delta * SPEED - -	position = Vector3( -		position.x + (velocity.x * delta), -		0, -		position.z + (velocity.y * delta) -	) +	input = input.rotated(-game.camera.angle_target) +	update(delta, input) +	super(delta) -	# collide -	collide(delta) -	velocity = lerp_vector2_exp(velocity, Vector2(0, 0), delta * 5.) +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(_delta: float): -	for i in map.get_children(): -		if is_instance_of(i, FullTile): -			var tile: FullTile = i -			var d = aabb_circle_distance( -				tile.position.x, -				tile.position.z, -				tile.position.x + 1, -				tile.position.z + 1, -				position.x, -				position.z -			) +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 not is_instance_of(game.map.tile_by_pos.get(str(tile)), FullTile): 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; -			if d > PLAYER_SIZE: -				continue - -			var h = 0.01 -			var d_sample_x = aabb_circle_distance( -				tile.position.x, -				tile.position.z, -				tile.position.x + 1, -				tile.position.z + 1, -				position.x + h, -				position.z -			) -			var d_sample_y = aabb_circle_distance( -				tile.position.x, -				tile.position.z, -				tile.position.x + 1, -				tile.position.z + 1, -				position.x, -				position.z + h -			) -			var grad_x = (d_sample_x - d) / h -			var grad_y = (d_sample_y - d) / h - -			position.x += (PLAYER_SIZE - d) * grad_x -			position.z += (PLAYER_SIZE - d) * grad_y - -			var vdotn = (grad_x * velocity.x) + (grad_y * velocity.y) - -			velocity.x -= grad_x * vdotn -			velocity.y -= grad_y * vdotn -	# TODO: Player collisions - -func lerp_vector2_exp(current: Vector2, target: Vector2, delta: float) -> Vector2: -	return Vector2( -		target.x + (current.x - target.x) * exp( - delta), -		target.y + (current.y - target.y) * exp( - delta) -	) +			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_circle_distance( -	min_x: float, -	min_y: float, -	max_x: float, -	max_y: float, -	px: float, -	py: float -) -> float: -	var dx = px - max(min_x, min(max_x, px)) -	var dy = py - max(min_y, min(max_y, py)) -	return sqrt(dx * dx + dy * dy) +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 diff --git a/client/scripts/game.gd b/client/scripts/game.gd index 9e02e7c0..48457f9c 100644 --- a/client/scripts/game.gd +++ b/client/scripts/game.gd @@ -1,3 +1,4 @@ +class_name Game  extends Node3D  @onready var camera: FollowCamera = $FollowCamera @@ -13,12 +14,10 @@ func _ready():  		func(player: int, name: String, pos: Vector2, character: int):  			var player_instance: Player  			if player == Multiplayer.player_id: -				player_instance = ControllablePlayer.new(player, name, pos, character) -				player_instance.camera = camera -				player_instance.map = map +				player_instance = ControllablePlayer.new(player, name, pos, character, self)  				camera.target = player_instance  			else: -				player_instance = Player.new(player, name, pos, character) +				player_instance = Player.new(player, name, pos, character, self)  			players[player] = player_instance  			add_child(player_instance)  	) diff --git a/client/scripts/map.gd b/client/scripts/map.gd index 9d9453e4..01c7b66e 100644 --- a/client/scripts/map.gd +++ b/client/scripts/map.gd @@ -1,5 +1,8 @@ +class_name Map  extends Node3D +var tile_by_pos: Dictionary = {} +  func _ready():  	Multiplayer.connect("update_map", update) @@ -48,6 +51,7 @@ func update(pos, tile_name, neighbors):  			instance = Floor.new(node_name, neighbors)  	instance.position = Vector3(pos[0], 0, pos[1]) +	tile_by_pos[str(Vector2i(pos[0],pos[1]))] = instance  	add_child(instance)  func queue_free_rename(node: Node) -> void: diff --git a/client/scripts/multiplayer.gd b/client/scripts/multiplayer.gd index f3f16387..6ac05699 100644 --- a/client/scripts/multiplayer.gd +++ b/client/scripts/multiplayer.gd @@ -14,6 +14,8 @@ var socket := WebSocketPeer.new()  var item_names = []  var tile_names = [] +var tile_collide = [] +var tile_interact = []  var item_idx_from_name: Dictionary = {}  var player_id = -1 @@ -53,6 +55,8 @@ func handle_packet(bytes: PackedByteArray):  			player_id = decoded["id"]  			item_names = decoded["data"]["item_names"]  			tile_names = decoded["data"]["tile_names"] +			tile_collide = decoded["data"]["tile_collide"] +			tile_interact = decoded["data"]["tile_interact"]  			for i in range(item_names.size()):  				item_idx_from_name[item_names[i]] = i  			emit_signal("init", player_id) diff --git a/client/scripts/player.gd b/client/scripts/player.gd index 3ad77322..8f53b790 100644 --- a/client/scripts/player.gd +++ b/client/scripts/player.gd @@ -4,13 +4,21 @@ extends Node3D  const PLAYER_SIZE: float = 0.4  const SPEED: float = 25. +var game: Game +var position_ = Vector2(0, 0) +  var mesh = preload("res://scenes/player.tscn").instantiate() -func _init(id: int, new_name: String, pos: Vector2, _character: int): +func _init(id: int, new_name: String, pos: Vector2, _character: int, new_game: Game):  	add_child(mesh) -	position = Vector3(pos.x, 0, pos.y) +	position_ = pos  	name = new_name +	game = new_game  func update_position(new_position: Vector2, new_rotation: float): -	position = Vector3(new_position.x, 0, new_position.y) +	position_ = new_position  	rotation.y = new_rotation + +func _process(delta): +	position.x = position_.x +	position.z = position_.y | 
