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 constanteMOUSE_BUTTON_ACTIONSdoivent ê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_mouseetMOUSE_BUTTON_ACTIONSsont publics -- le framework appelleupdate_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 = 0ré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_hoveretupdate_mouse_clickréutilisent@composition.find_hovered_row_indexet@composition.select_row-- les mêmes méthodes de sélection que le clavier. Le survol compare avec@composition.selected_indexpour ne se déclencher que quand la sélection change réellement.update_ctrl_button_mousedélègue àupdate_mouse_ctrl_buttons, un helper hérité deGamePlay::Base. Il gère la surbrillance au survol, l'animation d'appui et déclenche l'action mappée au clic.MOUSE_BUTTON_ACTIONSassocie les positions[A, X, Y, B]à des méthodes d'action ;nilsaute une position. L'entrée A (:action_a) devient active une fois qu'on affiche le bouton A et qu'on ajouteaction_adans 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_indexrenvoie l'index de la première ligne visible donthovered?est vrai, ounil. Chaque GiftRow possède son test de collision viasimple_mouse_in?(ajouté dans le guide SpriteStack).- Cette délégation à trois couches -- la ligne possède
hovered?, la Composition possèdefind_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_mouseetMOUSE_BUTTON_ACTIONSdoivent être publics -- le framework les appelle depuis l'extérieur.- Décomposez
update_mouseen molette, survol, clic, boutons ctrl ; chaque étape renvoietruepour 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_ACTIONSassocie les boutons ctrl[A, X, Y, B]à des méthodes d'action, avecnilpour sauter une position.