Dans la plupart des cas, le gestionnaire d’entrée des API multimédia se suffit à lui-même, on boucle sur les évènements, on test si l’un d’eux correspond à une touche désirée et on exécute la fonction correspondante :
while App.GetEvent(Event): # Event Handler if Event.Type == sf.Event.Closed: App.Close() return if Event.Type == sf.Event.KeyPressed: if Event.Key.Code == sf.Key.Escape: Running = False Stop = True if Event.Key.Code == sf.Key.Left: Dir = -1 if Event.Key.Code == sf.Key.Right: Dir = 1 if Crash and Length<=1: Running = False if Event.Type == sf.Event.KeyReleased: if Event.Key.Code == sf.Key.Left and Dir == -1: Dir = 0 if Event.Key.Code == sf.Key.Right and Dir == 1: Dir = 0
C’est en fait une simplicité toute relative, les entrées sont codées en dur dans le code et le paralyse une fois le projet prenant un peu d’ampleur.% Pour rendre l’ensemble plus interactif je vous propose une classe qui permet d’ajouter et de supprimer des actions à la volée, en leurs assignant une fonction à exécuter. % C’est assez simple comme système et je l’utilise en fait pour tout ce qui peut générer des évènements (collisions par exemple). Chaque évènement est définis par un eventcode (MouseReleased, KeyPressed,…) et un keycode ( A, Right, Space,…) qu'on “attache” (bind) à une fonction, ainsi qu’un argument, pour réduire le nombre de fonctions nécessaires ( Move(x, y) au lieu de Move_Up, Move_Down, Move_Left, Move_Right par exemple).
self.fonctions = { type1: { key1:(fonction, argument),
key2:(fonction, argument)
}
type2: { keyx:(fonction, argument),
keyy:(fonction, argument)
}
}
Le code de la classe :
class kInput: """ Gère l'ajout/suppression/traitement des évènements d'entrées. Évènement stockés sous la forme : event[type][key] = (fonction, argument) """ def __init__(self, handler): self.the_handler = handler handler.the_input = self self.input = handler.the_display.window.GetInput() self.get_events = handler.the_display.window.GetEvent self.event = Event() self.fonctions = {} def AddEvent(self, type, key, fonction, argument): """ Ajoute une fonction en réaction à un évènement de touche. prépare le moteur à exécuter la [fonction]([argument]) pour l'évènement de type [type] et de touche [key]. """ if not self.fonctions.has_key(type): self.fonctions[type] = {} self.fonctions[type][key] = (fonction, argument) def DelEvent(self, type, key): """ Supprime l'écoute de l'évènement [type][key] """ self.fonctions[type].pop(key) def Scan(self): """ Inspecte les entrées pour exécuter les évènements mémorisés. A appeler à chaque tour de boucle. """ event = self.event #Allège le parcours fonc = self.fonctions while self.get_events(event): if fonc.has_key(event.Type): code = None #=== Récuperation du code === if event.Type == Event.KeyReleased or event.Type == Event.KeyPressed: code = event.Key.Code elif event.Type == Event.MouseButtonPressed or event.Type == Event.MouseButtonReleased: code = event.MouseButton.Button elif event.Type == Event.JoyButtonPressed or event.Type == Event.JoyButtonReleased: code = Event.JoyButton.Button elif event.Type == Event.JoyMoved: code = event.JoyMove.Axis #=== Execution de la bonne fonction === if fonc[event.Type].has_key(code): fonc[event.Type][code][0](event, fonc[event.Type][code][1])
En relisant le code, je me rends compte qu’il est assez facilement compréhensible, je ne l’explique donc pas de A à Z, mais si vous avez des questions ou des remarques, c’est avec plaisir que je répondrais à vos commentaires :) En stockant un tuple vous pouvez passer autant d'arguments que vous voulez (voir l'exemple en dessous). Pour les évènements sans keycode (comme les mousemove,…) il faut donner None au gestionnaire. Pour l’utilisation, il suffit ensuite de faire :
class Personnage: def __init__(self): instance_kinput.AddEvent(Event.KeyPressed, Key.Right, self.Moving, (1, 0)) instance_kinput.AddEvent(Event.KeyReleased, Key.Right, self.Moving, (-1, 0)) instance_kinput.AddEvent(Event.MouseButtonPressed, Mouse.Left, clic, None) instance_kinput.AddEvent(Event.MouseMoved, None, self.MouseMove, None) def Moving(self, event, dummy): self.movex += dummy[0] self.movey += dummy[1] def clic(self, event, dummy): print "clic" def MouseMove(self, event, dummy): print event.MouseMove.X, event.MouseMove.Y