2 votes

Interprétation des touches enfoncées

Je suis en train de construire un rover Raspberry Pi écrit en Python et je cherche à contrôler le rover via SSH. Ainsi, je voudrais exécuter le script et ensuite vouloir que le rover se déplace dans les directions que je lui indique en temps réel, comme une voiture RC (pensez aux touches haut, bas, gauche, droite).

J'ai lu en ligne qu'une des possibilités pourrait être d'utiliser la fonction pygame.key.get_pressed(), mais cela ne fonctionne pas dans mon shell. Lorsque j'exécute cette commande dans mon shell python raspberry pi, je reçois seulement un tuple de zéros qui expire après une fraction de seconde.

Voici mon code :

speed = input('À quelle vitesse voulez-vous que le rover aille? Donnez une valeur inférieure à 1: ')

while True:
    keys = pygame.key.get_pressed()  #vérifier les touches pressées
    if keys == True:
        if keys[pygame.K_UP]:
            fwd(speed)
        if keys[pygame.K_DOWN]:
            bwd(speed)
    if keys == False:
        MS.motor1off
        MS.motor2off     

avec fwd et bwd étant des fonctions qui activent les moteurs dans les directions avant et arrière.

Lorsque j'exécute le script, il parcourt la boucle correctement, mais les moteurs ne répondent pas à la touche maintenue. Lorsque j'ai ajouté une instruction print, j'ai remarqué que cela n'était pas non plus imprimé dans la console.

Est-ce que quelqu'un a une idée de comment procéder avec cela, s'il vous plaît?

2voto

WurzelseppQX Points 460

Je ne suis pas un expert en pygame et je n'ai jamais utilisé la méthode key.get_pressed(). J'utilise event.get() qui fonctionne bien. Voici un exemple minimum du code que j'utilise:

import pygame

pygame.init()

WINDOW_WIDTH = 250
WINDOW_HEIGHT = 120

pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))

while True:
    for event in pygame.event.get():        
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_w:
                print('fonctionne!')

Vous devez vous assurer d'initialiser pygame et de créer une fenêtre ET que la fenêtre soit au premier plan. Alors ça marchera. Si ce n'est pas pratique pour vous, alors vous devrez vous connecter à l'événement de pression de touche de votre clavier pour obtenir la pression de touche globale, peu importe la fenêtre qui est au premier plan.

J'espère que cela vous aidera.

2voto

skrx Points 13884

pygame.key.get_pressed() retourne une liste de booléens qui représentent l'état des touches. Une liste ne peut jamais être égale à True ou False donc le code dans vos clauses if keys == True: et if keys == False: ne sera jamais exécuté.

Donc tout simplement supprimez ces clauses if et utilisez une clause else après if keys[pygame.K_UP]: ou les deux instructions pour éteindre le moteur (pas sûr de ce que vous voulez exactement faire).

while True:
    # Vous devez faire un appel à la file d'événements à chaque trame sinon la fenêtre va "freeze".
    pygame.event.pump()

    keys = pygame.key.get_pressed()
    if keys[pygame.K_UP]:
        fwd(speed)
    elif keys[pygame.K_DOWN]:
        bwd(speed)
    else:  # Aucune touche pressée.
        MS.motor1off
        MS.motor2off

En passant, si motor1off et motor2off sont des méthodes, vous voulez probablement les appeler : MS.motor1off().

0voto

Black Thunder Points 2255

De @WurzelseppQX's code , j'ai créé un nouveau code qui imprime un texte aussi longtemps que le bouton est maintenu enfoncé et s'arrêtera d'imprimer lorsque le bouton est relâché. Voici le code:

import pygame  #importation de pygame

pygame.init() #initialisation de pygame

largeur = 100 # largeur de la fenêtre
hauteur = 100 #hauteur de la fenêtre

pygame.display.set_mode((largeur, hauteur)) # définir les dimensions

while True:
    tbreak = False # pour interrompre deux boucles
    for event in pygame.event.get():   #obtenir les événements     
        if event.type == pygame.KEYDOWN: #voir si un bouton est pressé
            if event.key == pygame.K_w: # si le bouton est 'W' alors
                while True: # création d'une boucle
                    print("Touche 'W' enfoncée") 
                    ev = pygame.event.get() #obtention d'événements pour voir si l'utilisateur vient de relâcher la touche
                    for e in ev: #parcours des événements
                        if e.type == pygame.KEYUP: #si une touche est relâchée
                            #Vous pouvez également définir des touches spécifiques
                            tbreak = True #pour interrompre la boucle extérieure
                            break #interrompre la boucle interne
                    if tbreak == True:break #interrompre

Maintenant, le code ci-dessus bloque le reste de votre jeu lorsque le bouton est pressé. Si vous ne voulez pas que votre code fasse ça, utilisez le code suivant:

global topass
topass = 0
def on_press(): #quoi faire lorsqu'on presse le bouton
    global topass
    print("Touche 'W' enfoncée")
    topass = 1
while True:
    events = pygame.event.get()
    if len(events) == 0 and topass == 1:on_press()
    for event in events:
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_w or topass == 1:
                on_press()
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_w:
                topass = 0

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X