small racing game im working on
splits
bendn 2023-01-28
parent eeddb6c · commit c21aeb0
-rw-r--r--classes/checkpoint.gd2
-rw-r--r--race.gd14
-rw-r--r--race.tscn52
-rw-r--r--scenes/ring_finish.tscn11
-rw-r--r--scenes/track-base.gd11
-rw-r--r--ui/intro_cam.gd2
-rw-r--r--ui/splits/difference.gd27
-rw-r--r--ui/splits/gains.tres6
-rw-r--r--ui/splits/loss.tres6
-rw-r--r--ui/splits/neutral.tres6
-rw-r--r--ui/splits/splits.gd13
-rw-r--r--ui/splits/splits.tres10
-rw-r--r--ui/splits/splits.tscn49
-rw-r--r--ui/timer.gd5
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:
diff --git a/race.gd b/race.gd
index 4a86e88..bae0000 100644
--- a/race.gd
+++ b/race.gd
@@ -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 = []
diff --git a/race.tscn b/race.tscn
index 2bac7f6..6fb7f56 100644
--- a/race.tscn
+++ b/race.tscn
@@ -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