Add track minimap to GUI
parent
fbc01a296e
commit
5b05771bb3
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
|
@ -0,0 +1,35 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/player_icon.png-97b071f9d92f0abba7d34c4aae551713.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/player_icon.png"
|
||||
dest_files=[ "res://.import/player_icon.png-97b071f9d92f0abba7d34c4aae551713.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
|
@ -1,5 +1,7 @@
|
|||
extends Node
|
||||
|
||||
signal peers_updated
|
||||
|
||||
const GUI_SCENE = "res://player/gui.tscn"
|
||||
|
||||
var enet_peer = NetworkedMultiplayerENet.new()
|
||||
|
@ -9,31 +11,42 @@ var current_track: Node = null
|
|||
var current_track_path: String
|
||||
var current_vehicle: String
|
||||
|
||||
var colors = [
|
||||
Color.blue, Color.yellow, Color.green, Color.violet, Color.brown, Color.cyan, Color.orange
|
||||
]
|
||||
|
||||
|
||||
class PeerInfo:
|
||||
var id: int
|
||||
var vehicle: String
|
||||
var name: String
|
||||
var spawned: bool
|
||||
var color: Color
|
||||
|
||||
static func new_peer(
|
||||
new_id: int, new_vehicle: String = "", new_name: String = "", new_spawned: bool = false
|
||||
new_id: int,
|
||||
new_vehicle: String = "",
|
||||
new_name: String = "",
|
||||
new_spawned: bool = false,
|
||||
new_color: Color = Color(1, 1, 1)
|
||||
) -> PeerInfo:
|
||||
var new_instance = PeerInfo.new()
|
||||
new_instance.id = new_id
|
||||
new_instance.vehicle = new_vehicle
|
||||
new_instance.name = new_name
|
||||
new_instance.spawned = new_spawned
|
||||
new_instance.color = new_color
|
||||
return new_instance
|
||||
|
||||
func to_array() -> Array:
|
||||
return [id, vehicle, name, spawned]
|
||||
return [id, vehicle, name, spawned, color]
|
||||
|
||||
func from_array(data: Array) -> void:
|
||||
self.id = data[0]
|
||||
self.vehicle = data[1]
|
||||
self.name = data[2]
|
||||
self.spawned = data[3]
|
||||
self.color = data[4]
|
||||
|
||||
|
||||
func _ready():
|
||||
|
@ -57,9 +70,12 @@ func create_server(port, track, vehicle):
|
|||
current_vehicle = vehicle
|
||||
enet_peer.create_server(port, 2)
|
||||
get_tree().network_peer = enet_peer
|
||||
peers[1] = PeerInfo.new_peer(1, vehicle, GlobalSettings.multiplayer_name, true)
|
||||
peers[1] = PeerInfo.new_peer(
|
||||
1, vehicle, GlobalSettings.multiplayer_name, true, get_next_color(1)
|
||||
)
|
||||
create_player(1, vehicle)
|
||||
get_tree().root.call_deferred("add_child", current_track)
|
||||
emit_signal("peers_updated")
|
||||
|
||||
|
||||
func create_client(address, port, vehicle):
|
||||
|
@ -67,18 +83,24 @@ func create_client(address, port, vehicle):
|
|||
enet_peer.create_client(address, port)
|
||||
get_tree().network_peer = enet_peer
|
||||
peers[get_tree().get_network_unique_id()] = PeerInfo.new_peer(
|
||||
get_tree().get_network_unique_id(), vehicle, GlobalSettings.multiplayer_name, true
|
||||
get_tree().get_network_unique_id(),
|
||||
vehicle,
|
||||
GlobalSettings.multiplayer_name,
|
||||
true,
|
||||
get_next_color(1)
|
||||
)
|
||||
emit_signal("peers_updated")
|
||||
|
||||
|
||||
func _peer_connected(peer_id):
|
||||
peers[peer_id] = PeerInfo.new_peer(peer_id, "", "", false)
|
||||
peers[peer_id] = PeerInfo.new_peer(peer_id, "", "", false, get_next_color(peer_id))
|
||||
rpc_id(
|
||||
peer_id,
|
||||
"add_player",
|
||||
get_tree().get_network_unique_id(),
|
||||
peers[get_tree().get_network_unique_id()].to_array()
|
||||
)
|
||||
emit_signal("peers_updated")
|
||||
if get_tree().get_network_unique_id() == 1:
|
||||
rpc_id(peer_id, "select_track", current_track_path)
|
||||
|
||||
|
@ -135,12 +157,12 @@ func quit():
|
|||
|
||||
remote func add_player(peer_id, peer_info: Array):
|
||||
if peers[peer_id] == null:
|
||||
peers[peer_id] = PeerInfo.new_peer(peer_id, "", "", false)
|
||||
peers[peer_id] = PeerInfo.new_peer(peer_id, "", "", false, get_next_color(peer_id))
|
||||
|
||||
if peers[peer_id].spawned == false:
|
||||
peers[peer_id].from_array(peer_info)
|
||||
|
||||
# Check for duplicate names on server side
|
||||
# Check for duplicate names on server side and update colors
|
||||
if get_tree().get_network_unique_id() == 1:
|
||||
var names = []
|
||||
for peer in peers:
|
||||
|
@ -151,11 +173,15 @@ remote func add_player(peer_id, peer_info: Array):
|
|||
peers[peer_id].name = peers[peer_id].name + ("(%s)" % peer_id)
|
||||
rpc("update_name", peer_id, peers[peer_id].name)
|
||||
|
||||
peers[peer_id].color = get_next_color(peer_id)
|
||||
rpc("update_color", peer_id, peers[peer_id].color)
|
||||
|
||||
if current_track != null:
|
||||
peers[peer_id].spawned = true
|
||||
create_player(peer_id, peers[peer_id].vehicle)
|
||||
else:
|
||||
peers[peer_id].spawned = false
|
||||
emit_signal("peers_updated")
|
||||
|
||||
|
||||
remote func select_track(track_path):
|
||||
|
@ -166,7 +192,21 @@ remote func select_track(track_path):
|
|||
if peers[peer].spawned == false:
|
||||
peers[peer].spawned = true
|
||||
create_player(peer, peers[peer].vehicle)
|
||||
emit_signal("peers_updated")
|
||||
|
||||
|
||||
remote func update_name(peer_id, name: String):
|
||||
peers[peer_id].name = name
|
||||
emit_signal("peers_updated")
|
||||
|
||||
|
||||
remote func update_color(peer_id, color: Color):
|
||||
peers[peer_id].color = color
|
||||
emit_signal("peers_updated")
|
||||
|
||||
|
||||
func get_next_color(peer_id: int) -> Color:
|
||||
if peers.size() >= colors.size():
|
||||
return Color(peer_id)
|
||||
else:
|
||||
return colors[peers.size()]
|
||||
|
|
|
@ -27,6 +27,7 @@ func spawn_player(player_node: BuggedVehicle, gui: Node) -> void:
|
|||
|
||||
|
||||
func spawn_vehicle(vehicle: BuggedVehicle) -> void:
|
||||
vehicle.connect("position_updated", track, "_on_player_position_updated")
|
||||
reset_player_to(track.get_furthest_checkpoint(), vehicle)
|
||||
add_child(vehicle)
|
||||
|
||||
|
@ -47,6 +48,7 @@ func reset_player_to(node_to_reset_to: Node, player_node: BuggedVehicle) -> void
|
|||
|
||||
func _spawn_in_player():
|
||||
reset_player_to(track.get_furthest_checkpoint(), player_node)
|
||||
player_node.connect("position_updated", track, "_on_player_position_updated")
|
||||
add_child(player_node)
|
||||
add_child(gui)
|
||||
player_controller = PLAYER_CONTROLLER.new()
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
extends Node2D
|
||||
|
||||
export(Curve2D) var curve
|
||||
export(Color) var color = Color.red
|
||||
export(float) var width = 2.0
|
||||
|
||||
|
||||
func _draw() -> void:
|
||||
if curve == null:
|
||||
return
|
||||
|
||||
draw_polyline(curve.get_baked_points(), color, width)
|
|
@ -0,0 +1,6 @@
|
|||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://scenes/components/curved_line_2d.gd" type="Script" id=1]
|
||||
|
||||
[node name="CurvedLine2d" type="Node2D"]
|
||||
script = ExtResource( 1 )
|
|
@ -0,0 +1,90 @@
|
|||
extends Node2D
|
||||
|
||||
export(Vector2) var size = Vector2(200, 200)
|
||||
export(Texture) var player_icon
|
||||
|
||||
onready var scaling_helper = $ScalingHelper
|
||||
onready var track_path = $ScalingHelper/TrackPath
|
||||
onready var track_line = $ScalingHelper/TrackLine
|
||||
onready var start_line = $ScalingHelper/TrackPath/StartLine
|
||||
onready var players_container = $ScalingHelper/Players
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
scaling_helper.position.x = size.x / 2
|
||||
scaling_helper.position.y = size.y / 2
|
||||
MultiplayerController.connect("peers_updated", self, "_on_peers_updated")
|
||||
|
||||
|
||||
func set_curve(curve: Curve3D) -> void:
|
||||
var curve2d = Curve2D.new()
|
||||
var point_count = curve.get_point_count()
|
||||
for point in range(point_count):
|
||||
var point3d = curve.get_point_position(point)
|
||||
var point_in = curve.get_point_in(point)
|
||||
var point_out = curve.get_point_out(point)
|
||||
curve2d.add_point(
|
||||
Vector2(point3d.x, point3d.z),
|
||||
Vector2(point_in.x, point_in.z),
|
||||
Vector2(point_out.x, point_out.z)
|
||||
)
|
||||
|
||||
var max_x = curve2d.get_baked_points()[0].x
|
||||
var max_y = curve2d.get_baked_points()[0].y
|
||||
var min_x = curve2d.get_baked_points()[0].x
|
||||
var min_y = curve2d.get_baked_points()[0].y
|
||||
for point in curve2d.get_baked_points():
|
||||
if point.x > max_x:
|
||||
max_x = point.x
|
||||
if point.x < min_x:
|
||||
min_x = point.x
|
||||
if point.y > max_y:
|
||||
max_y = point.y
|
||||
if point.y < min_y:
|
||||
min_y = point.y
|
||||
|
||||
var center_x = (max_x + min_x) / 2
|
||||
var center_y = (max_y + min_y) / 2
|
||||
var width = max_x - min_x
|
||||
var height = max_y - min_y
|
||||
var max_dim = max(width, height)
|
||||
var scale_factor = size.x / (max_dim + track_line.width)
|
||||
var new_center_x = scaling_helper.position.x - (center_x * scale_factor)
|
||||
var new_center_y = scaling_helper.position.y - (center_y * scale_factor)
|
||||
scaling_helper.scale.x = scale_factor
|
||||
scaling_helper.scale.y = scale_factor
|
||||
scaling_helper.position.x = new_center_x
|
||||
scaling_helper.position.y = new_center_y
|
||||
track_path.curve = curve2d
|
||||
track_line.curve = curve2d
|
||||
start_line.offset = 0.01
|
||||
|
||||
|
||||
func on_player_position_updated(player_id: int, position: Transform) -> void:
|
||||
var existing_node: Sprite = players_container.get_node_or_null(String(player_id))
|
||||
if existing_node == null:
|
||||
var player_color
|
||||
if MultiplayerController.is_online():
|
||||
player_color = MultiplayerController.peers[player_id].color
|
||||
else:
|
||||
player_color = Color(1, 1, 1)
|
||||
existing_node = Sprite.new()
|
||||
existing_node.name = String(player_id)
|
||||
existing_node.texture = player_icon
|
||||
existing_node.modulate = player_color
|
||||
players_container.add_child(existing_node)
|
||||
existing_node.position.x = position.origin.x
|
||||
existing_node.position.y = position.origin.z
|
||||
existing_node.rotation = position.basis.x.signed_angle_to(Vector3.LEFT, Vector3.UP)
|
||||
|
||||
|
||||
func _on_peers_updated() -> void:
|
||||
for peer in MultiplayerController.peers:
|
||||
var existing_node: Sprite = players_container.get_node_or_null(String(peer))
|
||||
if existing_node != null:
|
||||
var player_color = MultiplayerController.peers[peer].color
|
||||
existing_node.modulate = player_color
|
||||
|
||||
for child in players_container.get_children():
|
||||
if not MultiplayerController.peers.has(int(float(child.name))):
|
||||
child.queue_free()
|
|
@ -0,0 +1,37 @@
|
|||
[gd_scene load_steps=6 format=2]
|
||||
|
||||
[ext_resource path="res://assets/player_icon.png" type="Texture" id=1]
|
||||
[ext_resource path="res://scenes/track_minimap.gd" type="Script" id=2]
|
||||
[ext_resource path="res://scenes/components/curved_line_2d.tscn" type="PackedScene" id=3]
|
||||
|
||||
[sub_resource type="Gradient" id=1]
|
||||
offsets = PoolRealArray( 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 )
|
||||
colors = PoolColorArray( 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1 )
|
||||
|
||||
[sub_resource type="GradientTexture" id=2]
|
||||
gradient = SubResource( 1 )
|
||||
width = 50
|
||||
|
||||
[node name="TrackMinimap" type="Node2D"]
|
||||
script = ExtResource( 2 )
|
||||
player_icon = ExtResource( 1 )
|
||||
|
||||
[node name="ScalingHelper" type="Node2D" parent="."]
|
||||
|
||||
[node name="TrackPath" type="Path2D" parent="ScalingHelper"]
|
||||
curve = null
|
||||
|
||||
[node name="StartLine" type="PathFollow2D" parent="ScalingHelper/TrackPath"]
|
||||
position = Vector2( -99.1171, -154.856 )
|
||||
rotation = -0.742965
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="ScalingHelper/TrackPath/StartLine"]
|
||||
rotation = 1.5708
|
||||
scale = Vector2( 1, 5 )
|
||||
texture = SubResource( 2 )
|
||||
|
||||
[node name="TrackLine" parent="ScalingHelper" instance=ExtResource( 3 )]
|
||||
color = Color( 0.482353, 0, 0, 1 )
|
||||
width = 10.0
|
||||
|
||||
[node name="Players" type="Node2D" parent="ScalingHelper"]
|
|
@ -8,6 +8,7 @@ onready var best_time_value = $VBoxContainer/HBoxContainer/BestTimeValue
|
|||
onready var wrong_way_label = $CenterContainer/WrongWayLabel
|
||||
onready var leaderboards = $VBoxContainer/LeaderboardsLine
|
||||
onready var leaderboards_list = $VBoxContainer/LeaderboardsLine/VBoxContainer/Leaderboards
|
||||
onready var track_minimap = $VBoxContainer2/HBoxContainer/ViewportContainer/TrackRadar/TrackMinimap
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
|
@ -15,6 +16,7 @@ func _ready() -> void:
|
|||
best_time_value.text = "NaN"
|
||||
if MultiplayerController.is_online():
|
||||
leaderboards.visible = true
|
||||
MultiplayerController.connect("peers_updated", self, "_on_peers_updated")
|
||||
else:
|
||||
leaderboards.visible = false
|
||||
|
||||
|
@ -47,7 +49,10 @@ func _format_time(time: float) -> String:
|
|||
|
||||
remote func update_leaderboard_time(peer_id: String, lap_time: float):
|
||||
leaderboards_data[peer_id] = lap_time
|
||||
_refresh_leaderboard()
|
||||
|
||||
|
||||
func _refresh_leaderboard():
|
||||
var leaderboards_sorted = []
|
||||
for peer in leaderboards_data:
|
||||
leaderboards_sorted.append([peer, leaderboards_data[peer]])
|
||||
|
@ -67,3 +72,19 @@ remote func update_leaderboard_time(peer_id: String, lap_time: float):
|
|||
|
||||
func _leaderbords_comparison(left: Array, right: Array) -> bool:
|
||||
return left[1] < right[1]
|
||||
|
||||
|
||||
func set_curve(curve: Curve3D) -> void:
|
||||
track_minimap.set_curve(curve)
|
||||
|
||||
|
||||
func on_player_position_updated(player_id: int, position: Transform) -> void:
|
||||
track_minimap.on_player_position_updated(player_id, position)
|
||||
|
||||
|
||||
func _on_peers_updated() -> void:
|
||||
for peer in leaderboards_data.keys():
|
||||
if not MultiplayerController.peers.has(peer):
|
||||
leaderboards_data.erase(peer)
|
||||
|
||||
_refresh_leaderboard()
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
[gd_scene load_steps=5 format=2]
|
||||
[gd_scene load_steps=6 format=2]
|
||||
|
||||
[ext_resource path="res://assets/fonts/kenney-future-narrow.ttf" type="DynamicFontData" id=1]
|
||||
[ext_resource path="res://scenes/trackgui.gd" type="Script" id=2]
|
||||
[ext_resource path="res://scenes/track_minimap.tscn" type="PackedScene" id=3]
|
||||
|
||||
[sub_resource type="DynamicFont" id=1]
|
||||
size = 36
|
||||
|
@ -125,3 +126,30 @@ align = 1
|
|||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="VBoxContainer2" type="VBoxContainer" parent="."]
|
||||
margin_right = 984.0
|
||||
margin_bottom = 560.0
|
||||
alignment = 2
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer2"]
|
||||
margin_top = 360.0
|
||||
margin_right = 984.0
|
||||
margin_bottom = 560.0
|
||||
alignment = 2
|
||||
|
||||
[node name="ViewportContainer" type="ViewportContainer" parent="VBoxContainer2/HBoxContainer"]
|
||||
margin_left = 784.0
|
||||
margin_right = 984.0
|
||||
margin_bottom = 200.0
|
||||
|
||||
[node name="TrackRadar" type="Viewport" parent="VBoxContainer2/HBoxContainer/ViewportContainer"]
|
||||
size = Vector2( 200, 200 )
|
||||
transparent_bg = true
|
||||
handle_input_locally = false
|
||||
disable_3d = true
|
||||
usage = 0
|
||||
render_target_update_mode = 3
|
||||
gui_disable_input = true
|
||||
|
||||
[node name="TrackMinimap" parent="VBoxContainer2/HBoxContainer/ViewportContainer/TrackRadar" instance=ExtResource( 3 )]
|
||||
|
|
|
@ -24,6 +24,7 @@ var current_time = 0
|
|||
var lap_done = false
|
||||
|
||||
onready var checkpoints = $Checkpoints
|
||||
onready var track_gui = $TrackGUI
|
||||
onready var path: Path = get_node(track_path)
|
||||
|
||||
|
||||
|
@ -51,6 +52,7 @@ func _ready() -> void:
|
|||
gate.scale = gate_size
|
||||
checkpoints.get_child(0).add_child(gate)
|
||||
checkpoints.global_transform.origin = path.global_transform.origin
|
||||
track_gui.set_curve(path.curve)
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
|
@ -96,3 +98,7 @@ func _build_checkpoint_collision():
|
|||
func _update_time():
|
||||
current_time = OS.get_ticks_msec() - start_time
|
||||
emit_signal("time_updated", current_time)
|
||||
|
||||
|
||||
func _on_player_position_updated(player_id: int, position: Transform) -> void:
|
||||
track_gui.on_player_position_updated(player_id, position)
|
||||
|
|
|
@ -8,6 +8,7 @@ signal brake_updated(brake_percent)
|
|||
signal clutch_updated(clutch_percent)
|
||||
signal gear_updated(gear)
|
||||
signal steering_updated(steering_angle, steering_percent)
|
||||
signal position_updated(player_id, position)
|
||||
|
||||
enum GearRequest { NONE, UP, DOWN }
|
||||
|
||||
|
@ -256,6 +257,8 @@ func _physics_process(delta: float):
|
|||
steering = steering_input * lerp(max_steer_angle_rad, speed_steer_angle_rad, steer_speed_factor)
|
||||
emit_signal("steering_updated", steering, steering / max_steer_angle_rad)
|
||||
|
||||
emit_signal("position_updated", get_network_master(), global_transform)
|
||||
|
||||
if MultiplayerController.is_online():
|
||||
if get_network_master() == get_tree().get_network_unique_id():
|
||||
_synchronize()
|
||||
|
@ -288,6 +291,7 @@ func _synchronize():
|
|||
|
||||
remote func sync_position(position: Transform):
|
||||
reset_transform = position
|
||||
emit_signal("position_updated", get_network_master(), global_transform)
|
||||
|
||||
|
||||
remote func sync_inputs(remote_inputs):
|
||||
|
|
Loading…
Reference in New Issue