dev #23

Merged
TheThomaas merged 55 commits from dev into main 2026-10-06 13:22:01 +00:00
3 changed files with 219 additions and 0 deletions
Showing only changes of commit 9efc974344 - Show all commits

208
game/ui/hud/team_hud.gd Normal file
View file

@ -0,0 +1,208 @@
class_name TeamHUD
extends Control
#element de HUD : barre de l'equipe en bas a gauche ; le pokemon selectionne est agrandi.
#la selection est stockee dans GameData (GameData.get_selected_pokemon()),
#pour que le lancer (ThrowState...) sache quel pokemon envoyer.
#
#usage : ajouter TeamHUD.new() a ton HUD (CanvasLayer), ou attacher ce script a un Control plein ecran.
const ControllerIconTextureScript = preload("res://addons/controller_icons/objects/ControllerIconTexture.gd")
#actions creees automatiquement si elles n'existent pas (croix gauche/droite, fleches du clavier)
@export var prev_action : StringName = &"hud_team_prev"
@export var next_action : StringName = &"hud_team_next"
@export var slot_size : float = 68.0
@export var selected_slot_size : float = 90.0
var _root_box : MarginContainer
var _name_label : Label
var _prev_icon : TextureRect
var _next_icon : TextureRect
var _slot_panels : Array[PanelContainer] = []
var _slot_styles : Array[StyleBoxFlat] = []
var _slot_sprites : Array[TextureRect] = []
var _slot_bars : Array[ProgressBar] = []
var _slot_fills : Array[StyleBoxFlat] = []
var _signatures : Array = [] #evite de reappliquer l'affichage d'un emplacement qui n'a pas change
func _ready() -> void:
_ensure_actions()
_build_ui()
#---------- actions d'entree ----------
func _ensure_actions() -> void:
_ensure_action(prev_action, [_joy_event(JOY_BUTTON_DPAD_LEFT), _key_event(KEY_LEFT)])
_ensure_action(next_action, [_joy_event(JOY_BUTTON_DPAD_RIGHT), _key_event(KEY_RIGHT)])
func _ensure_action(action : StringName, events : Array[InputEvent]) -> void:
if InputMap.has_action(action): return
InputMap.add_action(action)
for e in events: InputMap.action_add_event(action, e)
func _joy_event(button : JoyButton) -> InputEvent:
var e := InputEventJoypadButton.new()
e.button_index = button
return e
func _key_event(key : Key) -> InputEvent:
var e := InputEventKey.new()
e.physical_keycode = key
return e
func _unhandled_input(event : InputEvent) -> void:
#n'est pas appele quand le jeu est en pause (menu pause ouvert)
if event.is_action_pressed(prev_action):
GameData.cycle_selection(-1)
get_viewport().set_input_as_handled()
elif event.is_action_pressed(next_action):
GameData.cycle_selection(1)
get_viewport().set_input_as_handled()
#---------- construction ----------
func _build_ui() -> void:
set_anchors_preset(Control.PRESET_FULL_RECT)
mouse_filter = Control.MOUSE_FILTER_IGNORE
_root_box = MarginContainer.new()
_root_box.set_anchors_preset(Control.PRESET_BOTTOM_LEFT)
_root_box.grow_vertical = Control.GROW_DIRECTION_BEGIN #grandit vers le haut
_root_box.mouse_filter = Control.MOUSE_FILTER_IGNORE
for side in ["left", "bottom"]:
_root_box.add_theme_constant_override("margin_" + side, 32)
add_child(_root_box)
var column := VBoxContainer.new()
column.mouse_filter = Control.MOUSE_FILTER_IGNORE
column.add_theme_constant_override("separation", 6)
_root_box.add_child(column)
_name_label = Label.new()
_name_label.mouse_filter = Control.MOUSE_FILTER_IGNORE
_name_label.add_theme_font_size_override("font_size", 20)
_name_label.add_theme_constant_override("outline_size", 6)
_name_label.add_theme_color_override("font_outline_color", Color.BLACK)
column.add_child(_name_label)
var row := HBoxContainer.new()
row.mouse_filter = Control.MOUSE_FILTER_IGNORE
row.add_theme_constant_override("separation", 8)
column.add_child(row)
_prev_icon = _make_hint_icon(prev_action)
row.add_child(_prev_icon)
var slots_row := HBoxContainer.new()
slots_row.mouse_filter = Control.MOUSE_FILTER_IGNORE
slots_row.add_theme_constant_override("separation", 6)
row.add_child(slots_row)
for i in PokemonTeam.MAX_SIZE:
_add_slot(slots_row)
_signatures.append(null)
_next_icon = _make_hint_icon(next_action)
row.add_child(_next_icon)
func _add_slot(parent : Control) -> void:
var panel := PanelContainer.new()
panel.mouse_filter = Control.MOUSE_FILTER_IGNORE
panel.size_flags_vertical = Control.SIZE_SHRINK_END #les petits restent alignes en bas, le selectionne depasse vers le haut
var style := StyleBoxFlat.new()
style.bg_color = Color(0, 0, 0, 0.55)
style.set_corner_radius_all(10)
style.set_border_width_all(2)
style.set_content_margin_all(6)
panel.add_theme_stylebox_override("panel", style)
parent.add_child(panel)
var box := VBoxContainer.new()
box.mouse_filter = Control.MOUSE_FILTER_IGNORE
box.add_theme_constant_override("separation", 3)
panel.add_child(box)
var sprite := TextureRect.new()
sprite.mouse_filter = Control.MOUSE_FILTER_IGNORE
sprite.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
sprite.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
sprite.size_flags_vertical = Control.SIZE_EXPAND_FILL
box.add_child(sprite)
var bar := ProgressBar.new()
bar.mouse_filter = Control.MOUSE_FILTER_IGNORE
bar.show_percentage = false
bar.custom_minimum_size = Vector2(0, 6)
var fill := StyleBoxFlat.new()
fill.bg_color = Color(0.3, 0.8, 0.35)
bar.add_theme_stylebox_override("fill", fill)
box.add_child(bar)
_slot_panels.append(panel)
_slot_styles.append(style)
_slot_sprites.append(sprite)
_slot_bars.append(bar)
_slot_fills.append(fill)
func _make_hint_icon(action : StringName) -> TextureRect:
#icone de touche qui s'adapte au peripherique (addon controller_icons)
var tr := TextureRect.new()
tr.mouse_filter = Control.MOUSE_FILTER_IGNORE
var tex : Texture2D = ControllerIconTextureScript.new()
tex.set("path", String(action))
tr.texture = tex
tr.custom_minimum_size = Vector2(32, 32)
tr.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
tr.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
tr.size_flags_vertical = Control.SIZE_SHRINK_CENTER
return tr
#---------- mise a jour (l'equipe change souvent : on lit l'etat chaque frame, sans signaux a rebrancher) ----------
func _process(_delta : float) -> void:
var team : PokemonTeam = GameData.player_team
GameData.validate_selection()
var selected : int = GameData.selected_index
_root_box.visible = !team.is_empty()
var able_count : int = 0
for i in _slot_panels.size():
var p : PokemonInstance = team.get_pokemon(i)
if p == null:
_slot_panels[i].visible = false
_signatures[i] = null
continue
_slot_panels[i].visible = true
if !p.is_fainted(): able_count += 1
var sig : Array = [p.get_instance_id(), p.current_hp, p.get_max_hp(), i == selected]
if _signatures[i] == sig: continue
_signatures[i] = sig
_apply_slot(i, p, i == selected)
#les icones de touches n'apparaissent que s'il y a un choix a faire
_prev_icon.visible = able_count > 1
_next_icon.visible = able_count > 1
var selected_pokemon : PokemonInstance = team.get_pokemon(selected)
var label_text : String = ""
if selected_pokemon: label_text = "%s Niv.%d" % [selected_pokemon.get_display_name(), selected_pokemon.level]
if _name_label.text != label_text: _name_label.text = label_text
func _apply_slot(i : int, p : PokemonInstance, is_selected : bool) -> void:
var px : float = selected_slot_size if is_selected else slot_size
_slot_panels[i].custom_minimum_size = Vector2(px, px)
_slot_panels[i].modulate = Color(1.0, 0.55, 0.55) if p.is_fainted() else Color.WHITE
_slot_sprites[i].texture = p.species.get_menu_sprite(false)
_slot_styles[i].border_color = Color(1.0, 0.9, 0.4) if is_selected else Color(1, 1, 1, 0.25)
_slot_styles[i].set_border_width_all(3 if is_selected else 2)
var max_hp : int = p.get_max_hp()
_slot_bars[i].max_value = max_hp
_slot_bars[i].value = p.current_hp
var ratio : float = float(p.current_hp) / float(max_hp)
_slot_fills[i].bg_color = Color(0.3, 0.8, 0.35) if ratio > 0.5 else (Color(0.95, 0.7, 0.2) if ratio > 0.2 else Color(0.9, 0.25, 0.25))

View file

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

View file

@ -1,6 +1,7 @@
[gd_scene format=3 uid="uid://di22cs2qposdm"]
[ext_resource type="Script" uid="uid://7hglx6nfu063" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="1_4xhdt"]
[ext_resource type="Script" uid="uid://b3ddqgiawrh5c" path="res://game/ui/hud/team_hud.gd" id="2_lkjh2"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_uyiaf"]
@ -82,3 +83,12 @@ expand_mode = 1
layout_mode = 2
text = "Accepter"
label_settings = SubResource("LabelSettings_3agn1")
[node name="TeamHud" type="Control" parent="." unique_id=687093905]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("2_lkjh2")