Compare commits

...

11 commits

Author SHA1 Message Date
TheThomaas fc1f024fdd Update pause menu 2026-09-27 15:21:31 +02:00
TheThomaas 43bd8cb8fc Add sound management 2026-09-27 15:09:55 +02:00
TheThomaas 28fd165018 Add splash_screen scene 2026-09-27 15:04:16 +02:00
TheThomaas 6c040d05da Add static image splash screen 2026-09-27 12:17:35 +02:00
TheThomaas 26fde49734 Add game version 2026-09-27 12:17:19 +02:00
TheThomaas 80af211fd7 Add dodge option when crouching 2026-09-27 11:55:20 +02:00
TheThomaas 40dd2d35bb Update main_menu 2026-09-27 11:55:02 +02:00
TheThomaas 4d76902345 Remove double jump from player 2026-09-27 11:07:53 +02:00
TheThomaas c4825f8080 Add CrouchState 2026-09-27 11:05:24 +02:00
TheThomaas 042840309d Add DodgeState 2026-09-27 10:31:36 +02:00
TheThomaas 082f834d61 Fix RunState 2026-09-27 10:17:24 +02:00
30 changed files with 1004 additions and 99 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 MiB

View file

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://d23fefvrd41re"
path="res://.godot/imported/0.png-7d5620e6b53641efc94237993c24f99a.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/textures/background/0.png"
dest_files=["res://.godot/imported/0.png-7d5620e6b53641efc94237993c24f99a.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

BIN
assets/textures/splash.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View file

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c28nuhy3im7y4"
path="res://.godot/imported/splash.png-0b8f43ca2dd6cb6080b9bf1776f879c5.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/textures/splash.png"
dest_files=["res://.godot/imported/splash.png-0b8f43ca2dd6cb6080b9bf1776f879c5.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

9
default_bus_layout.tres Normal file
View file

@ -0,0 +1,9 @@
[gd_resource type="AudioBusLayout" format=3 uid="uid://cpmscnqvdpn8f"]
[resource]
bus/1/name = &"SFX"
bus/1/solo = false
bus/1/mute = false
bus/1/bypass_fx = false
bus/1/volume_db = 0.0
bus/1/send = &"Master"

View file

@ -12,6 +12,8 @@ class_name InputManagementComponent
@export var move_right_action : StringName = "player_move_right"
@export var run_action : StringName = "player_run"
@export var jump_action : StringName = "player_jump"
@export var dodge_action : StringName = "player_dodge"
@export var crouch_action : StringName = "player_crouch"
@export_subgroup("Camera variables")
@export var aim_cam_action : StringName = "player_aim_camera"
@export var cam_zoom_in_action : StringName = "player_zoom_camera_in"
@ -36,6 +38,8 @@ func attribute_keybinds() -> void:
play_char_ref.move_right_action = move_right_action
play_char_ref.run_action = run_action
play_char_ref.jump_action = jump_action
play_char_ref.dodge_action = dodge_action
play_char_ref.crouch_action = crouch_action
play_char_ref.aim_cam_action = aim_cam_action
cam_holder_ref.aim_cam_action = aim_cam_action

View file

@ -8,6 +8,9 @@
[ext_resource type="Script" uid="uid://2agliol5dulc" path="res://game/player/StateMachine/WalkState.gd" id="4_lg056"]
[ext_resource type="Script" uid="uid://dr5p8ygj25w6x" path="res://game/player/StateMachine/JumpState.gd" id="6_lwgph"]
[ext_resource type="Script" uid="uid://dn5idrvu68k83" path="res://game/player/StateMachine/AimState.gd" id="7_kxr4l"]
[ext_resource type="Script" uid="uid://dpcfffs3vt5co" path="res://game/player/StateMachine/RunState.gd" id="8_j4mf1"]
[ext_resource type="Script" uid="uid://bwojkp7yrwswt" path="res://game/player/StateMachine/DodgeState.gd" id="9_6abew"]
[ext_resource type="Script" uid="uid://d0577tj0c23bu" path="res://game/player/StateMachine/CrouchState.gd" id="10_mi63v"]
[sub_resource type="Curve" id="Curve_kxr4l"]
_limits = [0.0, 10.0, 0.0, 1.0]
@ -38,6 +41,7 @@ size = Vector3(0.1484375, 0.1640625, 0.907959)
[node name="PlayerCharacter" type="CharacterBody3D" unique_id=1830301535]
script = ExtResource("1_lg056")
nb_jumps_in_air_allowed = 0
in_air_move_speed = Array[Curve]([SubResource("Curve_kxr4l"), SubResource("Curve_j4mf1")])
in_air_accel = Array[Curve]([SubResource("Curve_6abew"), SubResource("Curve_mi63v")])
hit_wall_cut_velocity = true
@ -82,6 +86,13 @@ script = ExtResource("6_lwgph")
script = ExtResource("7_kxr4l")
[node name="RunState" type="Node" parent="StateMachine" unique_id=1345421775]
script = ExtResource("8_j4mf1")
[node name="DodgeState" type="Node" parent="StateMachine" unique_id=232179400]
script = ExtResource("9_6abew")
[node name="CrouchState" type="Node" parent="StateMachine" unique_id=381419367]
script = ExtResource("10_mi63v")
[node name="InputManagementComponent" type="Node" parent="." unique_id=1981951371]
script = ExtResource("2_r5dqo")

View file

@ -23,10 +23,14 @@ var play_char : CharacterBody3D
@export var aim_move_accel : float = 8.0
var auto_lock_blocked : bool = false #true apres un deverrouillage manuel, tant que la cible est encore au centre
var dodging_from_aim : bool = false #true quand on quitte Aim pour rouler, pour ne pas relacher la cible verrouillee
var came_from_crouch : bool = false #true si Aim a ete declenche depuis CrouchState, pour y retourner en sortant
func enter(play_char_ref : CharacterBody3D) -> void:
play_char = play_char_ref
auto_lock_blocked = false
#curr_state_name n'est pas encore mis a jour a ce stade : il reflete encore l'etat qu'on est en train de quitter
came_from_crouch = play_char.state_machine.curr_state_name == "Crouch"
verifications()
func verifications() -> void:
@ -34,6 +38,10 @@ func verifications() -> void:
play_char.cam_holder.cam_aimed = true
func exit() -> void:
if dodging_from_aim:
#on roule en visant : la camera et la cible verrouillee restent actives pendant la roulade
dodging_from_aim = false
return
release_target()
if play_char: play_char.cam_holder.cam_aimed = false
@ -51,8 +59,16 @@ func applies() -> bool:
return false
func input_management() -> bool:
if Input.is_action_just_pressed(play_char.dodge_action) and play_char.dodge_cooldown <= 0.0:
dodging_from_aim = true
transitioned.emit(self, "DodgeState")
return true
if !Input.is_action_pressed(aim_action):
transitioned.emit(self, play_char.walk_or_run if play_char.move_dir else "IdleState")
if came_from_crouch:
transitioned.emit(self, "CrouchState")
else:
transitioned.emit(self, play_char.walk_or_run if play_char.move_dir else "IdleState")
return true
if Input.is_action_just_pressed(unlock_action):

View file

@ -0,0 +1,74 @@
extends State
class_name CrouchState
var state_name : String = "Crouch"
var play_char : CharacterBody3D
func enter(play_char_ref : CharacterBody3D) -> void:
play_char = play_char_ref
verifications()
func verifications() -> void:
#play_char.godot_plush_skin.set_state("crouch")
play_char.move_speed = play_char.crouch_speed
play_char.move_accel = play_char.crouch_accel
play_char.move_deccel = play_char.crouch_deccel
play_char.floor_snap_length = 1.0
if play_char.jump_cooldown > 0.0: play_char.jump_cooldown = -1.0
if play_char.nb_jumps_in_air_allowed < play_char.nb_jumps_in_air_allowed_ref: play_char.nb_jumps_in_air_allowed = play_char.nb_jumps_in_air_allowed_ref
if play_char.coyote_jump_cooldown < play_char.coyote_jump_cooldown_ref: play_char.coyote_jump_cooldown = play_char.coyote_jump_cooldown_ref
if play_char.has_cut_jump: play_char.has_cut_jump = false
play_char.is_crouching = true
func exit() -> void:
play_char.is_crouching = false
func physics_update(delta : float) -> void:
applies()
play_char.gravity_apply(delta)
input_management()
move(delta)
func applies() -> void:
#quitter le sol (ex: crouch au bord d'une plateforme) bascule vers InairState, comme IdleState
if !play_char.is_on_floor() and !play_char.is_on_wall():
transitioned.emit(self, "InairState")
#le saut est bloque en crouch : on ne consomme pas le jump buffer ici, il restera en attente
#et sera pris en compte des la sortie du crouch (Idle/Walk)
func input_management() -> void:
if Input.is_action_just_pressed(play_char.dodge_action) and play_char.dodge_cooldown <= 0.0:
transitioned.emit(self, "DodgeState")
#courir annule automatiquement le crouch
if play_char.walk_or_run == "RunState":
transitioned.emit(self, "RunState")
#bascule (toggle) : un nouvel appui ressort du crouch vers l'etat au sol approprie
if Input.is_action_just_pressed(play_char.crouch_action):
transitioned.emit(self, play_char.walk_or_run if play_char.move_dir else "IdleState")
if Input.is_action_just_pressed(play_char.aim_cam_action):
transitioned.emit(self, "AimState")
#pas de saut ici : le jump_action est volontairement ignore pendant le crouch
func move(delta : float) -> void:
play_char.move_dir = Input.get_vector(play_char.move_left_action, play_char.move_right_action, play_char.move_forward_action, play_char.move_backward_action).rotated(-play_char.cam_holder.global_rotation.y)
if play_char.move_dir and play_char.is_on_floor():
#deplacement accroupi, a vitesse reduite
play_char.velocity.x = lerp(play_char.velocity.x, play_char.move_dir.x * play_char.move_speed, play_char.move_accel * delta)
play_char.velocity.z = lerp(play_char.velocity.z, play_char.move_dir.y * play_char.move_speed, play_char.move_accel * delta)
else:
#pas de transition vers Idle ici : Crouch gere lui-meme l'immobilite, comme AimState
play_char.velocity.x = lerp(play_char.velocity.x, 0.0, play_char.move_deccel * delta)
play_char.velocity.z = lerp(play_char.velocity.z, 0.0, play_char.move_deccel * delta)

View file

@ -0,0 +1 @@
uid://d0577tj0c23bu

View file

@ -0,0 +1,76 @@
extends State
class_name DodgeState
var state_name : String = "Dodge"
var play_char : CharacterBody3D
@export var dodge_speed_curve : Curve #optionnel : controle le "falloff" de vitesse pendant la roulade (1.0 = pleine vitesse, 0.0 = arret). Laisser vide pour une vitesse constante.
var dodge_dir : Vector2 = Vector2.ZERO
var dodge_timer : float = 0.0
var dodge_duration_ref : float = 0.0
func enter(play_char_ref : CharacterBody3D) -> void:
play_char = play_char_ref
verifications()
func verifications() -> void:
play_char.floor_snap_length = 1.0
play_char.is_dodging = true
play_char.dodge_cooldown = play_char.dodge_cooldown_ref
#roule dans la direction actuelle de l'input, ou dans la derniere direction connue si aucune touche n'est tenue (comportement Arceus)
dodge_dir = play_char.move_dir if play_char.move_dir != Vector2.ZERO else play_char.last_input_dir
if dodge_dir == Vector2.ZERO: dodge_dir = Vector2.DOWN #direction par defaut si le perso n'a encore jamais bouge
dodge_dir = dodge_dir.normalized()
dodge_timer = play_char.dodge_duration
dodge_duration_ref = play_char.dodge_duration
#oriente immediatement le modele dans la direction de la roulade, verrouillee pour toute sa duree
play_char.visual_root.rotation.y = -dodge_dir.orthogonal().angle()
func exit() -> void:
play_char.is_dodging = false
func physics_update(delta : float) -> void:
applies()
play_char.gravity_apply(delta)
move(delta)
dodge_timer -= delta
if dodge_timer <= 0.0:
end_dodge()
func applies() -> void:
#si le perso quitte le sol en roulant (ex: roulade vers un bord), on bascule vers InairState comme les autres etats au sol
if !play_char.is_on_floor() and !play_char.is_on_wall():
if play_char.velocity.y < 0.0:
transitioned.emit(self, "InairState")
func move(_delta : float) -> void:
if !play_char.is_on_floor(): return
#falloff de vitesse : pleine vitesse par defaut, ou modele par dodge_speed_curve si assignee
var ratio : float = 1.0
if dodge_speed_curve:
ratio = dodge_speed_curve.sample(1.0 - (dodge_timer / dodge_duration_ref))
play_char.velocity.x = dodge_dir.x * play_char.dodge_speed * ratio
play_char.velocity.z = dodge_dir.y * play_char.dodge_speed * ratio
func end_dodge() -> void:
#a la fin de la roulade, retour a l'etat approprie
if !play_char.is_on_floor():
transitioned.emit(self, "InairState")
elif Input.is_action_pressed(play_char.aim_cam_action):
transitioned.emit(self, "AimState") #le joueur a garde la visee enfoncee pendant la roulade
elif play_char.move_dir:
transitioned.emit(self, play_char.walk_or_run)
else:
transitioned.emit(self, "IdleState")

View file

@ -0,0 +1 @@
uid://bwojkp7yrwswt

View file

@ -44,6 +44,12 @@ func applies() -> void:
func input_management() -> void:
#manage the state transitions depending on the actions inputs
if Input.is_action_just_pressed(play_char.dodge_action) and play_char.dodge_cooldown <= 0.0:
transitioned.emit(self, "DodgeState")
if Input.is_action_just_pressed(play_char.crouch_action):
transitioned.emit(self, "CrouchState")
if Input.is_action_pressed(play_char.jump_action) if play_char.auto_jump else Input.is_action_just_pressed(play_char.jump_action):
transitioned.emit(self, "JumpState")
@ -51,13 +57,6 @@ func input_management() -> void:
if Input.is_action_just_pressed(play_char.aim_cam_action):
transitioned.emit(self, "AimState")
if play_char.continious_run:
if Input.is_action_just_pressed(play_char.run_action):
if play_char.walk_or_run == "WalkState": play_char.walk_or_run = "RunState"
elif play_char.walk_or_run == "RunState": play_char.walk_or_run = "WalkState"
else:
play_char.walk_or_run = "RunState" if Input.is_action_pressed(play_char.run_action) else "WalkState"
func move(delta : float) -> void:
#manage the character movement

View file

@ -13,6 +13,8 @@ var last_frame_position : Vector3
var last_frame_velocity : Vector3
var was_on_floor : bool = false
var walk_or_run : String = "WalkState" #keep in memory if play char was walking or running before being in the air
var is_dodging : bool = false #true while DodgeState is active ; hook this up to a hurtbox/i-frame check later
var is_crouching : bool = false #true while CrouchState is active ; hook this up to a collision-shape resize later
@export_group("Walk variables")
@export var walk_speed : float = 5.0
@ -25,6 +27,17 @@ var walk_or_run : String = "WalkState" #keep in memory if play char was walking
@export var run_deccel : float = 6.5
@export var continious_run : bool = false #if true, doesn't need to keep run button on to run
@export_group("Dodge variables")
@export var dodge_speed : float = 10.0
@export var dodge_duration : float = 0.4
@export var dodge_cooldown : float = 0.6
var dodge_cooldown_ref : float
@export_group("Crouch variables")
@export var crouch_speed : float = 2.5
@export var crouch_accel : float = 7.0
@export var crouch_deccel : float = 7.0
@export_group("Jump variables")
@export var jump_height : float = 3.0
@export var jump_time_to_peak : float = 0.35
@ -59,6 +72,8 @@ var move_left_action : StringName
var move_right_action : StringName
var run_action : StringName
var jump_action : StringName
var dodge_action : StringName
var crouch_action : StringName
var aim_cam_action : StringName
@export_group("Model variables")
@ -93,14 +108,17 @@ func _ready():
jump_cooldown_ref = jump_cooldown
nb_jumps_in_air_allowed_ref = nb_jumps_in_air_allowed
coyote_jump_cooldown_ref = coyote_jump_cooldown
dodge_cooldown_ref = dodge_cooldown
#connect_footstep_audio_effect()
func _process(delta: float):
modify_model_orientation(delta)
func _physics_process(_delta : float):
func _physics_process(delta : float):
update_run_toggle()
modify_physics_properties()
tick_dodge_cooldown(delta)
move_and_slide()
@ -135,6 +153,11 @@ func modify_physics_properties():
last_frame_position = position #get play char position every frame
last_frame_velocity = velocity #get play char velocity every frame
was_on_floor = !is_on_floor() #get if play char is on floor or not
if move_dir != Vector2.ZERO: last_input_dir = move_dir #memorize the last non-zero input direction, used as a dodge fallback
func tick_dodge_cooldown(delta : float) -> void:
if dodge_cooldown > 0.0:
dodge_cooldown -= delta
func gravity_apply(delta : float):
#if play char goes up, apply jump gravity
@ -159,3 +182,9 @@ func squash_and_strech(value : float, timing : float):
#foot_step_audio.play()
#)
func update_run_toggle() -> void:
if continious_run:
if Input.is_action_just_pressed(run_action):
walk_or_run = "WalkState" if walk_or_run == "RunState" else "RunState"
else:
walk_or_run = "RunState" if Input.is_action_pressed(run_action) else "WalkState"

View file

@ -46,21 +46,17 @@ func applies() -> void:
transitioned.emit(self, "JumpState")
func input_management() -> void:
if Input.is_action_just_pressed(play_char.dodge_action) and play_char.dodge_cooldown <= 0.0:
transitioned.emit(self, "DodgeState")
if Input.is_action_pressed(play_char.jump_action) if play_char.auto_jump else Input.is_action_just_pressed(play_char.jump_action):
transitioned.emit(self, "JumpState")
if play_char.continious_run:
#course continue : un nouvel appui sur la touche repasse a la marche
if Input.is_action_just_pressed(play_char.run_action):
stop_running()
else:
#course maintenue : on court tant que la touche est enfoncee
if !Input.is_action_pressed(play_char.run_action):
stop_running()
if Input.is_action_just_pressed(play_char.aim_cam_action):
transitioned.emit(self, "AimState")
func stop_running() -> void:
play_char.walk_or_run = "WalkState"
transitioned.emit(self, "WalkState")
if play_char.walk_or_run == "WalkState":
transitioned.emit(self, "WalkState")
func move(delta : float) -> void:
play_char.move_dir = Input.get_vector(play_char.move_left_action, play_char.move_right_action, play_char.move_forward_action, play_char.move_backward_action).rotated(-play_char.cam_holder.global_rotation.y)

View file

@ -46,15 +46,19 @@ func applies() -> void:
transitioned.emit(self, "JumpState")
func input_management() -> void:
if Input.is_action_just_pressed(play_char.dodge_action) and play_char.dodge_cooldown <= 0.0:
transitioned.emit(self, "DodgeState")
if Input.is_action_just_pressed(play_char.crouch_action):
transitioned.emit(self, "CrouchState")
if Input.is_action_pressed(play_char.jump_action) if play_char.auto_jump else Input.is_action_just_pressed(play_char.jump_action) :
transitioned.emit(self, "JumpState")
if Input.is_action_just_pressed(play_char.aim_cam_action):
transitioned.emit(self, "AimState")
var wants_run : bool = Input.is_action_just_pressed(play_char.run_action) if play_char.continious_run else Input.is_action_pressed(play_char.run_action)
if wants_run:
play_char.walk_or_run = "RunState"
if play_char.walk_or_run == "RunState":
transitioned.emit(self, "RunState")
func move(delta : float) -> void:
@ -66,3 +70,4 @@ func move(delta : float) -> void:
play_char.velocity.z = lerp(play_char.velocity.z, play_char.move_dir.y * play_char.move_speed, play_char.move_accel * delta)
else:
transitioned.emit(self, "IdleState")

View file

@ -11,13 +11,17 @@ config_version=5
[application]
config/name="Tales-of-PKMN"
run/main_scene="uid://bicg07c42wm1t"
config/version="0.0.1dev"
run/main_scene="uid://bi3r04lqth7iq"
config/features=PackedStringArray("4.7", "Forward Plus")
boot_splash/show_image=false
config/icon="res://icon.svg"
[autoload]
ControllerIcons="*uid://b7ho1rjcpht1d"
GameData="*uid://d4beiel88cwc7"
UiAudio="*uid://7e7fe2xk3aue"
[display]

View file

@ -2,6 +2,10 @@
[ext_resource type="Script" uid="uid://cj37ns1ahfvhr" path="res://scripts/main_menu.gd" id="1_ekxnf"]
[ext_resource type="Script" uid="uid://7hglx6nfu063" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="2_bqqt6"]
[ext_resource type="Texture2D" uid="uid://d23fefvrd41re" path="res://assets/textures/background/0.png" id="2_wu84c"]
[sub_resource type="LabelSettings" id="LabelSettings_3agn1"]
font_size = 64
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_bqqt6"]
@ -14,8 +18,12 @@ script = ExtResource("2_bqqt6")
path = "ui_accept"
metadata/_custom_type_script = "uid://7hglx6nfu063"
[sub_resource type="LabelSettings" id="LabelSettings_3agn1"]
font_size = 64
[sub_resource type="Texture2D" id="Texture2D_bqqt6"]
resource_local_to_scene = false
resource_name = ""
script = ExtResource("2_bqqt6")
path = "ui_cancel"
metadata/_custom_type_script = "uid://7hglx6nfu063"
[node name="MainMenu" type="Control" unique_id=1471802333]
layout_mode = 3
@ -25,60 +33,46 @@ anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_ekxnf")
progression_backgrounds = Array[Texture2D]([ExtResource("2_wu84c")])
[node name="PanelContainer" type="PanelContainer" parent="." unique_id=1404024715]
[node name="Background" type="TextureRect" parent="." unique_id=545049912]
unique_name_in_owner = true
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
expand_mode = 1
stretch_mode = 6
[node name="GameInfos" type="Control" parent="." unique_id=2060446590]
unique_name_in_owner = true
layout_mode = 1
anchors_preset = 6
anchor_left = 1.0
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
offset_left = -40.0
offset_top = -20.0
offset_bottom = 20.0
grow_horizontal = 0
grow_vertical = 2
[node name="GreyedBackground" type="PanelContainer" parent="GameInfos" unique_id=1404024715]
layout_mode = 0
anchor_left = 1.0
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
offset_left = -571.0
offset_top = -323.5
offset_bottom = 323.5
grow_horizontal = 0
grow_vertical = 2
[node name="MarginContainer" type="MarginContainer" parent="." unique_id=1437260283]
layout_mode = 1
anchors_preset = 3
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = -130.0
offset_top = -67.0
grow_horizontal = 0
grow_vertical = 0
theme_override_constants/margin_right = 200
theme_override_constants/margin_bottom = 150
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer" unique_id=212717997]
layout_mode = 2
[node name="PanelContainer" type="PanelContainer" parent="MarginContainer/VBoxContainer" unique_id=455366583]
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxEmpty_bqqt6")
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer/PanelContainer" unique_id=980574030]
layout_mode = 2
[node name="Start" type="Button" parent="MarginContainer/VBoxContainer/PanelContainer/HBoxContainer" unique_id=1823965781]
unique_name_in_owner = true
layout_mode = 2
theme_override_styles/focus = SubResource("StyleBoxEmpty_ekxnf")
text = "Appuyer sur"
flat = true
icon_alignment = 2
[node name="TextureRect" type="TextureRect" parent="MarginContainer/VBoxContainer/PanelContainer/HBoxContainer" unique_id=544893863]
custom_minimum_size = Vector2(40, 40)
layout_mode = 2
size_flags_vertical = 3
texture = SubResource("Texture2D_wu84c")
expand_mode = 1
[node name="Label" type="Label" parent="." unique_id=745232782]
[node name="GameTitle" type="Label" parent="GameInfos" unique_id=745232782]
layout_mode = 1
anchors_preset = 6
anchor_left = 1.0
@ -94,4 +88,95 @@ grow_vertical = 2
text = "Tales of PKMN"
label_settings = SubResource("LabelSettings_3agn1")
[connection signal="pressed" from="MarginContainer/VBoxContainer/PanelContainer/HBoxContainer/Start" to="." method="_on_start_pressed"]
[node name="Buttons" type="MarginContainer" parent="GameInfos" unique_id=1437260283]
layout_mode = 1
anchors_preset = 3
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = -347.0
offset_top = 79.0
offset_bottom = 304.0
grow_horizontal = 0
grow_vertical = 0
theme_override_constants/margin_right = 200
theme_override_constants/margin_bottom = 150
[node name="VBoxContainer" type="VBoxContainer" parent="GameInfos/Buttons" unique_id=212717997]
layout_mode = 2
[node name="StartContainer" type="PanelContainer" parent="GameInfos/Buttons/VBoxContainer" unique_id=455366583]
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxEmpty_bqqt6")
[node name="HBoxContainer" type="HBoxContainer" parent="GameInfos/Buttons/VBoxContainer/StartContainer" unique_id=980574030]
layout_mode = 2
[node name="Start" type="Button" parent="GameInfos/Buttons/VBoxContainer/StartContainer/HBoxContainer" unique_id=1823965781]
unique_name_in_owner = true
layout_mode = 2
focus_neighbor_bottom = NodePath("../../../QuitContainer/HBoxContainer/Quit")
theme_override_styles/focus = SubResource("StyleBoxEmpty_ekxnf")
text = "Appuyer sur"
flat = true
icon_alignment = 2
[node name="TextureRect" type="TextureRect" parent="GameInfos/Buttons/VBoxContainer/StartContainer/HBoxContainer" unique_id=544893863]
custom_minimum_size = Vector2(40, 40)
layout_mode = 2
size_flags_vertical = 3
texture = SubResource("Texture2D_wu84c")
expand_mode = 1
[node name="QuitContainer" type="PanelContainer" parent="GameInfos/Buttons/VBoxContainer" unique_id=24421836]
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxEmpty_bqqt6")
[node name="HBoxContainer" type="HBoxContainer" parent="GameInfos/Buttons/VBoxContainer/QuitContainer" unique_id=174332387]
layout_mode = 2
size_flags_horizontal = 4
[node name="Quit" type="Button" parent="GameInfos/Buttons/VBoxContainer/QuitContainer/HBoxContainer" unique_id=247251645]
unique_name_in_owner = true
layout_mode = 2
focus_neighbor_top = NodePath("../../../StartContainer/HBoxContainer/Start")
theme_override_styles/focus = SubResource("StyleBoxEmpty_ekxnf")
text = "Quitter le jeu"
flat = true
icon_alignment = 2
[node name="TextureRect" type="TextureRect" parent="GameInfos/Buttons/VBoxContainer/QuitContainer/HBoxContainer" unique_id=1821014740]
visible = false
custom_minimum_size = Vector2(40, 40)
layout_mode = 2
size_flags_vertical = 3
texture = SubResource("Texture2D_bqqt6")
expand_mode = 1
[node name="VersionLabel" type="Label" parent="." unique_id=673582892]
unique_name_in_owner = true
layout_mode = 1
anchors_preset = 2
anchor_top = 1.0
anchor_bottom = 1.0
offset_top = -23.0
offset_right = 40.0
grow_vertical = 0
[node name="MusicPlayer" type="AudioStreamPlayer" parent="." unique_id=1279071971]
unique_name_in_owner = true
[node name="TransitionRect" type="ColorRect" parent="." unique_id=389028330]
unique_name_in_owner = true
modulate = Color(1, 1, 1, 0)
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
color = Color(0, 0, 0, 1)
[connection signal="pressed" from="GameInfos/Buttons/VBoxContainer/StartContainer/HBoxContainer/Start" to="." method="_on_start_pressed"]
[connection signal="pressed" from="GameInfos/Buttons/VBoxContainer/QuitContainer/HBoxContainer/Quit" to="." method="_on_quit_pressed"]

View file

@ -0,0 +1,109 @@
[gd_scene format=3 uid="uid://bluq6da7tku3d"]
[ext_resource type="Script" uid="uid://cj37ns1ahfvhr" path="res://scripts/main_menu.gd" id="1_ekxnf"]
[ext_resource type="Script" uid="uid://7hglx6nfu063" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="2_bqqt6"]
[ext_resource type="Texture2D" uid="uid://d23fefvrd41re" path="res://assets/textures/background/0.png" id="2_wu84c"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_bqqt6"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_ekxnf"]
[sub_resource type="Texture2D" id="Texture2D_wu84c"]
resource_local_to_scene = false
resource_name = ""
script = ExtResource("2_bqqt6")
path = "ui_accept"
metadata/_custom_type_script = "uid://7hglx6nfu063"
[sub_resource type="LabelSettings" id="LabelSettings_3agn1"]
font_size = 64
[node name="MainMenu" type="Control" unique_id=1471802333]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_ekxnf")
progression_backgrounds = Array[Texture2D]([ExtResource("2_wu84c")])
[node name="Background" type="TextureRect" parent="." unique_id=545049912]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
expand_mode = 1
stretch_mode = 6
[node name="PanelContainer" type="PanelContainer" parent="." unique_id=1404024715]
layout_mode = 1
anchors_preset = 6
anchor_left = 1.0
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
offset_left = -571.0
offset_top = -323.5
offset_bottom = 323.5
grow_horizontal = 0
grow_vertical = 2
[node name="MarginContainer" type="MarginContainer" parent="." unique_id=1437260283]
layout_mode = 1
anchors_preset = 3
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = -130.0
offset_top = -67.0
grow_horizontal = 0
grow_vertical = 0
theme_override_constants/margin_right = 200
theme_override_constants/margin_bottom = 150
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer" unique_id=212717997]
layout_mode = 2
[node name="PanelContainer" type="PanelContainer" parent="MarginContainer/VBoxContainer" unique_id=455366583]
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxEmpty_bqqt6")
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer/PanelContainer" unique_id=980574030]
layout_mode = 2
[node name="Start" type="Button" parent="MarginContainer/VBoxContainer/PanelContainer/HBoxContainer" unique_id=1823965781]
unique_name_in_owner = true
layout_mode = 2
theme_override_styles/focus = SubResource("StyleBoxEmpty_ekxnf")
text = "Appuyer sur"
flat = true
icon_alignment = 2
[node name="TextureRect" type="TextureRect" parent="MarginContainer/VBoxContainer/PanelContainer/HBoxContainer" unique_id=544893863]
custom_minimum_size = Vector2(40, 40)
layout_mode = 2
size_flags_vertical = 3
texture = SubResource("Texture2D_wu84c")
expand_mode = 1
[node name="Label" type="Label" parent="." unique_id=745232782]
layout_mode = 1
anchors_preset = 6
anchor_left = 1.0
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
offset_left = -489.0
offset_top = -185.0
offset_right = -45.0
offset_bottom = -97.0
grow_horizontal = 0
grow_vertical = 2
text = "Tales of PKMN"
label_settings = SubResource("LabelSettings_3agn1")
[connection signal="pressed" from="MarginContainer/VBoxContainer/PanelContainer/HBoxContainer/Start" to="." method="_on_start_pressed"]

View file

@ -0,0 +1,109 @@
[gd_scene format=3 uid="uid://bluq6da7tku3d"]
[ext_resource type="Script" uid="uid://cj37ns1ahfvhr" path="res://scripts/main_menu.gd" id="1_ekxnf"]
[ext_resource type="Script" uid="uid://7hglx6nfu063" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="2_bqqt6"]
[ext_resource type="Texture2D" uid="uid://d23fefvrd41re" path="res://assets/textures/background/0.png" id="2_wu84c"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_bqqt6"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_ekxnf"]
[sub_resource type="Texture2D" id="Texture2D_wu84c"]
resource_local_to_scene = false
resource_name = ""
script = ExtResource("2_bqqt6")
path = "ui_accept"
metadata/_custom_type_script = "uid://7hglx6nfu063"
[sub_resource type="LabelSettings" id="LabelSettings_3agn1"]
font_size = 64
[node name="MainMenu" type="Control" unique_id=1471802333]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_ekxnf")
progression_backgrounds = Array[Texture2D]([ExtResource("2_wu84c")])
[node name="Background" type="TextureRect" parent="." unique_id=545049912]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
expand_mode = 1
stretch_mode = 6
[node name="PanelContainer" type="PanelContainer" parent="." unique_id=1404024715]
layout_mode = 1
anchors_preset = 6
anchor_left = 1.0
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
offset_left = -571.0
offset_top = -323.5
offset_bottom = 323.5
grow_horizontal = 0
grow_vertical = 2
[node name="MarginContainer" type="MarginContainer" parent="." unique_id=1437260283]
layout_mode = 1
anchors_preset = 3
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = -130.0
offset_top = -67.0
grow_horizontal = 0
grow_vertical = 0
theme_override_constants/margin_right = 200
theme_override_constants/margin_bottom = 150
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer" unique_id=212717997]
layout_mode = 2
[node name="PanelContainer" type="PanelContainer" parent="MarginContainer/VBoxContainer" unique_id=455366583]
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxEmpty_bqqt6")
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer/PanelContainer" unique_id=980574030]
layout_mode = 2
[node name="Start" type="Button" parent="MarginContainer/VBoxContainer/PanelContainer/HBoxContainer" unique_id=1823965781]
unique_name_in_owner = true
layout_mode = 2
theme_override_styles/focus = SubResource("StyleBoxEmpty_ekxnf")
text = "Appuyer sur"
flat = true
icon_alignment = 2
[node name="TextureRect" type="TextureRect" parent="MarginContainer/VBoxContainer/PanelContainer/HBoxContainer" unique_id=544893863]
custom_minimum_size = Vector2(40, 40)
layout_mode = 2
size_flags_vertical = 3
texture = SubResource("Texture2D_wu84c")
expand_mode = 1
[node name="Label" type="Label" parent="." unique_id=745232782]
layout_mode = 1
anchors_preset = 6
anchor_left = 1.0
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
offset_left = -489.0
offset_top = -185.0
offset_right = -45.0
offset_bottom = -97.0
grow_horizontal = 0
grow_vertical = 2
text = "Tales of PKMN"
label_settings = SubResource("LabelSettings_3agn1")
[connection signal="pressed" from="MarginContainer/VBoxContainer/PanelContainer/HBoxContainer/Start" to="." method="_on_start_pressed"]

View file

@ -0,0 +1,109 @@
[gd_scene format=3 uid="uid://bluq6da7tku3d"]
[ext_resource type="Script" uid="uid://cj37ns1ahfvhr" path="res://scripts/main_menu.gd" id="1_ekxnf"]
[ext_resource type="Script" uid="uid://7hglx6nfu063" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="2_bqqt6"]
[ext_resource type="Texture2D" uid="uid://d23fefvrd41re" path="res://assets/textures/background/0.png" id="2_wu84c"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_bqqt6"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_ekxnf"]
[sub_resource type="Texture2D" id="Texture2D_wu84c"]
resource_local_to_scene = false
resource_name = ""
script = ExtResource("2_bqqt6")
path = "ui_accept"
metadata/_custom_type_script = "uid://7hglx6nfu063"
[sub_resource type="LabelSettings" id="LabelSettings_3agn1"]
font_size = 64
[node name="MainMenu" type="Control" unique_id=1471802333]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_ekxnf")
progression_backgrounds = Array[Texture2D]([ExtResource("2_wu84c")])
[node name="Background" type="TextureRect" parent="." unique_id=545049912]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
expand_mode = 1
stretch_mode = 6
[node name="PanelContainer" type="PanelContainer" parent="." unique_id=1404024715]
layout_mode = 1
anchors_preset = 6
anchor_left = 1.0
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
offset_left = -571.0
offset_top = -323.5
offset_bottom = 323.5
grow_horizontal = 0
grow_vertical = 2
[node name="MarginContainer" type="MarginContainer" parent="." unique_id=1437260283]
layout_mode = 1
anchors_preset = 3
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = -130.0
offset_top = -67.0
grow_horizontal = 0
grow_vertical = 0
theme_override_constants/margin_right = 200
theme_override_constants/margin_bottom = 150
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer" unique_id=212717997]
layout_mode = 2
[node name="PanelContainer" type="PanelContainer" parent="MarginContainer/VBoxContainer" unique_id=455366583]
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxEmpty_bqqt6")
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer/PanelContainer" unique_id=980574030]
layout_mode = 2
[node name="Start" type="Button" parent="MarginContainer/VBoxContainer/PanelContainer/HBoxContainer" unique_id=1823965781]
unique_name_in_owner = true
layout_mode = 2
theme_override_styles/focus = SubResource("StyleBoxEmpty_ekxnf")
text = "Appuyer sur"
flat = true
icon_alignment = 2
[node name="TextureRect" type="TextureRect" parent="MarginContainer/VBoxContainer/PanelContainer/HBoxContainer" unique_id=544893863]
custom_minimum_size = Vector2(40, 40)
layout_mode = 2
size_flags_vertical = 3
texture = SubResource("Texture2D_wu84c")
expand_mode = 1
[node name="Label" type="Label" parent="." unique_id=745232782]
layout_mode = 1
anchors_preset = 6
anchor_left = 1.0
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
offset_left = -489.0
offset_top = -185.0
offset_right = -45.0
offset_bottom = -97.0
grow_horizontal = 0
grow_vertical = 2
text = "Tales of PKMN"
label_settings = SubResource("LabelSettings_3agn1")
[connection signal="pressed" from="MarginContainer/VBoxContainer/PanelContainer/HBoxContainer/Start" to="." method="_on_start_pressed"]

35
scenes/splash_screen.tscn Normal file
View file

@ -0,0 +1,35 @@
[gd_scene format=3 uid="uid://bi3r04lqth7iq"]
[ext_resource type="Script" uid="uid://ddxoruhyuxesc" path="res://scripts/splash_screen.gd" id="1_hsxvm"]
[ext_resource type="Texture2D" uid="uid://c28nuhy3im7y4" path="res://assets/textures/splash.png" id="2_4gp4q"]
[node name="SplashScreen" type="Control" unique_id=300161700]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_hsxvm")
[node name="AnimatedDisplay" type="TextureRect" parent="." unique_id=1433597692]
unique_name_in_owner = true
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("2_4gp4q")
expand_mode = 1
stretch_mode = 6
[node name="TransitionRect" type="ColorRect" parent="." unique_id=33546617]
unique_name_in_owner = true
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
color = Color(1, 1, 1, 0)

14
scripts/game_data.gd Normal file
View file

@ -0,0 +1,14 @@
extends Node
# Autoload : GameData
var story_progress : int = 0 # 0 = début, 1 = après 1er badge, 2 = après 2e badge, etc.
func save() -> void:
var config := ConfigFile.new()
config.set_value("progress", "story_progress", story_progress)
config.save("user://save.cfg")
func load_data() -> void:
var config := ConfigFile.new()
if config.load("user://save.cfg") == OK:
story_progress = config.get_value("progress", "story_progress", 0)

1
scripts/game_data.gd.uid Normal file
View file

@ -0,0 +1 @@
uid://d4beiel88cwc7

View file

@ -1,18 +1,77 @@
extends Node
@onready var Start: Button = %Start
@onready var Quit: Button = %Quit
@onready var background: TextureRect = %Background
@onready var music_player: AudioStreamPlayer = %MusicPlayer
@onready var transition_rect: ColorRect = %TransitionRect
@onready var version_label: Label = %VersionLabel
@onready var game_infos: Control = %GameInfos
@export var progression_backgrounds: Array[Texture2D] = []
@export var menu_music: AudioStream
@export var start_click_sound: AudioStream
const GAME_SCENE_PATH := "res://scenes/main.tscn"
const MUSIC_FADE_DURATION := 0.8
const SCREEN_FADE_DURATION := 0.6
var is_transitioning : bool = false
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
pass # Replace with function body.
update_background()
setup_version_label()
play_menu_music()
fade_in_game_infos()
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
Start.grab_focus()
pass
if !is_transitioning:
Start.grab_focus()
func update_background() -> void:
if progression_backgrounds.is_empty():
return
var stage : int = clampi(GameData.story_progress, 0, progression_backgrounds.size() - 1)
background.texture = progression_backgrounds[stage]
func setup_version_label() -> void:
var version : String = ProjectSettings.get_setting("application/config/version", "")
version_label.text = "v%s" % version if version != "" else ""
func play_menu_music() -> void:
if !menu_music: return
music_player.stream = menu_music
music_player.volume_db = -80.0
music_player.play()
var tween := create_tween()
tween.tween_property(music_player, "volume_db", 0.0, MUSIC_FADE_DURATION)
func fade_in_game_infos() -> void:
game_infos.modulate.a = 0.0
var tween := create_tween()
tween.tween_property(game_infos, "modulate:a", 1.0, 1.0)
func _on_start_pressed() -> void:
get_tree().change_scene_to_file("res://scenes/main.tscn")
pass # Replace with function body.
if is_transitioning: return
is_transitioning = true
play_click_sound()
start_transition_to(GAME_SCENE_PATH)
func play_click_sound() -> void:
UiAudio.play(start_click_sound)
func _on_quit_pressed() -> void:
get_tree().quit()
func start_transition_to(scene_path : String) -> void:
if music_player.playing:
var music_tween := create_tween()
music_tween.tween_property(music_player, "volume_db", -80.0, MUSIC_FADE_DURATION)
transition_rect.visible = true
transition_rect.modulate.a = 0.0
var screen_tween := create_tween()
screen_tween.tween_property(transition_rect, "modulate:a", 1.0, SCREEN_FADE_DURATION)
await screen_tween.finished
get_tree().change_scene_to_file(scene_path)

View file

@ -1,35 +1,61 @@
extends CanvasLayer
func _ready() -> void:
$".".visible = false
$AnimationPlayer.play("RESET")
@export var pause_sound : AudioStream
@export var resume_sound : AudioStream
@export var click_sound : AudioStream
func resume() -> void:
$".".visible = false
get_tree().paused = false
$AnimationPlayer.play_backwards("blur")
@onready var resume_button: Button = $PanelContainer/VBoxContainer/Resume
@onready var animation_player: AnimationPlayer = $AnimationPlayer
var is_transitioning : bool = false
func _ready() -> void:
process_mode = Node.PROCESS_MODE_ALWAYS
visible = false
animation_player.play("RESET")
func _unhandled_input(event: InputEvent) -> void:
if is_transitioning: return
if event.is_action_pressed("pause"):
if get_tree().paused:
resume()
else:
pause()
func pause() -> void:
$".".visible = true
get_tree().paused = true
$AnimationPlayer.play("blur")
$PanelContainer/VBoxContainer/Resume.grab_focus.call_deferred()
if is_transitioning: return
is_transitioning = true
func testEsc() -> void:
if Input.is_action_just_pressed("pause") and !get_tree().paused:
pause()
elif Input.is_action_just_pressed("pause") and get_tree().paused:
resume()
visible = true
get_tree().paused = true
UiAudio.play(pause_sound)
animation_player.play("blur")
await animation_player.animation_finished
resume_button.grab_focus()
is_transitioning = false
func resume() -> void:
if is_transitioning: return
is_transitioning = true
UiAudio.play(resume_sound)
animation_player.play_backwards("blur")
await animation_player.animation_finished
visible = false
get_tree().paused = false
is_transitioning = false
func _on_resume_pressed() -> void:
resume()
func _on_restart_pressed() -> void:
resume()
UiAudio.play(click_sound)
get_tree().paused = false
visible = false
get_tree().reload_current_scene()
func _on_quit_pressed() -> void:
UiAudio.play(click_sound)
get_tree().quit()
func _process(delta: float) -> void:
testEsc()

33
scripts/splash_screen.gd Normal file
View file

@ -0,0 +1,33 @@
extends Control
@onready var animated_display: TextureRect = %AnimatedDisplay
@onready var transition_rect: ColorRect = %TransitionRect
@export var main_menu_scene_path : String = "res://scenes/main_menu.tscn"
@export var splash_duration : float = 3.0
@export var allow_skip : bool = true
const SCREEN_FADE_DURATION := 0.6
var is_transitioning : bool = false
func _ready() -> void:
await get_tree().create_timer(splash_duration).timeout
go_to_main_menu()
func _unhandled_input(event: InputEvent) -> void:
# permet de passer le splash en appuyant sur une touche ou en cliquant
if allow_skip and !is_transitioning and event.is_pressed() and (event is InputEventKey or event is InputEventMouseButton):
go_to_main_menu()
func go_to_main_menu() -> void:
if is_transitioning: return
is_transitioning = true
transition_rect.visible = true
transition_rect.modulate.a = 0.0
var tween := create_tween()
tween.tween_property(transition_rect, "modulate:a", 1.0, SCREEN_FADE_DURATION)
await tween.finished
get_tree().change_scene_to_file(main_menu_scene_path)

View file

@ -0,0 +1 @@
uid://ddxoruhyuxesc

18
scripts/ui_audio.gd Normal file
View file

@ -0,0 +1,18 @@
extends Node
# Autoload : UiAudio
# Gère les sons d'interface (boutons, menus, pause...) indépendamment des scènes,
# pour qu'un son ne soit jamais coupé par un changement de scène.
@export var bus : StringName = &"SFX" # doit exister dans Audio Bus Layout, sinon utilise "Master"
func play(stream : AudioStream, volume_db : float = 0.0) -> void:
if !stream: return
var player := AudioStreamPlayer.new()
player.stream = stream
player.volume_db = volume_db
player.bus = bus if AudioServer.get_bus_index(bus) != -1 else &"Master"
add_child(player)
player.play()
player.finished.connect(player.queue_free)

1
scripts/ui_audio.gd.uid Normal file
View file

@ -0,0 +1 @@
uid://7e7fe2xk3aue