IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Machine à états.


Sujet :

Python

  1. #1
    Membre habitué
    Homme Profil pro
    OOpps
    Inscrit en
    Mai 2015
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Landes (Aquitaine)

    Informations professionnelles :
    Activité : OOpps

    Informations forums :
    Inscription : Mai 2015
    Messages : 11
    Par défaut Machine à états.
    Grâce à l'aide de wiztricks dans une autre discussion sur ce même forum, j'ai pu identifier mes besoins pour le jeu que je développe : une machine à états.

    En fouillant un peu sur le forum, j'ai trouvé le code ci-dessous qui devrait permettre de piloter deux balles :
    - une bleue pilotée par les touches e, s, d, z.
    - une rouge pilotée par les touches up, down, right et left.

    Il remplit pour une large part sa mission : permettre à deux joueurs de piloter simultanément les deux balles depuis le même clavier. Mais il persiste quelques défauts, par exemple pour la boule rouge :
    - on enfonce la touche up et tout en laissant le up enfoncé, on appuie sur down : la balle qui jusque là montait, se met à descendre.
    - par contre, si on enfonce la touche down, et tout en maintenant la touche down enfoncée, on appuie sur la touche up : la balle ne change pas de direction et continue à descendre.

    Quelqu'un saurait-il m'expliquer la différence de traitement et les modifications à y apporter pour obtenir un comportement plus "logique".

    Voici le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
     
    from tkinter import *
     
    activekey = {}
    for k in ['e', 's', 'd', 'x', 'left', 'up', 'right', 'down']:
        activekey[k] = False
     
    def pressed(event):
        key = event.keysym.lower()              # lower : met en minuscules une chaine de caractères
        if key in activekey:
            activekey[key] = True
     
    def released(event):
        key = event.keysym.lower()
        if key in activekey:
            activekey[key] = False
     
    def animation():
        c1 = canvas.coords(player1)
        c2 = canvas.coords(player2)
        if activekey['e']:
            canvas.coords(player1, (c1[0], c1[1]-2, c1[2], c1[3]-2))
        if activekey['s']:
            canvas.coords(player1, (c1[0]-2, c1[1], c1[2]-2, c1[3]))
        if activekey['d']:
            canvas.coords(player1, (c1[0]+2, c1[1], c1[2]+2, c1[3]))
        if activekey['x']:
            canvas.coords(player1, (c1[0], c1[1]+2, c1[2], c1[3]+2))
        if activekey['up']:
            canvas.coords(player2, (c2[0], c2[1]-2, c2[2], c2[3]-2))
        if activekey['left']:
            canvas.coords(player2, (c2[0]-2, c2[1], c2[2]-2, c2[3]))
        if activekey['right']:
            canvas.coords(player2, (c2[0]+2, c2[1], c2[2]+2, c2[3]))
        if activekey['down']:
            canvas.coords(player2, (c2[0], c2[1]+2, c2[2], c2[3]+2))
        root.after(10, animation)
     
    root = Tk()
    canvas = Canvas(width=500, height=500)
    canvas.pack()
    player1 = canvas.create_oval(20, 20, 70, 70, width=2, fill='blue')
    player2 = canvas.create_oval(420, 420, 470, 470, width=2, fill='red')
    root.bind("<KeyPress>", pressed)
    root.bind("<KeyRelease>", released)
    animation()
    root.mainloop()

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 712
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 712
    Par défaut
    Salut,
    Salut,

    Citation Envoyé par Piittt Voir le message
    Quelqu'un saurait-il m'expliquer la différence de traitement et les modifications à y apporter pour obtenir un comportement plus "logique".
    Virez tout ce qui ne concerne pas le problème i.e. garder juste ce qu'il faut pour reproduire l'histoire du "up", "down".
    Puis vous prenez un papier et un crayon et vous essayez de tracer sur une feuille ce que fait votre code.
    indice: le problème vient des "if".

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre habitué
    Homme Profil pro
    OOpps
    Inscrit en
    Mai 2015
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Landes (Aquitaine)

    Informations professionnelles :
    Activité : OOpps

    Informations forums :
    Inscription : Mai 2015
    Messages : 11
    Par défaut
    Effectivement, ce n'était pas bien sorcier ... autant pour moi ...

    Par contre la solution que j'ai trouvée conserve les if, tu avais une meilleure idée en tête ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    def animation():    
        if activekey['e']:
            c1 = canvas.coords(player1)
            canvas.coords(player1, (c1[0], c1[1]-2, c1[2], c1[3]-2))
        if activekey['s']:
            c1 = canvas.coords(player1)
            canvas.coords(player1, (c1[0]-2, c1[1], c1[2]-2, c1[3]))
        if activekey['d']:
            c1 = canvas.coords(player1)
            canvas.coords(player1, (c1[0]+2, c1[1], c1[2]+2, c1[3]))
        if activekey['x']:
            c1 = canvas.coords(player1)
            canvas.coords(player1, (c1[0], c1[1]+2, c1[2], c1[3]+2))
        if activekey['up']:
            c2 = canvas.coords(player2)
            canvas.coords(player2, (c2[0], c2[1]-2, c2[2], c2[3]-2))
        if activekey['left']:
            c2 = canvas.coords(player2)
            canvas.coords(player2, (c2[0]-2, c2[1], c2[2]-2, c2[3]))
        if activekey['right']:
            c2 = canvas.coords(player2)
            canvas.coords(player2, (c2[0]+2, c2[1], c2[2]+2, c2[3]))
        if activekey['down']:
            c2 = canvas.coords(player2)
            canvas.coords(player2, (c2[0], c2[1]+2, c2[2], c2[3]+2))
        root.after(10, animation)

  4. #4
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 712
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 712
    Par défaut
    Salut,

    J'utiliserais plutôt canvas.move:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        if activekey['e']:
             canvas.move(player1, 0, -2)
    pour le reste, je ne suis pas inspiré.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 712
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 712
    Par défaut
    Salut,

    Juste pour le fun:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    from tkinter import *
     
    delta_moves = {
        'left' : (-2, 0),
        'right': (2, 0),
        'up' : (0, -2),
        'down': (0, 2),
        }
     
     
    player1 = {
        'iid' : None,
        'motions': dict(),
        'dxy' : (0, 0),
        'keymap' : { 
            'e' : 'left',
            's': 'right',
            'd' : 'up',
            'x': 'down',
            }
        }
     
    player2 = {
        'iid' : None,
        'motions': dict(),
        'dxy' : (0, 0),
        'keymap' : {
            'Left' : 'left',
            'Right': 'right',
            'Up' : 'up',
            'Down': 'down',
            },
        }
     
    players = [ player1, player2 ]
     
    def pressed(keysym):
        for player in players:
            key = player['keymap'].get(keysym)
            if key is not None and key not in player['motions']:
                player['motions'][key] = None
                player['dxy'] = tuple(x + y for x, y in zip(player['dxy'], delta_moves[key]))
     
    def released(keysym):
        for player in players:
            key = player['keymap'].get(keysym)
            if key is not None:
                del player['motions'][key]
                player['dxy'] = tuple(x - y for x, y in zip(player['dxy'], delta_moves[key]))
     
    def animation():
        for player in players:
            if player['dxy'] != (0, 0):
                canvas.move(player['iid'], *player['dxy'])
     
        root.after(10, animation)
     
    root = Tk()
    canvas = Canvas(width=500, height=500)
    canvas.pack()
     
    player1['iid'] = canvas.create_oval(20, 20, 70, 70, width=2, fill='blue')
    player2['iid'] = canvas.create_oval(420, 420, 470, 470, width=2, fill='red')
     
    root.bind("<KeyPress>",lambda e: pressed(e.keysym))
    root.bind("<KeyRelease>", lambda e: released(e.keysym))
    animation()
    root.mainloop()
    Mais, pour rendre animation aussi court:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def animation():
        for player in players:
            if player['dxy'] != (0, 0):
                canvas.move(player['iid'], *player['dxy'])
     
        root.after(10, animation)
    Il faut travailler côté structures de données et au plus on va dans cette direction au plus les "class" s'imposent.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

Discussions similaires

  1. Réponses: 5
    Dernier message: 22/07/2008, 09h06
  2. [Etat] Design pattern pour présenter une machine à état
    Par solawe dans le forum Design Patterns
    Réponses: 7
    Dernier message: 15/07/2008, 15h58
  3. machine à état xml
    Par bassi44 dans le forum XML/XSL et SOAP
    Réponses: 3
    Dernier message: 19/02/2008, 08h58
  4. machine à état en java
    Par bassi44 dans le forum Général Java
    Réponses: 2
    Dernier message: 28/01/2008, 12h53
  5. Machine à états finis en C++
    Par mb3575 dans le forum C++
    Réponses: 10
    Dernier message: 24/04/2007, 10h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo