Skip to content

Commit

Permalink
feat: add a podium at the end of the race (#50)
Browse files Browse the repository at this point in the history
* feat: add a podium at the end of the race

* fix: update marble collision mask at each race

* refactor: better oob detection

* chore: add changelog entries
  • Loading branch information
florianvazelle authored Feb 11, 2024
1 parent 8b5eab3 commit 82af809
Show file tree
Hide file tree
Showing 8 changed files with 206 additions and 23 deletions.
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

0 comments on commit 82af809

Please sign in to comment.