Aller au contenu principal
Voir
Mystery Gift — Etape 7 / 11Gérer la souris
1. Préparer les assets et les textes avant de créer une UI
2. Créer une scène UI
3. Créer une Composition
4. Créer un composant SpriteStack
5. Ajouter une couche de données avec PFM
6. Gérer les entrées clavier
7. Gérer la souris
8. Ajouter du texte multilingue
9. Utiliser les dialogues de confirmation
10. Créer des animations
11. Personnaliser GenericBase

Gérer la souris

Ce guide s'appuie sur le guide clavier : la scène a une liste de cadeaux navigable. Ici, on ajoute la gestion souris -- défilement, survol, clic sur les lignes, et les boutons ctrl du bas -- dans son propre fichier qui rouvre la classe de scène.

Principe

La gestion souris suit des conventions précises dans PSDK :

  • Elle vit dans un fichier séparé (004 Mouse.rb) qui rouvre la classe de scène.
  • update_mouse(moved) et la constante MOUSE_BUTTON_ACTIONS doivent être publics -- le framework les appelle depuis l'extérieur de la classe.
  • Le traitement se décompose en quatre étapes ordonnées : molette, survol, clic, boutons ctrl.
  • Les sous-composants possèdent leur détection de collision via simple_mouse_in? ; la scène route les événements, elle ne teste jamais les collisions de sprites directement.

Le fichier Mouse

update_mouse orchestre les quatre types d'interaction dans l'ordre. Chaque sous-méthode renvoie true si elle a consommé l'événement, ce qui stoppe le traitement suivant. Créez scripts/20 MysteryGift/003 GamePlay/004 Mouse.rb :

module GamePlay
# Mouse input handling for the Mystery Gift scene
class MysteryGift < BaseCleanUpdate::FrameBalanced
# Mouse button action mapping for ctrl buttons [A, X, Y, B]
MOUSE_BUTTON_ACTIONS = [:action_a, nil, nil, :action_b]

# Handle mouse input each frame
# @param moved [Boolean] whether the mouse moved this frame
def update_mouse(moved)
return false unless @composition.done?
return false if update_mouse_wheel
return false if moved && update_mouse_hover
return false if update_mouse_click

return update_ctrl_button_mouse
end

# Handle mouse wheel scrolling
# @return [Boolean] true if the wheel was used
def update_mouse_wheel
delta = Mouse.wheel
return false if delta == 0

Mouse.wheel = 0
play_cursor_se if @composition.move_selection(delta > 0 ? -1 : 1)
return true
end

# Handle mouse hover over gift rows
# @return [Boolean] true if hover changed the selection
def update_mouse_hover
hovered_index = @composition.find_hovered_row_index
return false if hovered_index.nil?
return false if hovered_index == @composition.selected_index

play_cursor_se
@composition.select_row(hovered_index)
return true
end

# Handle mouse clicks on gift rows
# @return [Boolean] true if a click was handled
def update_mouse_click
return false unless Mouse.trigger?(:LEFT)

hovered_index = @composition.find_hovered_row_index
return false if hovered_index.nil?

play_cursor_se
@composition.select_row(hovered_index)
return true
end

# Handle ctrl button mouse interaction
# @return [Boolean]
def update_ctrl_button_mouse
update_mouse_ctrl_buttons(@base_ui.ctrl, MOUSE_BUTTON_ACTIONS)
return false
end
end
end
  • update_mouse et MOUSE_BUTTON_ACTIONS sont publics -- le framework appelle update_mouse(Mouse.moved) à chaque frame.
  • @composition.done? bloque les entrées souris pendant les animations, exactement comme le clavier.
  • L'ordre compte : molette d'abord, puis survol (seulement si le curseur a bougé), puis clic, et enfin les boutons ctrl en dernier recours.
  • Mouse.wheel = 0 réinitialise la valeur après lecture. Cette remise à zéro est obligatoire : sans elle, la valeur persiste et la molette défile à chaque frame.
  • update_mouse_hover et update_mouse_click réutilisent @composition.find_hovered_row_index et @composition.select_row -- les mêmes méthodes de sélection que le clavier. Le survol compare avec @composition.selected_index pour ne se déclencher que quand la sélection change réellement.
  • update_ctrl_button_mouse délègue à update_mouse_ctrl_buttons, un helper hérité de GamePlay::Base. Il gère la surbrillance au survol, l'animation d'appui et déclenche l'action mappée au clic. MOUSE_BUTTON_ACTIONS associe les positions [A, X, Y, B] à des méthodes d'action ; nil saute une position. L'entrée A (:action_a) devient active une fois qu'on affiche le bouton A et qu'on ajoute action_a dans les guides i18n et dialogues.

Test de collision dans la Composition

La scène demande à la Composition « quelle ligne est survolée ? » ; la Composition demande à chaque ligne. Ajoutez cette méthode à scripts/20 MysteryGift/002 UI/999 Composition.rb :

# Find which row the mouse hovers
# @return [Integer, nil] the row index or nil
def find_hovered_row_index
return @rows.index { |row| row.visible && row.hovered? }
end

La scène lit aussi la sélection courante via la Composition, donc exposez-la -- ajoutez attr_reader :selected_index en haut de la classe :

class Composition < SpriteStack
# @return [Integer] current selected row index
attr_reader :selected_index
# ...
  • find_hovered_row_index renvoie l'index de la première ligne visible dont hovered? est vrai, ou nil. Chaque GiftRow possède son test de collision via simple_mouse_in? (ajouté dans le guide SpriteStack).
  • Cette délégation à trois couches -- la ligne possède hovered?, la Composition possède find_hovered_row_index, la scène route l'événement -- garde chaque couche concentrée sur sa responsabilité. La scène ne touche jamais directement la boîte de collision d'un sprite.

Essayez

Réclamez quelques codes, puis ouvrez la scène :

$user_data[:mystery_gift].claim('POTION50')
$user_data[:mystery_gift].claim('MASTERBALL')
GamePlay.open_mystery_gift

Passer la souris sur une ligne la met en surbrillance, la molette fait défiler la sélection, un clic gauche sélectionne une ligne, et cliquer le bouton « Quit » en bas ferme la scène.

Conclusion

  • update_mouse et MOUSE_BUTTON_ACTIONS doivent être publics -- le framework les appelle depuis l'extérieur.
  • Décomposez update_mouse en molette, survol, clic, boutons ctrl ; chaque étape renvoie true pour stopper la chaîne.
  • Réinitialisez toujours Mouse.wheel à 0 après lecture, sinon la molette défile sans fin.
  • Souris et clavier partagent les mêmes méthodes de Composition (select_row, move_selection, find_hovered_row_index).
  • Les sous-composants possèdent leur détection de collision via simple_mouse_in? ; la scène interroge la Composition, jamais les sprites directement.
  • MOUSE_BUTTON_ACTIONS associe les boutons ctrl [A, X, Y, B] à des méthodes d'action, avec nil pour sauter une position.