Pydiderot / pydiderotIDE

Environnement de dévelopement python adapté à l'enseignement et l'apprentissage de l'algorithmique.
MIT License
1 stars 2 forks source link

Proposition pour la bibliothèque graphique #25

Closed zebobs closed 5 years ago

zebobs commented 5 years ago

Je suis un nouveau sur Github alors je propose ici

def evenementtouches(touches):
    """
    Récupère les touches alphabétiques pressées parmi une liste et gère la fermeture de la fenetre.

    Arguments: Une liste de lettres, chiffres, signes au format string  

    Returns: Un dictionnaire des états des touches (1 pour pressé)
    """

    etatTouches = {}
    for touche in touches :
        etatTouches[touche] = 0

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            quit()
        elif event.type == pygame.KEYDOWN:
            event.unicode.encode('ascii','ignore')
            for touche in touches :
                if event.unicode == touche:
                    etatTouches[touche] = 1

    return etatTouches
zebobs commented 5 years ago

Une grosse amélioration qui gère en plus les flèches et la barre d'espace.

def evenementtouches(touches = False):
    """
    Récupère les touches flèches et la barre d'espace pressées et optionnelle parmi une liste de touches alphanumériques  et gère la fermeture de la fenetre.

    Arguments : (optionnel) Une liste de lettres, chiffres, signes alphanumériques au format string par exemple evenementtouches(['a','e'])

    Returns: Un dictionnaire des états des touches (1 pour pressé) haut, bas, droite, gauche, espace ainsi que l'état des touches indiqués optionnellement
             Un drapeau action dans le dictionnaire pour indiquer qu'une touche surveillée a été pressée
    """

    #Initialisation du dictionnaire de sortie
    etatTouches = {}

    etatTouches['action'] = 0
    etatTouches['haut'] = 0
    etatTouches['bas'] = 0
    etatTouches['droite'] = 0
    etatTouches['gauche'] = 0
    etatTouches['espace'] = 0

    if touches != False :
        for touche in touches :
            etatTouches[touche] = 0

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            quit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                etatTouches['haut'] = 1
                etatTouches['action'] =1
            elif event.key == pygame.K_DOWN:
                etatTouches['bas'] = 1
                etatTouches['action'] =1
            if event.key == pygame.K_RIGHT:
                etatTouches['droite'] = 1
                etatTouches['action'] =1
            elif event.key == pygame.K_LEFT:
                etatTouches['gauche'] = 1
                etatTouches['action'] =1 
            elif event.key == pygame.K_SPACE:
                etatTouches['espace'] = 1
                etatTouches['action'] =1   
            elif touches != False : 
                # event.key repère la position à partir d'un clavier QWERTY. On utilise donc event.unicode de pygame
                # Pour le test on transforme l'unicode en ASCII
                event.unicode.encode('ascii','ignore')
                for touche in touches :
                    if event.unicode == touche:
                        etatTouches[touche] = 1
                        etatTouches['action'] = 1
                        etatTouches['action'] =1

    return etatTouches
cspaier commented 5 years ago

Bien joué!

Une proposition d'amélioration:

def evenementtouches(touches = []):
    """
    Récupère les touches flèches et la barre d'espace pressées et optionnelle parmi une liste de touches alphanumériques  et gère la fermeture de la fenetre.

    Arguments :
        touches(list, optionnel): Une liste de lettres, chiffres, signes alphanumériques au format string par exemple `evenementtouches(['a','e'])`

    Returns:
        Une liste de touches pressées

    """

    #Initialisation de la liste de sortie
   liste_touches = []

    touches_de_base = {
        'haut': pygame.K_UP,
        'bas': pygame.K_DOWN,
        'gauche': pygame.K_LEFT,
        'droite': pygame.K_RIGHT,
        'espace': pygame.K_SPACE
    }

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            quit()
        if event.type == pygame.KEYDOWN:
            for k, v in touches_de_base.items():
                if event.key == v:
                    liste_touches.append(k)
                    break

            # event.key repère la position à partir d'un clavier QWERTY. On utilise donc event.unicode de pygame
            # Pour le test on transforme l'unicode en ASCII
            event.unicode.encode('ascii','ignore')
            for touche in touches :
                if event.unicode == touche:
                    liste_touches.append(touche)
                    break

    return liste_touches

exemple:

# On initialise les coordonnées du point 
x = 100
y = 100

# On créé la fenêtre graphique
creer_fenetre()
# On active le mode repeat de pygame
pygame.key.set_repeat(1)

# Trace un cercle au coordonnées (x,y)
trace_cercle(x, y)
# Boucle principale
while 1:
    # Il est important d’appeler  la fonction evenements() qui gère la fermeture de la fenêtre
    touches = evenementtouches()

    if touches: # test si touches est une liste vide
        # Efface le cercle
        trace_cercle(x, y, couleur=blanc)
        if 'haut' in touches:
            y = y - 1
        if 'bas' in touches:
            y = y + 1
        # Trace un cercle au coordonnées (x,y)
        trace_cercle(x, y)

    # Attend un dixième de secondes
    time.sleep(0.1)

Par rapport à github, si tu veux pas te prendre la tête avec les forks, pull request et autres, je peux te mettre collaborateur comme ca tu peux mettre le bazar directement dans le dépot.

Sinon tu fais des propositions dans des issues comme ici.

cspaier commented 5 years ago

Encore plus simple. Pas d'argument optionnel. On retourne la liste des touches pressés en ascii.

def evenementtouches():
    """
    Renvoie une liste de touches préssées.

    - Les caractères alphanumériques sont encodés en ascii : 'a', 'n', ';', ...
    - les fleches directionelles et la touches espaces ainsi: 'espace', 'haut', 'bas' 'droite', 'gauche'

    Returns:
        Une liste de touches préssées. Par exemple `['a', 'espace', 'bas']`

    """

    #Initialisation du dictionnaire de sortie
    touches = []

    touches_de_base = {
        'haut': pygame.K_UP,
        'bas': pygame.K_DOWN,
        'gauche': pygame.K_LEFT,
        'droite': pygame.K_RIGHT,
        'espace': pygame.K_SPACE
    }

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            quit()
        if event.type == pygame.KEYDOWN:
            for k, v in touches_de_base.items():
                if event.key == v:
                    touches.append(k)
                    break

            # event.key repère la position à partir d'un clavier QWERTY. On utilise donc event.unicode de pygame
            # Pour le test on transforme l'unicode en ASCII

            if event.unicode.encode('ascii','ignore'):
                touches.append(event.unicode)

    return touches
cspaier commented 5 years ago

On fait pareil avec la souris tant qu'on y est? On chope MOUSEBUTTONDOWN et MOUSEMOTION et on ajoute des click, souris_bouge à notre liste?

arf, la doc de pygame est horrible!

zebobs commented 5 years ago

Pas de break car il peut y avoir 2 touches comme haut et bas en même temps

Effectivement pour mouse Il faut un seul traitement evenement pour tout c'est plus simple

J'avais codé comme ça en pensant aux écouteurs en javascript (la logique des interruptions n'est pas la même dans notre cas)

J'apprends comme on parcourt les dictionnaires en python. C'est pas pareil qu'en javascript ou en php...

Je veux pas être collaborateur, je regarderai les forks plus tard.

cspaier commented 5 years ago

Pas de break car il peut y avoir 2 touches comme haut et bas en même temps

Bien vu!

J'apprends comme on parcourt les dictionnaires en python. C'est pas pareil qu'en javascript ou en php...

C'est propre python quand meme :)

Hésite pas si t'as des questions sur les forks.

cspaier commented 5 years ago

Bon, on est obligé d'utiliser un dict pour gérer la souris:

def evenements():
    """
    Récupère les évenements pygame gère la fermeture de la fenetre et retourne les évenements formatés.

    Renvoie un dictionaire d'évenements formaté comme suit:
    {'touche1': None, 'touche2':None, 'souris': [x,y], 'click': [x,y]}

    Les valeurs `None` pour les touches peuvent surprendre mais il est nécéssaire d'utiliser un dictionaire pour avoir les coordonnées
    éventuelles de la souris lors d'un click par exemple. L'importance est la présence de la cléf et la valeur associé est donc `None`.

    - Les caractères alphanumériques sont encodés en ascii (`'a'`, `'n'`, `';'`) et, si présent, leur valeur est `None`.
    - les touches spéciales ont les clefs `'espace'`, `'haut'`, `'bas'`, `'droite'`, `'gauche'` et, si présent, leur valeur est `None`.
    - Un clic avec le bouton gauche de la souris ajoute une clef `'clic'`. Sa valeur est une liste `[x, y]` des coordonées de la souris.
    - Un déplacement de la souris ajoute une clef `'souris'`. Sa valeur est une liste `[x, y]` des coordonées de la souris.

    """

    #Initialisation du dictionnaire de sortie
    evenements = {}

    touches_speciales = {
        'haut': pygame.K_UP,
        'bas': pygame.K_DOWN,
        'gauche': pygame.K_LEFT,
        'droite': pygame.K_RIGHT,
        'espace': pygame.K_SPACE
    }

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        if event.type == pygame.KEYDOWN:
            for c, v in touches_speciales.items():
                # On parcours le dictionnaire par clef valeur
                # Par exmple c = 'haut' et v = pygame.K_UP
                if event.key == v:
                    # L'important est simplement d'avoir la clef dans le dictionnaire.
                    # La valeur n'a pas d'importance et est donc None
                    evenements[c] = None

            # Si l'unicode peut être convertit en ascii, on ajoute la clef au dictionnaire sous unicode
            if event.unicode.encode('ascii', 'ignore'):
                evenements[event.unicode] = None

        # Gestion des evenements souris
        if event.type == pygame.MOUSEMOTION:
            evenements['souris'] = list(event.pos)
        if event.type == pygame.MOUSEBUTTONDOWN:
            evenements['clic'] = list(event.pos)

    return evenements

Je commence à documenter.

cspaier commented 5 years ago

And we are live!