small racing game im working on
splits
| -rw-r--r-- | classes/checkpoint.gd | 2 | ||||
| -rw-r--r-- | race.gd | 14 | ||||
| -rw-r--r-- | race.tscn | 52 | ||||
| -rw-r--r-- | scenes/ring_finish.tscn | 11 | ||||
| -rw-r--r-- | scenes/track-base.gd | 11 | ||||
| -rw-r--r-- | ui/intro_cam.gd | 2 | ||||
| -rw-r--r-- | ui/splits/difference.gd | 27 | ||||
| -rw-r--r-- | ui/splits/gains.tres | 6 | ||||
| -rw-r--r-- | ui/splits/loss.tres | 6 | ||||
| -rw-r--r-- | ui/splits/neutral.tres | 6 | ||||
| -rw-r--r-- | ui/splits/splits.gd | 13 | ||||
| -rw-r--r-- | ui/splits/splits.tres | 10 | ||||
| -rw-r--r-- | ui/splits/splits.tscn | 49 | ||||
| -rw-r--r-- | ui/timer.gd | 5 |
14 files changed, 172 insertions, 42 deletions
diff --git a/classes/checkpoint.gd b/classes/checkpoint.gd index c0d7fc4..9b7d3e4 100644 --- a/classes/checkpoint.gd +++ b/classes/checkpoint.gd @@ -3,8 +3,6 @@ class_name CheckPoint signal collected -var id: int # checkpoint id - @export var needs_collision := true func enter() -> void: @@ -2,6 +2,8 @@ extends Node3D @export var car: PackedScene @export var track: TrackLoader +@export var splits: Control +@export var timer: Control signal created_car(car: Car) @@ -18,11 +20,17 @@ func _ready() -> void: c.global_position = c.global_position - (c.ball.global_transform.basis.z * 2) # bump forward a teensy bit c.visible = true created_car.emit(c) - for cp in track.checkpoints: - cp.collected.connect(collect.bind(cp.id)) + for i in len(track.checkpoints): + track.checkpoints[i].collected.connect(collect.bind(i)) + + track.finish.collected.connect( + func passed_finish() -> void: + if track.checkpoints.size() == len(collected_checkpoints): + collect(-1) + ) func collect(cp: int) -> void: - print("collected cp %d" % cp) + splits.update(timer.elapsed_time, 10) collected_checkpoints.append(cp) var collected_checkpoints: PackedInt32Array = [] @@ -1,4 +1,4 @@ -[gd_scene load_steps=20 format=3 uid="uid://dmkcxlevx4c7g"] +[gd_scene load_steps=21 format=3 uid="uid://dmkcxlevx4c7g"] [ext_resource type="Script" path="res://race.gd" id="1_ckbwd"] [ext_resource type="Environment" uid="uid://biwshm46yl62v" path="res://default_env.tres" id="2_pnp7e"] @@ -13,6 +13,7 @@ [ext_resource type="PackedScene" uid="uid://clw61td2wh84w" path="res://scenes/track.tscn" id="11_6q53c"] [ext_resource type="Curve3D" uid="uid://cuonflkcdybj0" path="res://tracks/test_curve.tres" id="12_8yl7p"] [ext_resource type="Resource" uid="uid://de46bcu1ivmtq" path="res://tracks/test.tres" id="13_sh6e8"] +[ext_resource type="PackedScene" uid="uid://nkh2xi7tnumc" path="res://ui/splits/splits.tscn" id="14_ge1w6"] [ext_resource type="Script" path="res://ui/intro_cam.gd" id="14_yajvg"] [sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_tkhh8"] @@ -21,9 +22,25 @@ material = ExtResource("4_i1mlf") size = Vector2(5000, 5000) +[sub_resource type="Animation" id="Animation_2si4r"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Counter:text") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [" +"] +} + [sub_resource type="Animation" id="Animation_uaks0"] resource_name = "count_in" -length = 1.5 +length = 3.0 step = 0.5 tracks/0/type = "value" tracks/0/imported = false @@ -32,7 +49,7 @@ tracks/0/path = NodePath("Counter:text") tracks/0/interp = 1 tracks/0/loop_wrap = true tracks/0/keys = { -"times": PackedFloat32Array(0, 0.5, 1, 1.5), +"times": PackedFloat32Array(0, 1, 2, 3), "transitions": PackedFloat32Array(1, 1, 1, 1), "update": 1, "values": ["[center][b]3[/b][/center]", "[center][b]2[/b][/center] @@ -46,7 +63,7 @@ tracks/1/path = NodePath("Counter:theme_override_colors/default_color") tracks/1/interp = 1 tracks/1/loop_wrap = true tracks/1/keys = { -"times": PackedFloat32Array(0, 1.5), +"times": PackedFloat32Array(0, 3), "transitions": PackedFloat32Array(1, 1), "update": 0, "values": [Color(1, 0.360784, 0.227451, 1), Color(0.980392, 0.737255, 0, 1)] @@ -58,7 +75,7 @@ tracks/2/path = NodePath("CanvasLayer/HBoxContainer/Panel2/Timer") tracks/2/interp = 1 tracks/2/loop_wrap = true tracks/2/keys = { -"times": PackedFloat32Array(1.5), +"times": PackedFloat32Array(3), "transitions": PackedFloat32Array(1), "values": [{ "args": [], @@ -83,7 +100,7 @@ tracks/4/path = NodePath("Camera") tracks/4/interp = 1 tracks/4/loop_wrap = true tracks/4/keys = { -"times": PackedFloat32Array(1.5), +"times": PackedFloat32Array(3), "transitions": PackedFloat32Array(1), "values": [{ "args": [], @@ -91,32 +108,18 @@ tracks/4/keys = { }] } -[sub_resource type="Animation" id="Animation_2si4r"] -length = 0.001 -tracks/0/type = "value" -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/path = NodePath("Counter:text") -tracks/0/interp = 1 -tracks/0/loop_wrap = true -tracks/0/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 1, -"values": [" -"] -} - [sub_resource type="AnimationLibrary" id="AnimationLibrary_hplnw"] _data = { "RESET": SubResource("Animation_2si4r"), "count_in": SubResource("Animation_uaks0") } -[node name="race" type="Node3D" node_paths=PackedStringArray("track")] +[node name="race" type="Node3D" node_paths=PackedStringArray("track", "splits", "timer")] script = ExtResource("1_ckbwd") car = ExtResource("6_nu32e") track = NodePath("Track") +splits = NodePath("CanvasLayer/Splits") +timer = NodePath("CanvasLayer/HBoxContainer/Panel2/Timer") [node name="Track" parent="." instance=ExtResource("11_6q53c")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) @@ -191,6 +194,9 @@ script = ExtResource("10_58kgt") track = NodePath("../../Track") player_color = Color(1, 0.388235, 0.321569, 0.803922) +[node name="Splits" parent="CanvasLayer" instance=ExtResource("14_ge1w6")] +visible = false + [node name="IntroCamera" type="Camera3D" parent="." node_paths=PackedStringArray("main_cam", "track", "count_player")] transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0) current = true diff --git a/scenes/ring_finish.tscn b/scenes/ring_finish.tscn index 1c3a86e..bcefdb6 100644 --- a/scenes/ring_finish.tscn +++ b/scenes/ring_finish.tscn @@ -3,13 +3,13 @@ [ext_resource type="Script" path="res://scenes/ring_finish.gd" id="1_oj823"] [ext_resource type="TorusMesh" uid="uid://bc8hyk8kfo4q1" path="res://assets/meshes/ring_finish.tres" id="2_hvrqd"] -[sub_resource type="TorusMesh" id="TorusMesh_c1qmt"] +[sub_resource type="TorusMesh" id="TorusMesh_afdq1"] inner_radius = 25.0 outer_radius = 40.0 rings = 10 ring_segments = 4 -[sub_resource type="BoxShape3D" id="BoxShape3D_431ml"] +[sub_resource type="BoxShape3D" id="BoxShape3D_bu8o6"] size = Vector3(52, 52, 3) [node name="RingFinish" type="PathFollow3D"] @@ -23,15 +23,14 @@ mesh = ExtResource("2_hvrqd") transform = Transform3D(1, 0, 0, 0, 1, -8.35187e-23, 0, -8.35187e-23, 1, 0, 0, 0) visible = false use_collision = true -mesh = SubResource("TorusMesh_c1qmt") +mesh = SubResource("TorusMesh_afdq1") [node name="PlayerDetector" type="Area3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.34943, 1.90735e-06, 0.0562134) collision_layer = 0 collision_mask = 2 monitorable = false [node name="Area" type="CollisionShape3D" parent="PlayerDetector"] -shape = SubResource("BoxShape3D_431ml") +shape = SubResource("BoxShape3D_bu8o6") -[connection signal="body_entered" from="PlayerDetector" to="." method="enter" flags=6 unbinds=1] +[connection signal="body_entered" from="PlayerDetector" to="." method="enter" unbinds=1] diff --git a/scenes/track-base.gd b/scenes/track-base.gd index ea2f40d..4a429b7 100644 --- a/scenes/track-base.gd +++ b/scenes/track-base.gd @@ -24,6 +24,7 @@ class_name TrackLoader @onready var sun := $Sun as DirectionalLight3D var checkpoints: Array[CheckPoint] +var finish: Finish var start_rot: Vector3 var start_pos: Vector3 var is_dirty := true @@ -103,17 +104,17 @@ func _update(): for i in len(track.checkpoints): var c: CheckPoint = make_follower(track.checkpoint_scene, track.checkpoints[i], track.checkpoint_scale, track.checkpoint_needs_collision) - checkpoints.append(c) if not Engine.is_editor_hint(): # godot tools are wierd - c.id = i + checkpoints.append(c) - var f: Finish = make_follower(track.finish_scene, track.finish_location, track.finish_scale, track.finish_needs_collision) - start_pos = f.global_position - start_rot = f.rotation + finish = make_follower(track.finish_scene, track.finish_location, track.finish_scale, track.finish_needs_collision) if track.laps == 0: var s: Start = make_follower(track.start_scene, track.start_location, track.start_scale, track.start_needs_collision) start_pos = s.global_position start_rot = s.rotation + else: + start_pos = finish.global_position + start_rot = finish.rotation start_rot = start_rot.snapped(Vector3(PI/2, PI/2, PI/2)) # loopage diff --git a/ui/intro_cam.gd b/ui/intro_cam.gd index 00c2afe..e1c3e60 100644 --- a/ui/intro_cam.gd +++ b/ui/intro_cam.gd @@ -19,7 +19,7 @@ func _ready() -> void: tween.tween_property(self, ^"global_position", main_cam.global_position, 2) tween.tween_property(self, ^"global_rotation", main_cam.global_rotation, 1) await tween.finished - count_player.play(&"count_in") + count_player.play(&"count_in", -1, 2) await count_player.animation_finished car.ball.freeze = false diff --git a/ui/splits/difference.gd b/ui/splits/difference.gd new file mode 100644 index 0000000..8d81ff3 --- /dev/null +++ b/ui/splits/difference.gd @@ -0,0 +1,27 @@ +extends PanelContainer + +@export var gain_style: StyleBox +@export var loss_style: StyleBox +@export var neutral_style: StyleBox +@export var label: Label + +enum Change { GAIN, LOSS, EQUAL } + +func update(time: float, prev_time: float) -> void: + var change := diff(time, prev_time) + style(change) + match change: + Change.LOSS: label.text = "+" + GameTimer.format(time - prev_time) + Change.GAIN: label.text = "-" + GameTimer.format(prev_time - time) + Change.EQUAL: label.text = "0:00.00" + +func diff(t1: float, t2: float) -> int: + if t1 == t2: + return Change.EQUAL + return Change.GAIN if t1 < t2 else Change.LOSS + +func style(d: int) -> void: + match d: + Change.LOSS: add_theme_stylebox_override(&"panel", loss_style) + Change.GAIN: add_theme_stylebox_override(&"panel", gain_style) + Change.EQUAL: add_theme_stylebox_override(&"panel", neutral_style) diff --git a/ui/splits/gains.tres b/ui/splits/gains.tres new file mode 100644 index 0000000..9a74265 --- /dev/null +++ b/ui/splits/gains.tres @@ -0,0 +1,6 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://b8xfllxmdboe5"] + +[resource] +content_margin_left = 5.0 +content_margin_right = 5.0 +bg_color = Color(0.458824, 0.545098, 1, 0.886275) diff --git a/ui/splits/loss.tres b/ui/splits/loss.tres new file mode 100644 index 0000000..dbb1eb3 --- /dev/null +++ b/ui/splits/loss.tres @@ -0,0 +1,6 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://dwfuwf6qbggrd"] + +[resource] +content_margin_left = 5.0 +content_margin_right = 5.0 +bg_color = Color(0.921569, 0.32549, 0.317647, 0.886275) diff --git a/ui/splits/neutral.tres b/ui/splits/neutral.tres new file mode 100644 index 0000000..fbbca98 --- /dev/null +++ b/ui/splits/neutral.tres @@ -0,0 +1,6 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://dddpw6gu8fex7"] + +[resource] +content_margin_left = 5.0 +content_margin_right = 5.0 +bg_color = Color(0.270588, 0.270588, 0.270588, 0.886275) diff --git a/ui/splits/splits.gd b/ui/splits/splits.gd new file mode 100644 index 0000000..a446b37 --- /dev/null +++ b/ui/splits/splits.gd @@ -0,0 +1,13 @@ +extends VBoxContainer + +@export var diff: PanelContainer +@export var current: Label + +var timer: SceneTreeTimer + +func update(time: float, prev_time: float) -> void: + show() + diff.update(time, prev_time) + current.text = GameTimer.format(time) + timer = get_tree().create_timer(5) + timer.timeout.connect(hide)
\ No newline at end of file diff --git a/ui/splits/splits.tres b/ui/splits/splits.tres new file mode 100644 index 0000000..3128fd6 --- /dev/null +++ b/ui/splits/splits.tres @@ -0,0 +1,10 @@ +[gd_resource type="Theme" load_steps=3 format=3 uid="uid://s8odxpp6ro5s"] + +[ext_resource type="SystemFont" uid="uid://xriuk0v4f6wj" path="res://ui/ubuntu.tres" id="1_feesq"] +[ext_resource type="StyleBox" uid="uid://dddpw6gu8fex7" path="res://ui/splits/neutral.tres" id="1_fv505"] + +[resource] +default_font = ExtResource("1_feesq") +default_font_size = 40 +PanelContainer/styles/panel = ExtResource("1_fv505") +VBoxContainer/constants/separation = 0 diff --git a/ui/splits/splits.tscn b/ui/splits/splits.tscn new file mode 100644 index 0000000..e7237ee --- /dev/null +++ b/ui/splits/splits.tscn @@ -0,0 +1,49 @@ +[gd_scene load_steps=7 format=3 uid="uid://nkh2xi7tnumc"] + +[ext_resource type="Theme" uid="uid://s8odxpp6ro5s" path="res://ui/splits/splits.tres" id="1_m5q5h"] +[ext_resource type="Script" path="res://ui/splits/splits.gd" id="2_2frki"] +[ext_resource type="Script" path="res://ui/splits/difference.gd" id="3_4w6ms"] +[ext_resource type="StyleBox" uid="uid://dwfuwf6qbggrd" path="res://ui/splits/loss.tres" id="4_5hoie"] +[ext_resource type="StyleBox" uid="uid://dddpw6gu8fex7" path="res://ui/splits/neutral.tres" id="4_ebhpa"] +[ext_resource type="StyleBox" uid="uid://b8xfllxmdboe5" path="res://ui/splits/gains.tres" id="4_uicx0"] + +[node name="Splits" type="VBoxContainer" node_paths=PackedStringArray("diff", "current")] +anchors_preset = 14 +anchor_top = 0.5 +anchor_right = 1.0 +anchor_bottom = 0.5 +offset_top = -395.0 +offset_bottom = -307.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("1_m5q5h") +script = ExtResource("2_2frki") +diff = NodePath("Difference") +current = NodePath("Current/Label") + +[node name="Current" type="PanelContainer" parent="."] +layout_mode = 2 +size_flags_horizontal = 4 + +[node name="Label" type="Label" parent="Current"] +custom_minimum_size = Vector2(160, 0) +layout_mode = 2 +text = "0:00.00" +horizontal_alignment = 2 +vertical_alignment = 1 + +[node name="Difference" type="PanelContainer" parent="." node_paths=PackedStringArray("label")] +layout_mode = 2 +size_flags_horizontal = 4 +script = ExtResource("3_4w6ms") +gain_style = ExtResource("4_uicx0") +loss_style = ExtResource("4_5hoie") +neutral_style = ExtResource("4_ebhpa") +label = NodePath("Label") + +[node name="Label" type="Label" parent="Difference"] +custom_minimum_size = Vector2(160, 0) +layout_mode = 2 +text = "+0:00.00" +horizontal_alignment = 2 +vertical_alignment = 1 diff --git a/ui/timer.gd b/ui/timer.gd index e2508ed..0895ecc 100644 --- a/ui/timer.gd +++ b/ui/timer.gd @@ -1,4 +1,5 @@ extends Label +class_name GameTimer var elapsed_time: float = 0.0 @@ -12,9 +13,9 @@ func stop() -> void: set_process(false) ## format a number of seconds into m:s.ms -func format(time: float) -> String: +static func format(time: float) -> String: return "%01d:%02d.%02d" % [time / 60, fmod(time, 60), fmod(time * 1000, 100)] func _process(delta: float) -> void: elapsed_time += delta - text = format(elapsed_time)
\ No newline at end of file + text = "祥 %s" % GameTimer.format(elapsed_time)
\ No newline at end of file |