From 1e40fc8c50818651838af749ccc72b42cb25cc61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Wed, 17 Nov 2021 20:10:51 +0100 Subject: [PATCH] Add basic track timing logic --- project.godot | 8 ++- scenes/test_level.tscn | 105 +++++++++++++++++++++++++++++++++++++-- scenes/track.gd | 72 +++++++++++++++++++++++++++ scenes/trackgui.gd | 28 +++++++++++ vehicles/beetlecar.tscn | 2 +- vehicles/buggy.tscn | 2 +- vehicles/buggy_test.tscn | 24 --------- vehicles/bugmobile.tscn | 2 +- 8 files changed, 211 insertions(+), 32 deletions(-) create mode 100644 scenes/track.gd create mode 100644 scenes/trackgui.gd delete mode 100644 vehicles/buggy_test.tscn diff --git a/project.godot b/project.godot index 4932751..cd170da 100644 --- a/project.godot +++ b/project.godot @@ -13,9 +13,15 @@ _global_script_classes=[ { "class": "TireSmoke", "language": "GDScript", "path": "res://vehicles/tire_smoke.gd" +}, { +"base": "Spatial", +"class": "Track", +"language": "GDScript", +"path": "res://scenes/track.gd" } ] _global_script_class_icons={ -"TireSmoke": "" +"TireSmoke": "", +"Track": "" } [application] diff --git a/scenes/test_level.tscn b/scenes/test_level.tscn index 01e1faa..83c79a1 100644 --- a/scenes/test_level.tscn +++ b/scenes/test_level.tscn @@ -1,8 +1,11 @@ -[gd_scene load_steps=11 format=2] +[gd_scene load_steps=16 format=2] [ext_resource path="res://scenes/test_level.gd" type="Script" id=1] [ext_resource path="res://scenes/menu/pause_menu.tscn" type="PackedScene" id=2] [ext_resource path="res://icon.png" type="Texture" id=3] +[ext_resource path="res://scenes/track.gd" type="Script" id=4] +[ext_resource path="res://assets/fonts/kenney-future-narrow.ttf" type="DynamicFontData" id=5] +[ext_resource path="res://scenes/trackgui.gd" type="Script" id=6] [sub_resource type="PlaneMesh" id=1] @@ -12,6 +15,10 @@ albedo_texture = ExtResource( 3 ) [sub_resource type="ConcavePolygonShape" id=3] data = PoolVector3Array( 1, 0, 1, -1, 0, 1, 1, 0, -1, -1, 0, 1, -1, 0, -1, 1, 0, -1 ) +[sub_resource type="SpatialMaterial" id=9] +flags_transparent = true +albedo_color = Color( 0.0470588, 0.956863, 0.921569, 0.439216 ) + [sub_resource type="Curve3D" id=4] _data = { "points": PoolVector3Array( 9.79904, 0, 18.6319, -9.79904, 0, -18.6319, -31.895, 0, 7.96057, 0, 0, 0, 0, 0, 0, -57.093, 0, -13.8155, -7.43263, 0, 17.8593, 7.43263, 0, -17.8593, -58.3374, 0, -41.6578, -15.1113, 0, 9.06681, 15.1113, 0, -9.06681, -37.8981, 0, -68.1249, -14.7755, 0, 2.35069, 14.7755, 0, -2.35069, 4.94635, 7.23662, -84.5424, -17.7978, 0, -2.68641, 17.7978, 0, 2.68641, 61.5006, 0, -91.6313, 0.67157, 0, -25.5212, -0.67157, 0, 25.5212, 97.0961, 0, -69.1323, 2.68643, 0, -7.38771, -2.68643, 0, 7.38771, 78.6267, 0, -42.2678, -8.73099, 0, -17.4619, 8.73099, 0, 17.4619, 66.0252, 8.78723, -14.4988, 0, 0, 0, 0, 0, 0, 95.7529, 0, -1.6352, 0, 0, 0, 0, 0, 0, 139.408, 0, 1.05125, -20.1485, 0, -13.7681, 20.1485, 0, 13.7681, 185.413, 0, 3.4019, 0, 0, 0, 0, 0, 0, 201.868, 0, 23.2145, 0.335724, 0, -17.462, -0.335724, 0, 17.462, 210.21, 5.87604, 64.836, 3.97235, -0.0415859, -7.46809, -3.97235, 0.0415859, 7.46809, 201.532, 0, 95.7487, 0, 0, 0, 0, 0, 0, 183.063, 0, 103.472, 14.7754, 0, 11.0815, -14.7754, 0, -11.0815, 157.877, 0, 103.472, -7.25508, 0, 9.91405, 7.25508, 0, -9.91405, 162.578, 0, 79.2942, 8.24519, 0, 4.16077, -8.24519, 0, -4.16077, 159.22, 0, 35.3035, 0, 0, 0, 0, 0, 0, 109.521, 0, 55.4519, 13.9191, 0, -4.46759, -13.9191, 0, 4.46759, 61.5006, 0, 84.6671, 0, 0, 0, 0, 0, 0, 19.5493, 3.78882, 91.2156, 12.2019, 0, 6.94766, -12.2019, 0, -6.94766, -14.7275, 0, 82.6522, 6.66099, 0.313545, 7.53158, -6.66099, -0.313545, -7.53158, -22.7176, 8.46592, 50.9225, 2.76307, 0.531036, 4.97682, -2.76307, -0.531036, -4.97682, -31.895, 0, 7.96057 ), @@ -35,13 +42,19 @@ noise_offset = Vector2( -1, -1 ) albedo_color = Color( 0.4, 0.301961, 0.00784314, 1 ) albedo_texture = SubResource( 6 ) +[sub_resource type="DynamicFont" id=8] +size = 36 +outline_size = 2 +outline_color = Color( 1, 1, 1, 0.317647 ) +font_data = ExtResource( 5 ) + [node name="Spatial" type="Spatial"] script = ExtResource( 1 ) [node name="PauseMenu" parent="." instance=ExtResource( 2 )] -[node name="PlayerSpawnLocation" type="Spatial" parent="."] -transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -53.0538, 4.97082, -42.7552 ) +[node name="PlayerSpawnLocation" type="Position3D" parent="."] +transform = Transform( -0.577573, 0, -0.816339, 0, 1, 0, 0.816339, 0, -0.577573, -28.4356, 7.65286, 30.9025 ) [node name="StaticBody" type="StaticBody" parent="."] transform = Transform( 99.9785, 0, 0, 0, 99.9785, 0, 0, 0, 99.9785, 0, 0, 0 ) @@ -56,12 +69,16 @@ transform = Transform( 6.13726, 0, 0, 0, 6.13726, 0, 0, 0, 6.13726, 0, 0, 0 ) shape = SubResource( 3 ) [node name="Track" type="Spatial" parent="."] +script = ExtResource( 4 ) +track_path = NodePath("Path") +debug = true +debug_material = SubResource( 9 ) [node name="Path" type="Path" parent="Track"] curve = SubResource( 4 ) [node name="Road" type="CSGPolygon" parent="Track/Path"] -transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.194962, 0.721504, -0.0180283 ) +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.381588, 0.85226, -0.386032 ) use_collision = true invert_faces = true polygon = PoolVector2Array( -8, 0, 2, 0.1, 8, 0.1, 2, 0 ) @@ -91,3 +108,83 @@ path_local = true path_continuous_u = true path_u_distance = 1.0 path_joined = true + +[node name="Checkpoints" type="Spatial" parent="Track"] + +[node name="TrackGUI" type="MarginContainer" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 +margin_left = 20.0 +margin_top = 20.0 +margin_right = -20.0 +margin_bottom = -20.0 +script = ExtResource( 6 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="HBoxContainer" type="HBoxContainer" parent="TrackGUI"] +margin_right = 984.0 +margin_bottom = 560.0 + +[node name="TimeLabel" type="Label" parent="TrackGUI/HBoxContainer"] +margin_right = 289.0 +margin_bottom = 41.0 +size_flags_horizontal = 3 +size_flags_vertical = 0 +custom_colors/font_color = Color( 0.482353, 0, 0, 1 ) +custom_fonts/font = SubResource( 8 ) +text = "Current lap -" +align = 1 +valign = 1 + +[node name="TimeValue" type="Label" parent="TrackGUI/HBoxContainer"] +margin_left = 297.0 +margin_right = 489.0 +margin_bottom = 41.0 +size_flags_horizontal = 3 +size_flags_vertical = 0 +custom_colors/font_color = Color( 0.482353, 0, 0, 1 ) +custom_fonts/font = SubResource( 8 ) +text = "12:23.245" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Divider" type="Label" parent="TrackGUI/HBoxContainer"] +margin_left = 497.0 +margin_right = 562.0 +margin_bottom = 41.0 +size_flags_horizontal = 3 +size_flags_vertical = 0 +custom_colors/font_color = Color( 0.482353, 0, 0, 1 ) +custom_fonts/font = SubResource( 8 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="BestTimeLabel" type="Label" parent="TrackGUI/HBoxContainer"] +margin_left = 570.0 +margin_right = 784.0 +margin_bottom = 41.0 +size_flags_horizontal = 3 +size_flags_vertical = 0 +custom_colors/font_color = Color( 0.482353, 0, 0, 1 ) +custom_fonts/font = SubResource( 8 ) +text = "Best Lap -" + +[node name="BestTimeValue" type="Label" parent="TrackGUI/HBoxContainer"] +margin_left = 792.0 +margin_right = 984.0 +margin_bottom = 41.0 +size_flags_horizontal = 3 +size_flags_vertical = 0 +custom_colors/font_color = Color( 0.482353, 0, 0, 1 ) +custom_fonts/font = SubResource( 8 ) +text = "01:23.256" +__meta__ = { +"_edit_use_anchors_": false +} + +[connection signal="lap_complete" from="Track" to="TrackGUI" method="_on_lap_complete"] +[connection signal="time_updated" from="Track" to="TrackGUI" method="_on_time_updated"] diff --git a/scenes/track.gd b/scenes/track.gd new file mode 100644 index 0000000..0f51ffe --- /dev/null +++ b/scenes/track.gd @@ -0,0 +1,72 @@ +class_name Track +extends Spatial + +signal time_updated(new_time) +signal lap_complete(lap_time) + +export (NodePath) var track_path = null +export (int, 10, 50) var checkpoint_count = 20 +export (Vector2) var checkpoint_dim = Vector2(20, 15) +export (bool) var debug = false +export (Material) var debug_material = null + +onready var checkpoints = $Checkpoints +onready var path: Path = get_node(track_path) +var last_checkpoint = -1 + +var start_time = 0 +var current_time = 0 + +func _ready() -> void: + start_time = OS.get_ticks_msec() + var length = path.curve.get_baked_length() + var section_size = 1.0 * length / checkpoint_count + var section = 0.0 + for _checkpoint_number in range(checkpoint_count): + var new_checkpoint: Area = Area.new() + new_checkpoint.add_child(_build_checkpoint_collision()) + new_checkpoint.transform.origin = path.curve.interpolate_baked(section, true) + section += section_size + checkpoints.add_child(new_checkpoint) + if debug: + var mesh = CylinderMesh.new() + mesh.top_radius = checkpoint_dim.y + mesh.bottom_radius = checkpoint_dim.y + mesh.height = checkpoint_dim.x + if debug_material != null: + mesh.material = debug_material + var meshinst = MeshInstance.new() + meshinst.mesh = mesh + new_checkpoint.add_child(meshinst) + new_checkpoint.connect("body_entered", self, "_on_body_entered_area", [ new_checkpoint ]) + checkpoints.global_transform.origin = path.global_transform.origin + + +func _process(delta: float) -> void: + _update_time() + + +func _on_body_entered_area(body: Node, area: Area) -> void: + if body.get_groups().has("car"): + # We got the correct checkpoint + if last_checkpoint == area.get_index() - 1: + last_checkpoint += 1 + + if last_checkpoint == checkpoints.get_child_count() - 1: + emit_signal("lap_complete", current_time) + start_time = OS.get_ticks_msec() + _update_time() + last_checkpoint = -1 + + +func _build_checkpoint_collision(): + var collision = CollisionShape.new() + var shape = CylinderShape.new() + shape.radius = checkpoint_dim.x + shape.height = checkpoint_dim.y + collision.shape = shape + return collision + +func _update_time(): + current_time = OS.get_ticks_msec() - start_time + emit_signal("time_updated", current_time) diff --git a/scenes/trackgui.gd b/scenes/trackgui.gd new file mode 100644 index 0000000..0f16509 --- /dev/null +++ b/scenes/trackgui.gd @@ -0,0 +1,28 @@ +extends MarginContainer + +var best_time = -1 + +onready var time_value = $HBoxContainer/TimeValue +onready var best_time_value = $HBoxContainer/BestTimeValue + +func _ready() -> void: + time_value.text = "NaN" + best_time_value.text = "NaN" + + +func _on_time_updated(new_time: float) -> void: + time_value.text = _format_time(new_time) + + +func _on_lap_complete(lap_time: float) -> void: + print(lap_time) + if lap_time < best_time or best_time < 0: + best_time = lap_time + best_time_value.text = _format_time(best_time) + + +func _format_time(time: float) -> String: + var minute = floor(time / 1000.0 / 60.0) + var second = floor((time / 1000.0) - minute * 60) + var millisecond = time - minute * 60 - second * 1000 + return "%02d:%02d.%03d" % [minute, second, millisecond] diff --git a/vehicles/beetlecar.tscn b/vehicles/beetlecar.tscn index 62bbd08..3bb3555 100644 --- a/vehicles/beetlecar.tscn +++ b/vehicles/beetlecar.tscn @@ -41,7 +41,7 @@ material = SubResource( 6 ) radial_segments = 4 rings = 3 -[node name="beetlecar" instance=ExtResource( 2 )] +[node name="beetlecar" groups=["car"] instance=ExtResource( 2 )] mass = 140.0 script = ExtResource( 1 ) EXPECTED_MAX_SPEED = 180.0 diff --git a/vehicles/buggy.tscn b/vehicles/buggy.tscn index 1e77863..dfda815 100644 --- a/vehicles/buggy.tscn +++ b/vehicles/buggy.tscn @@ -40,7 +40,7 @@ material = SubResource( 10 ) radial_segments = 4 rings = 3 -[node name="buggy" instance=ExtResource( 1 )] +[node name="buggy" groups=["car"] instance=ExtResource( 1 )] mass = 150.0 script = ExtResource( 3 ) BASE_ENGINE_PITCH = 0.95 diff --git a/vehicles/buggy_test.tscn b/vehicles/buggy_test.tscn deleted file mode 100644 index a6f4ac9..0000000 --- a/vehicles/buggy_test.tscn +++ /dev/null @@ -1,24 +0,0 @@ -[gd_scene load_steps=4 format=2] - -[ext_resource path="res://vehicles/buggy.tscn" type="PackedScene" id=1] - -[sub_resource type="CubeMesh" id=1] - -[sub_resource type="ConcavePolygonShape" id=2] -data = PoolVector3Array( -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1 ) - -[node name="buggy" instance=ExtResource( 1 )] - -[node name="Camera" type="Camera" parent="." index="7"] -transform = Transform( -0.0903024, 0, -0.995914, 0, 1, 0, 0.995914, 0, -0.0903024, -3.4904, 1.22508, 0 ) - -[node name="StaticBody" type="StaticBody" parent="." index="8"] - -[node name="MeshInstance" type="MeshInstance" parent="StaticBody" index="0"] -transform = Transform( 6.60148, 0, 0, 0, 0.0658818, 0, 0, 0, 6.60148, 0, -0.212286, 0 ) -mesh = SubResource( 1 ) -material/0 = null - -[node name="CollisionShape" type="CollisionShape" parent="StaticBody" index="1"] -transform = Transform( 6.60148, 0, 0, 0, 0.0658818, 0, 0, 0, 6.60148, 0, -0.212286, 0 ) -shape = SubResource( 2 ) diff --git a/vehicles/bugmobile.tscn b/vehicles/bugmobile.tscn index f8de5a4..2971fac 100644 --- a/vehicles/bugmobile.tscn +++ b/vehicles/bugmobile.tscn @@ -48,7 +48,7 @@ material = SubResource( 10 ) radial_segments = 4 rings = 3 -[node name="bugmobile" instance=ExtResource( 2 )] +[node name="bugmobile" groups=["car"] instance=ExtResource( 2 )] mass = 600.0 script = ExtResource( 3 ) MAX_ENGINE_FORCE = 400.0