small racing game im working on
| -rw-r--r-- | classes/car.gd | 4 | ||||
| -rw-r--r-- | classes/trackdata.gd | 31 | ||||
| -rw-r--r-- | race.gd | 40 | ||||
| -rw-r--r-- | race.tscn | 34 | ||||
| -rw-r--r-- | scenes/ring_checkpoint.tscn | 10 | ||||
| -rw-r--r-- | tracks/multilap_test.tres (renamed from tracks/speedway_track.tres) | 19 | ||||
| -rw-r--r-- | tracks/multilap_test_curve.tres (renamed from tracks/speedway_curve.tres) | 0 | ||||
| -rw-r--r-- | ui/laps.gd | 14 | ||||
| -rw-r--r-- | ui/splits/difference.gd | 3 |
9 files changed, 113 insertions, 42 deletions
diff --git a/classes/car.gd b/classes/car.gd index 133abff..05085a2 100644 --- a/classes/car.gd +++ b/classes/car.gd @@ -7,8 +7,8 @@ class_name Car # mesh references @onready var right_wheel := $CarMesh/frontright as MeshInstance3D @onready var left_wheel := $CarMesh/frontleft as MeshInstance3D -@onready var skid_l = $CarMesh/SkidL as GPUParticles3D -@onready var skid_r = $CarMesh/SkidR as GPUParticles3D +@onready var skid_l := $CarMesh/SkidL as GPUParticles3D +@onready var skid_r := $CarMesh/SkidR as GPUParticles3D @onready var body_mesh := $CarMesh/body as MeshInstance3D @export var show_debug := false diff --git a/classes/trackdata.gd b/classes/trackdata.gd index e8a3914..3ac8175 100644 --- a/classes/trackdata.gd +++ b/classes/trackdata.gd @@ -1,10 +1,10 @@ class_name TrackSaveableData -extends RefCounted +extends Resource const SaveLoad := preload("res://addons/@bendn/remap/private/SaveLoadUtils.gd") var time: float -var checkpoints: PackedFloat32Array +var checkpoints: Array[PackedFloat32Array] var positional := { origins = PackedVector3Array(), rotations = PackedVector3Array(), @@ -15,15 +15,22 @@ var positional := { func data() -> Dictionary: return ({time = time, checkpoints = checkpoints, positional = positional}) -func _init(num_checkpoints: int) -> void: - checkpoints.resize(num_checkpoints) - checkpoints.fill(-1) +func _init(num_checkpoints := 0, laps := 0) -> void: + for i in laps: + var arr: PackedFloat32Array = [] + arr.resize(num_checkpoints + 1) + arr.fill(-1) + checkpoints.append(arr) -func collect(cp: int, now: float) -> void: - if cp == -1: # fin +func collect(lap: int, cp: int, now: float) -> void: + if lap == len(checkpoints) - 1 && cp == -1: + checkpoints[lap][cp] = now time = now else: - checkpoints[cp] = now + checkpoints[lap][cp] = now + +func get_time(lap: int, cp: int) -> float: + return checkpoints[lap][cp] func snapshot(obj: Car) -> void: positional.origins.append(obj.car_mesh.global_position) @@ -38,10 +45,12 @@ func snaps() -> int: return positional.snaps static func from_d(d: Dictionary) -> TrackSaveableData: + if !d.has_all(["checkpoints", "positional", "time"]) and d.positional.has_all(["origins", "rotations", "steering", "snaps"]): + return null var obj := TrackSaveableData.new(0) - obj.checkpoints = d.get("checkpoints", []) - obj.time = d.get("time", -1) - obj.positional = d.get("positional", {origins = [], rotations = [], steering = [], snaps = 0}) + obj.checkpoints = d.checkpoints + obj.time = d.time + obj.positional = d.positional return obj static func _load(path: String) -> TrackSaveableData: @@ -5,15 +5,18 @@ extends Node3D @export var track: TrackLoader @export var splits: Control @export var timer: Control -@onready var data := TrackSaveableData.new(track.checkpoints.size()) +@onready var data := TrackSaveableData.new(track.checkpoints.size(), track.track.laps) @onready var best_time_data := TrackSaveableData._load(saves % track.track.name) var car: Car var ghost: GhostCar +var current_lap := 0 var start_frame: int +var playing := false const SaveLoad := preload("res://addons/@bendn/remap/private/SaveLoadUtils.gd") const saves := "user://%s.trackdata" +signal next_lap signal created_car(car: Car) signal finished @@ -42,21 +45,29 @@ func _ready() -> void: created_car.emit(car) print("car created") for i in len(track.checkpoints): - track.checkpoints[i].collected.connect(collect.bind(i)) + track.checkpoints[i].collected.connect( + (func passed_cp(cp: int) -> void: if playing and data.checkpoints[current_lap][i] < 0: collect(cp)) + .bind(i)) track.finish.collected.connect( func passed_finish() -> void: - for t in data.checkpoints: # no any() function on packedfloat32 - if t < 0: + if !playing: return + for i in len(data.checkpoints[current_lap]) - 1: # no any() function on packedfloat32 + if data.checkpoints[current_lap][i] < 0: return collect(-1) - finished.emit() - print("finished") - if not best_time_data or data.time < best_time_data.time: - print("new pb!") - SaveLoad.save(saves % track.track.name, data.data()) - # best_time_data = data # this messes with the ghost, and doesnt matter yet anyways (until i can reset) - data = TrackSaveableData.new(track.checkpoints.size()) + if not track.track.laps or track.track.laps - 1 == current_lap: + finished.emit() + playing = false + print("finished") + if not best_time_data or data.time < best_time_data.time: + print("new pb!") + SaveLoad.save(saves % track.track.name, data.data()) + # best_time_data = data # this messes with the ghost, and doesnt matter yet anyways (until i can reset) + data = TrackSaveableData.new(track.checkpoints.size()) + else: + current_lap += 1 + next_lap.emit() ) func _physics_process(_delta: float) -> void: @@ -73,12 +84,13 @@ func _physics_process(_delta: float) -> void: func collect(cp: int) -> void: - var time := best_time_data.checkpoints[cp] if best_time_data else -1.0 - time = best_time_data.time if cp == -1 and time != -1.0 else time + var time := best_time_data.get_time(current_lap, cp) if best_time_data else -1.0 + time = best_time_data.time if (not track.track.laps or track.track.laps == current_lap + 1) and cp == -1 and time != -1.0 else time splits.update(timer.now(), time) - data.collect(cp, timer.now()) + data.collect(current_lap, cp, timer.now()) func _on_intro_camera_race_started() -> void: start_frame = Engine.get_physics_frames() + playing = true set_physics_process(true) @@ -1,4 +1,4 @@ -[gd_scene load_steps=22 format=3 uid="uid://dmkcxlevx4c7g"] +[gd_scene load_steps=23 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"] @@ -6,16 +6,17 @@ [ext_resource type="CameraAttributesPractical" uid="uid://nhsovwj5hjip" path="res://cam.tres" id="3_jx550"] [ext_resource type="Material" uid="uid://bdyn312e6c3ll" path="res://assets/mats/grass.tres" id="4_i1mlf"] [ext_resource type="Script" path="res://cam.gd" id="5_nb035"] +[ext_resource type="Curve3D" uid="uid://u2f56xx8h2re" path="res://tracks/multilap_test_curve.tres" id="5_yk721"] +[ext_resource type="Resource" uid="uid://crye0ijvmtsyb" path="res://tracks/multilap_test.tres" id="6_506fu"] [ext_resource type="PackedScene" uid="uid://ccn1nk1a0b0sa" path="res://assets/cars/kenney_sedan/sedan.tscn" id="6_nu32e"] [ext_resource type="Theme" uid="uid://ch2uo5qd8ubx6" path="res://ui/theme.tres" id="7_6itw5"] [ext_resource type="Script" path="res://ui/speedometer.gd" id="8_awr5n"] [ext_resource type="Script" path="res://ui/timer.gd" id="9_dn61b"] [ext_resource type="Script" path="res://ui/map.gd" id="10_58kgt"] [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"] +[ext_resource type="Script" path="res://ui/laps.gd" id="16_mxur4"] [sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_tkhh8"] @@ -125,8 +126,8 @@ 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) -curve = ExtResource("12_8yl7p") -track = ExtResource("13_sh6e8") +curve = ExtResource("5_yk721") +track = ExtResource("6_506fu") [node name="Camera" type="Camera3D" parent="."] transform = Transform3D(0.226651, 0, -0.973976, 0, 1, 0, 0.973976, 0, 0.226651, -25.1963, 1.82268, -2.33777) @@ -199,6 +200,27 @@ player_color = Color(1, 0.388235, 0.321569, 0.803922) [node name="Splits" parent="CanvasLayer" instance=ExtResource("14_ge1w6")] visible = false +[node name="Laps" type="PanelContainer" parent="CanvasLayer" node_paths=PackedStringArray("track", "label")] +anchors_preset = 2 +anchor_top = 1.0 +anchor_bottom = 1.0 +offset_left = 10.0 +offset_top = -80.0 +offset_right = 105.0 +grow_vertical = 0 +theme = ExtResource("7_6itw5") +script = ExtResource("16_mxur4") +track = NodePath("../../Track") +label = NodePath("Label") + +[node name="Label" type="Label" parent="CanvasLayer/Laps"] +layout_mode = 2 +size_flags_horizontal = 4 +theme_override_font_sizes/font_size = 50 +text = " 1/3" +horizontal_alignment = 1 +vertical_alignment = 1 + [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 @@ -239,4 +261,6 @@ libraries = { [connection signal="created_car" from="." to="CanvasLayer/HBoxContainer/Panel/Speedometer" method="_on_race_created_car"] [connection signal="created_car" from="." to="CanvasLayer/MiniMap" method="_on_race_created_car"] [connection signal="created_car" from="." to="IntroCamera" method="_on_race_created_car"] +[connection signal="finished" from="." to="CanvasLayer/Laps" method="increment"] +[connection signal="next_lap" from="." to="CanvasLayer/Laps" method="increment"] [connection signal="race_started" from="IntroCamera" to="." method="_on_intro_camera_race_started"] diff --git a/scenes/ring_checkpoint.tscn b/scenes/ring_checkpoint.tscn index eae51f3..c85070c 100644 --- a/scenes/ring_checkpoint.tscn +++ b/scenes/ring_checkpoint.tscn @@ -3,13 +3,13 @@ [ext_resource type="Script" path="res://scenes/ring_checkpoint.gd" id="1_cmmpp"] [ext_resource type="TorusMesh" uid="uid://dlbpusye3e33p" path="res://assets/meshes/checkpoint.tres" id="2_xys6y"] -[sub_resource type="TorusMesh" id="TorusMesh_wt6vi"] +[sub_resource type="TorusMesh" id="TorusMesh_mi087"] inner_radius = 25.0 outer_radius = 40.0 rings = 10 ring_segments = 4 -[sub_resource type="BoxShape3D" id="BoxShape3D_2btqs"] +[sub_resource type="BoxShape3D" id="BoxShape3D_k77jm"] size = Vector3(52, 52, 3) [node name="Checkpoint" type="PathFollow3D"] @@ -24,7 +24,7 @@ mesh = ExtResource("2_xys6y") 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_wt6vi") +mesh = SubResource("TorusMesh_mi087") [node name="PlayerDetector" type="Area3D" parent="."] collision_layer = 0 @@ -32,6 +32,6 @@ collision_mask = 2 monitorable = false [node name="Area" type="CollisionShape3D" parent="PlayerDetector"] -shape = SubResource("BoxShape3D_2btqs") +shape = SubResource("BoxShape3D_k77jm") -[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/tracks/speedway_track.tres b/tracks/multilap_test.tres index 9ee2d5e..b8894b9 100644 --- a/tracks/speedway_track.tres +++ b/tracks/multilap_test.tres @@ -1,9 +1,10 @@ -[gd_resource type="Resource" script_class="TrackResource" load_steps=5 format=3 uid="uid://busubw34xl76"] +[gd_resource type="Resource" script_class="TrackResource" load_steps=6 format=3 uid="uid://crye0ijvmtsyb"] [ext_resource type="Script" path="res://classes/track.gd" id="1_c5h3o"] [ext_resource type="PackedScene" uid="uid://d4a3e1w62m3ck" path="res://scenes/ring_checkpoint.tscn" id="1_ehf5p"] -[ext_resource type="Curve3D" uid="uid://u2f56xx8h2re" path="res://tracks/speedway_curve.tres" id="2_33qpi"] +[ext_resource type="Curve3D" uid="uid://u2f56xx8h2re" path="res://tracks/multilap_test_curve.tres" id="2_33qpi"] [ext_resource type="PackedScene" uid="uid://t8ywjcjgw322" path="res://scenes/ring_finish.tscn" id="2_lfdrw"] +[ext_resource type="PackedScene" uid="uid://bsftidvcmsha0" path="res://scenes/ring_start.tscn" id="4_awtsk"] [resource] resource_local_to_scene = true @@ -15,11 +16,21 @@ support_height = 2.0 track = ExtResource("2_33qpi") left_barrier = true right_barrier = true -sun_x = -90 +sun_x = -50 sun_y = 0 +name = "multilap test" +is_loop = true offset = Vector3(0, 1, 0) +laps = 3 checkpoints = PackedFloat32Array(0.2, 0.6) checkpoint_scene = ExtResource("1_ehf5p") +checkpoint_scale = Vector3(1, 1, 1) +checkpoint_needs_collision = true finish_location = 0.0 finish_scene = ExtResource("2_lfdrw") -laps = 0 +finish_scale = Vector3(1, 1, 1) +finish_needs_collision = true +start_location = 0.0 +start_scene = ExtResource("4_awtsk") +start_scale = Vector3(1, 1, 1) +start_needs_collision = true diff --git a/tracks/speedway_curve.tres b/tracks/multilap_test_curve.tres index 2523886..2523886 100644 --- a/tracks/speedway_curve.tres +++ b/tracks/multilap_test_curve.tres diff --git a/ui/laps.gd b/ui/laps.gd new file mode 100644 index 0000000..9189a17 --- /dev/null +++ b/ui/laps.gd @@ -0,0 +1,14 @@ +extends PanelContainer + +@export var track: TrackLoader +@export var label: Label + +var lap := 0 + +func _ready() -> void: + visible = track.track.laps + increment() + +func increment() -> void: + lap += 1 + label.text = " %d/%d" % [lap, track.track.laps] diff --git a/ui/splits/difference.gd b/ui/splits/difference.gd index ee5c910..c9d33eb 100644 --- a/ui/splits/difference.gd +++ b/ui/splits/difference.gd @@ -10,6 +10,7 @@ enum Change { GAIN, LOSS, EQUAL } func update(time: float, prev_time: float) -> void: if prev_time < 0: # no time set hide() + return else: show() # shouldnt be needed but just to be carefull var change := diff(time, prev_time) @@ -20,7 +21,7 @@ func update(time: float, prev_time: float) -> void: Change.EQUAL: label.text = "0:00.00" func diff(t1: float, t2: float) -> int: - if t1 == t2: + if is_equal_approx(t1, t2): return Change.EQUAL return Change.GAIN if t1 < t2 else Change.LOSS |