Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add a podium at the end of the race #50

Merged
merged 4 commits into from
Feb 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

## [Unreleased]
### Added
- Add a podium at the end of the race ([#50](https://github.com/MechanicalFlower/Marble/pull/50))
### Changed
- Downgrade rendering settings of Godot ([#49](https://github.com/MechanicalFlower/Marble/pull/49))
- Refactor boost to define multiple power types ([#48](https://github.com/MechanicalFlower/Marble/pull/48))
- Refactor the out of bound detection ([#50](https://github.com/MechanicalFlower/Marble/pull/50))
### Deprecated
### Removed
### Fixed
- Update marble collision mask at each race ([#50](https://github.com/MechanicalFlower/Marble/pull/50))
### Security
### Dependencies

Expand Down
4 changes: 2 additions & 2 deletions project.godot
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ source/commit="41b766d42997fc9af1af4cb8680329bf02d0833f"

[custom_options]

build_info/commit="3d878b4ec308bd6e91a7d10dc8734d0f65c005fb"
build_info/date="2024/02/10"
build_info/commit="8b5eab3456e7d73e84274c37eb9fd5ca14825420"
build_info/date="2024/02/11"

[display]

Expand Down
8 changes: 7 additions & 1 deletion scenes/main.tscn
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
[gd_scene load_steps=8 format=3 uid="uid://bxmtpk5gebd06"]
[gd_scene load_steps=9 format=3 uid="uid://bxmtpk5gebd06"]

[ext_resource type="Script" path="res://scripts/main.gd" id="1"]
[ext_resource type="PackedScene" uid="uid://1ni00kklpf4b" path="res://scenes/gui/overlay.tscn" id="2"]
[ext_resource type="PackedScene" uid="uid://b8obdevmnmamd" path="res://scenes/race.tscn" id="3"]
[ext_resource type="PackedScene" uid="uid://4g5aorgnd1hu" path="res://scenes/marble.tscn" id="5"]
[ext_resource type="PackedScene" uid="uid://do5uv5bqridi0" path="res://scenes/explosion.tscn" id="6"]
[ext_resource type="PackedScene" uid="uid://bh0nd3c40wf75" path="res://scenes/gui/menu.tscn" id="7"]
[ext_resource type="PackedScene" uid="uid://butiacoqyc0um" path="res://scenes/podium.tscn" id="8_q3udf"]
[ext_resource type="PackedScene" uid="uid://cr0ipqbbhw6fv" path="res://scenes/gui/countdown.tscn" id="9"]

[node name="Main" type="Node"]
Expand Down Expand Up @@ -78,6 +79,11 @@ visible = false
[node name="Explosion" parent="." instance=ExtResource("6")]
visible = false

[node name="Podium" parent="." instance=ExtResource("8_q3udf")]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10, 30, 0)
visible = false

[node name="Timer" type="Timer" parent="."]
unique_name_in_owner = true
wait_time = 10.0
Expand Down
95 changes: 95 additions & 0 deletions scenes/podium.tscn
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
[gd_scene load_steps=11 format=3 uid="uid://butiacoqyc0um"]

[ext_resource type="Script" path="res://scripts/podium.gd" id="1_62kyn"]

[sub_resource type="BoxMesh" id="BoxMesh_j1v6k"]
size = Vector3(1, 1, 0.75)

[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_78627"]
diffuse_mode = 3
specular_mode = 1
albedo_color = Color(0.733333, 0.611765, 0.380392, 1)

[sub_resource type="BoxShape3D" id="BoxShape3D_olhkp"]

[sub_resource type="BoxMesh" id="BoxMesh_mf1on"]
size = Vector3(1, 0.75, 0.6)

[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_y6m2y"]
diffuse_mode = 3
specular_mode = 2
albedo_color = Color(0.690196, 0.670588, 0.654902, 1)

[sub_resource type="BoxShape3D" id="BoxShape3D_es7k6"]
size = Vector3(1, 0.75, 1)

[sub_resource type="BoxMesh" id="BoxMesh_u4h8o"]
size = Vector3(1, 0.5, 0.5)

[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_a8m4f"]
diffuse_mode = 3
specular_mode = 2
albedo_color = Color(0.658824, 0.435294, 0.254902, 1)

[sub_resource type="BoxShape3D" id="BoxShape3D_o3may"]
size = Vector3(1, 0.5, 1)

[node name="Podium" type="Node3D"]
script = ExtResource("1_62kyn")

[node name="FirstPlace" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
mesh = SubResource("BoxMesh_j1v6k")
surface_material_override/0 = SubResource("StandardMaterial3D_78627")

[node name="Marker3D" type="Marker3D" parent="FirstPlace"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.75, 0)

[node name="StaticBody3D" type="StaticBody3D" parent="FirstPlace"]

[node name="CollisionShape3D" type="CollisionShape3D" parent="FirstPlace/StaticBody3D"]
shape = SubResource("BoxShape3D_olhkp")

[node name="Label3D" type="Label3D" parent="FirstPlace"]
transform = Transform3D(4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0.426261)
text = "1"

[node name="SecondPlace" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1, 0.375, 0)
mesh = SubResource("BoxMesh_mf1on")
surface_material_override/0 = SubResource("StandardMaterial3D_y6m2y")

[node name="Marker3D" type="Marker3D" parent="SecondPlace"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.65, 0)

[node name="StaticBody3D" type="StaticBody3D" parent="SecondPlace"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0.125, 0)

[node name="CollisionShape3D" type="CollisionShape3D" parent="SecondPlace/StaticBody3D"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1, -0.125, 0)
shape = SubResource("BoxShape3D_es7k6")

[node name="Label3D" type="Label3D" parent="SecondPlace"]
transform = Transform3D(3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0.025, 0.5)
text = "2
"

[node name="ThirdPlace" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0.25, 0)
mesh = SubResource("BoxMesh_u4h8o")
surface_material_override/0 = SubResource("StandardMaterial3D_a8m4f")

[node name="Marker3D" type="Marker3D" parent="ThirdPlace"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.45, 0)

[node name="StaticBody3D" type="StaticBody3D" parent="ThirdPlace"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1, 0.25, 0)

[node name="CollisionShape3D" type="CollisionShape3D" parent="ThirdPlace/StaticBody3D"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, -0.250427, 0)
shape = SubResource("BoxShape3D_o3may")

[node name="Label3D" type="Label3D" parent="ThirdPlace"]
transform = Transform3D(2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0.5)
text = "3
"
25 changes: 17 additions & 8 deletions scripts/gui/ranking.gd
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ class_name Ranking
extends VBoxContainer

var _first_marble: Marble = null
var _second_marble: Marble = null
var _third_marble: Marble = null
var _last_marble: Marble = null


Expand All @@ -19,6 +21,10 @@ func update() -> void:

if len(arr) > 0:
_first_marble = arr[0].get_marble()
if len(arr) > 1:
_second_marble = arr[1].get_marble()
if len(arr) > 2:
_third_marble = arr[2].get_marble()

var rank := 0
for child in arr:
Expand All @@ -36,24 +42,27 @@ func more_checkpoint(a: Participant, b: Participant) -> bool:
var b_marble = b.get_marble()

var out: bool
if (
a_marble.has_finish() and b_marble.has_finish()
or a_marble.get_checkpoint_count() == b_marble.get_checkpoint_count()
):
if a_marble.has_finish() and b_marble.has_finish():
out = a.get_rank() < b.get_rank()
elif a_marble.has_finish():
out = true
elif b_marble.has_finish():
out = false
else:
if a_marble.has_explode() and b_marble.has_explode():
if (
(a_marble.has_explode() or a_marble.has_oob())
and (b_marble.has_explode() or b_marble.has_oob())
):
out = a.get_rank() < b.get_rank()
elif a_marble.has_explode():
elif a_marble.has_explode() or a_marble.has_oob():
out = false
elif b_marble.has_explode():
elif b_marble.has_explode() or b_marble.has_oob():
out = true
else:
out = a_marble.get_checkpoint_count() > b_marble.get_checkpoint_count()
if a_marble.get_checkpoint_count() == b_marble.get_checkpoint_count():
out = a.get_rank() < b.get_rank()
else:
out = a_marble.get_checkpoint_count() > b_marble.get_checkpoint_count()
return out


Expand Down
54 changes: 52 additions & 2 deletions scripts/main.gd
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ var _current_marble_index := 0
var _time := 0.0
var _explosion_enabled := false
var _race_has_started := false
var _lower_boundary = null

# Variables used in explosion mode to check
# if we need to generate another chunk of the race
Expand All @@ -38,6 +39,7 @@ var _positions := []
@onready var _panel_timer := _overlay.get_node(^"Panel2") as ColorRect
@onready var _label_timer = _overlay.get_node(^"Panel2/CenterContainer3/VBoxContainer/LabelTimer")
@onready var _countdown := get_node(^"%Countdown")
@onready var _podium := get_node(^"%Podium")


func _ready() -> void:
Expand Down Expand Up @@ -104,6 +106,7 @@ func _unhandled_input(event):
KEY_R:
if _mode == State.MODE_MARBLE:
_race.generate_race(!_explosion_enabled)
_lower_boundary = get_lowest_piece(_race, true).global_transform.origin.y

KEY_SPACE:
for marble in _marbles:
Expand Down Expand Up @@ -156,13 +159,39 @@ func get_highest_piece() -> Piece:
var pieces = _race.get_children()
if len(pieces) == 0:
return null
var highest_piece = pieces[0]
var highest_piece = null
for piece in pieces:
if piece.position.y > highest_piece.position.y:
if not piece is Piece:
continue
if highest_piece == null:
highest_piece = piece
elif piece.position.y > highest_piece.position.y:
highest_piece = piece
return highest_piece


func get_lowest_piece(piece_or_race, recursive: bool = false) -> Piece:
var pieces = piece_or_race.get_children()
if len(pieces) == 0:
return null

# Find the lower piece from children of the current node3d
var lowest_piece = null
for piece in pieces:
if not piece is Piece:
continue
if lowest_piece == null:
lowest_piece = piece
elif piece.position.y < lowest_piece.position.y:
lowest_piece = piece

if recursive:
var child_lowest_piece = get_lowest_piece(lowest_piece)
if child_lowest_piece != null:
lowest_piece = child_lowest_piece
return lowest_piece


# Replace cameras with a new one
func replace_camera(new_camera, old_cameras) -> void:
# Ensure old cameras are removed from the current scene
Expand Down Expand Up @@ -210,10 +239,13 @@ func set_mode(mode):
if _mode == State.MODE_MARBLE:
# If no marbles exist
if start_a_new_race:
_podium.hide()

await Fade.fade_out(1, Color.BLACK, "Diamond", false, false).finished

_explosion_enabled = SettingsManager.get_value(&"marbles", &"explosion_enabled") as bool
_race.generate_race(!_explosion_enabled)
_lower_boundary = get_lowest_piece(_race, true).global_transform.origin.y

_overlay.reset()
reset_position()
Expand Down Expand Up @@ -313,6 +345,7 @@ func _process(delta):
if lap_count > _old_lap_count:
# Generate a chunk
_race.generate_chunk()
_lower_boundary = get_lowest_piece(_race, true).global_transform.origin.y
_old_lap_count = lap_count
else:
_panel_timer.hide()
Expand All @@ -334,6 +367,23 @@ func _process(delta):
if not found:
replace_camera(_rotation_camera, [_marble_camera])

if _race_has_started:
_race_has_started = false
_podium.show()
_podium.set_first(_ranking._first_marble)
_podium.set_second(_ranking._second_marble)
_podium.set_third(_ranking._third_marble)

# Check if some marbles are out of bound
if _race_has_started and _lower_boundary != null:
for marble in _marbles:
if (
marble.visible
and marble._state == Marble.State.ROLL
and marble.global_transform.origin.y + 100 < _lower_boundary
):
marble.out_of_bound()


# Handle victory conditions on explosion mode
func explosion_victory(_last_marble: Marble) -> bool:
Expand Down
21 changes: 11 additions & 10 deletions scripts/marble.gd
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,6 @@ func _ready() -> void:
x_ray_material.set_next_pass(toon_material)
_ball_mesh.set_surface_override_material(0, x_ray_material)

# Set collision mask
var collision_enabled = SettingsManager.get_value(&"marbles", &"collision_enabled") as bool
if collision_enabled:
collision_mask = 1 << CollisionLayers.PROPS | 1 << CollisionLayers.MARBLES
else:
collision_mask = 1 << CollisionLayers.PROPS

pause()


Expand Down Expand Up @@ -93,9 +86,6 @@ func _process(_delta: float) -> void:
_name.global_transform.origin = offset
_score.global_transform.origin = offset + Vector3(-0.4, -0.2, 0)

if global_transform.origin.y < -10000:
out_of_bound()


func reset() -> void:
_start()
Expand Down Expand Up @@ -134,6 +124,16 @@ func _start() -> void:
set_physics_process(true)
set_sleeping(false)
set_linear_velocity(Vector3.ZERO)
set_inertia(Vector3.ZERO)
set_freeze_enabled(false)

# Set collision mask
var collision_enabled = SettingsManager.get_value(&"marbles", &"collision_enabled") as bool
if collision_enabled:
collision_mask = 1 << CollisionLayers.PROPS | 1 << CollisionLayers.MARBLES
else:
collision_mask = 1 << CollisionLayers.PROPS

collision_layer = 1 << CollisionLayers.MARBLES


Expand All @@ -143,4 +143,5 @@ func _stop() -> void:
set_physics_process(false)
set_sleeping(true)
set_linear_velocity(Vector3.ZERO)
set_freeze_enabled(true)
collision_layer = 0
19 changes: 19 additions & 0 deletions scripts/podium.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
extends Node3D


func set_first(marble: Marble):
if marble:
marble.global_position = get_node(^"FirstPlace/Marker3D").global_position
marble.visible = true


func set_second(marble: Marble):
if marble:
marble.global_position = get_node(^"SecondPlace/Marker3D").global_position
marble.visible = true


func set_third(marble: Marble):
if marble:
marble.global_position = get_node(^"ThirdPlace/Marker3D").global_position
marble.visible = true
Loading