Bon j'avais déjà écrit ce post, mais en enregistrant une modification, il a été prit pour du spam et s'est fait supprimer ... -_-'
J'ai pas envie de tout réécrire donc cette fois-ci je vais pas y aller par 4 chemins.
J'ai besoin d'aide car :
- il faudrait pouvoir effectuer une action tant que j'appuie sur une touche. (j'y reviens après)
- Et j'aimerai aussi que quand j'appuie sur plusieurs touches qui contrôlent chacune un moteur, qu'elles fassent chacune leur taf en même temps. (j'y reviens aussi après)
Voici le code :
import time
import pygame
from pygame.locals import *
from poppy.creatures import *
from poppy.creatures import PoppyTorso
poppy = PoppyTorso(simulator='vrep')
pygame.init()
ecran = pygame.display.set_mode((50, 50))
continuer = True
while continuer:
for event in pygame.event.get():
if event.type == KEYDOWN :
if event.key == K_UP :
print("Haut")
poppy.r_shoulder_x.goto_position(-90)
if event.key == K_LEFT :
print("Gauche")
if event.key == K_RIGHT :
print("Droite")
if event.key == K_DOWN :
print("Bas")
if event.key == K_ESCAPE :
print("Fin du programme")
continuer = False
pygame.quit()
Donc ici poppy.r_shoulder_x.goto_position(-90)permet au robot Poppyde bouger le moteur r_shoulder_xjusqu'à l'angle-90°.
Ce que je voudrai c'est que tant que je reste appuyé sur une touche, le moteur change de degré petit à petit, comme ça on pourrait le faire bouger jusqu'où l'on veut. J'ai essayé avec la fonction pygame.key.set_repeat(500,500) mais je ne sais pas où la placer pour que ça fonctionne. J'ai aussi pensé à créer une fonction (def je crois ?) qui changerai de quelques degrés l'angle du moteur à chaque fois de façon régulière toujours le tant que la touche est enfoncée bien sûr.
J'aimerai aussi que si j'appuie sur plusieurs touches, celles-ci agissent normalement mais en même temps. Je pense pas avoir besoin d'en dire plus, c'est explicite, mais c'est dur.
Un exemple de ce que je voudrai pouvoir faire :
Disons que si j'appuie sur left le bras gauche se lève de 5° par seconde jusqu'à ce que je relâche la pression. Et si j'appuie sur right le bras droit se lève de 5° par seconde jusqu'à ce que je relâche la pression. Et bien j'aimerai déjà pouvoir faire ça, et en plus, de pouvoir appuyer sur left et right en même temps et que ça fonctionne.
Voilà désolé si j'ai pas expliqué assez, j'ai du oublier des trucs comparé à l'ancien post supprimé.
Quelques infos :
système -> Windows 64bit
jeu d'instructions -> 32bit
distribution -> 6.1.7601
version python -> 3.4.5
Merci d'avance pour votre aide, et le temps que ça vous prendra !
Administrateur du Discord Monster Hunter dédié aux anciens opus émulés par RomStation.
Merci pour la réponse, j'ai donc essayé de mettre pygame.key.set_repeat(500,500) au bon endroit, mais ça ne semble pas fonctionner.
J'ai même essayé avec une boucle WHILE, mais impossible de l'arrêter...
Voici le code :
import time
import pygame
from pygame.locals import *
pygame.init()
ecran = pygame.display.set_mode((50, 50))
pygame.key.set_repeat(500,500)
continuer = True
while continuer:
for event in pygame.event.get():
if event.type == KEYDOWN :
if event.key == K_UP :
while event.key == K_UP:
print("Haut")
if event.type == KEYUP :
break
if event.key == K_LEFT :
print("Gauche")
if event.key == K_RIGHT :
print("Droite")
if event.key == K_DOWN :
print("Bas")
if event.key == K_ESCAPE :
print("Fin du programme")
continuer = False
pygame.quit()
Sinon j'ai commencé à créer une classe avec des fonctions, je me renseigne, mais tant que je n'arrive pas à répéter une action tant que je maintiens la touche ça ne sert à rien.
Donc je suis encore bloqué.
Administrateur du Discord Monster Hunter dédié aux anciens opus émulés par RomStation.
Désolé, j'étais occupé. Non il ne faut pas de boucle WHILE.
Je viens de comprendre votre problème. Vous cherchez à appuyer sur plusieurs touche en même temps.
Il existe une autre méthode. Sans la boucle FOR d'événements.
Il suffit de:
while continuer:
for event in pygame.event.get():
if event.type == KEYDOWN :
if event.key == K_ESCAPE :
print("Fin du programme")
continuer = False
## Retourne une liste d'événements.
keyboard = pygame.key.get_pressed()
if keyboard[K_UP]:
print('HAUT')
if keyboard[K_DOWN]:
print('BAS')
if keyboard[K_LEFT]:
print('GAUCHE')
if keyboard[K_RIGHT]:
print('DROITE')
Sauf qu'il n'y aura aucun délais. (Comme le 1 seconde)... Les servomoteurs (du robot), risque de capoter et d'être endommagé.
Il faudra que vous essayez de créer une sorte de décompte (un compteur) . Probablement avec pygame.time.get_ticks() .
Quelque chose comme ceci:
compteur_start = pygame.time.get_ticks()
while continuer:
keyboard = pygame.key.get_pressed()
if ( (compteur_start - pygame.time.get_ticks()) / 1000) % 1 == 0:
if keyboard[K_UP]:
print('HAUT')
if keyboard[K_DOWN]:
print('BAS')
Le get_ticks() vous donne le temps en milliseconde, on divise donc, par 1000 pour convertir en seconde. Ensuite, on fait un modulo 1 pour savoir, si c'est un multiple de 1.
(Si vous connaissez pas le modulo, je vous invite à regarder la documentation et à créer quelque exemple.)
On s'entend que c'est assez moche. Il existe d'autre moyen, mais le principe est là.
Merci pour ta réponse, finalement ce matin j'ai réussi à faire fonctionner mon algorithme avec le key repeat !
Donc ça c'est fait, maintenant je bloque sur ma class, je voudrais que quand j'appelle une fonction, celle ci ajoute par exemple 5 à une valeur.
Je m'explique, disons que a = 0
J'appelle ma fonction et donc a = 5
Je rappelle ma fonction et a = 10
et ainsi de suite...
Sauf que là, j'appelle ma fonction j'ai a = 5 puis a = 5 puis a = 5, elle garde le 0, je ne vois pas comment faire, ça doit être tout bête mais je manque de logique j'imagine ...
class moteur:
#gestion de l'angle des moteurs
def __init__(): #initialisation du moteur pour avoir l'angle à 0
angle = 0
def change(): #ajouter 5 à l'angle
angle += 5
return a
moteur.__init__() #on met l'angle à 0
moteur.change() #on ajoute 5 à l'angle
Mais il y a un problème dans ma fonction change, car "local variable 'angle' referenced before assignment", j'imagine que c'est parce que je lui dis de faire angle = angle + 5 alors qu'il n'y a pas de variable angle DANS la fonction, ce qui est logique car sinon elle commencerait toujours à 0...
Donc là je vois pas comment faire. :/
Administrateur du Discord Monster Hunter dédié aux anciens opus émulés par RomStation.
class moteur:
def __init__(self):
self.angle = 0
def change(self):
self.angle += 5
m = moteur() ## On instancie la classe (Elle exécute __init__() tout seul)
print(m.angle) ## self.angle vaut 0
m.change() ## On vient d'incrémenter l'angle par la méthode(fonction)
print(m.angle) ## self.angle vaut 5
Dans le fond, une classe est simplement des variables (attributs) et des méthodes (fonctions), qui communiquent tous entre-elles grâce au self.
Cela permet de créer un ensemble de variables/fonctions, pour tout ce qui est en rapport avec un objet (dans votre cas, le moteur). Ce qui veut dire, que tout ce qui concerne le moteur, il y aura tous les variables comme l'angle, la vitesse, etc. On appel cela un objet. (Je crois)
Cela permet aussi, de pas utiliser global partout dans vos fonctions. Ce qui rend votre code, plus lisible sans global.
C'est comme si vous aviez ceci:
angle = 0
def change():
global angle ## Pour modifie une variable externe à la fonction, on met global.
angle += 5
print(angle) ## vaut 0
change()
print(angle) ## vaut 5
Je connais pas tout la théorie, donc il se peut que j'utilise pas les bons mots.
Je vous invite à lire de la documentation sur les classes. Cela vous sera très pratique.
Le code peut encore être optimisé, mais tout fonctionne comme prévu donc ça me va !
#importation de tout
import time
import pygame
#appel de ce dont j'ai besoin
from pygame.locals import *
from poppy.creatures import *
from poppy.creatures import PoppyTorso
#démarrage de pygame
poppy = PoppyTorso(simulator='vrep')
pygame.init()
ecran = pygame.display.set_mode((500,500))
pygame.key.set_repeat(10,40)
class moteur_shouldery: #Rotation des épaules
def __init__(self):
self.angle = 0
def changepos(self): #change la valeur en positif
self.angle += 2
def changeneg(self): #change la valeur en négatif
self.angle -= 2
class moteur_elbow: #les coudes vers haut/bas
def __init__(self):
self.angle = 0
def changepos(self):
self.angle += 2
def changeneg(self):
self.angle -= 2
class moteur_absz: #Buste de droite à gauche
def __init__(self):
self.angle = 0
def changepos(self):
self.angle += 2
def changeneg(self):
self.angle -= 2
class moteur_arm: #Rotation des bras
def __init__(self):
self.anglea = 0
self.angleb = 0
def change1(self): #Un moteur dans un sens, l'autre dans l'autre
self.anglea += 2
self.angleb -= 2
def change2(self): #Pareil ici, mais à l'inverse
self.anglea -= 2
self.angleb += 2
class moteur_shoulderx: #Lever/baisser épaule
def __init__(self):
self.anglea = 0
self.angleb = 0
def change1(self):
self.anglea += 2
self.angleb -= 2
def change2(self):
self.anglea -= 2
self.angleb += 2
#initiation des moteurs
msy = moteur_shouldery()
me = moteur_elbow()
maz = moteur_absz()
ma = moteur_arm()
msx = moteur_shoulderx()
#lancement de l'algorithme
continuer = True
while continuer:
for event in pygame.event.get():
if event.type == KEYDOWN : #récupère les touches enfoncées
#Gère le moteur épaule Y
if pygame.key.get_pressed()[pygame.K_w]:
msy.changeneg()
poppy.r_shoulder_y.goto_position(msy.angle,1)
poppy.l_shoulder_y.goto_position(msy.angle,1)
if pygame.key.get_pressed()[pygame.K_s]:
msy.changepos()
poppy.r_shoulder_y.goto_position(msy.angle,1)
poppy.l_shoulder_y.goto_position(msy.angle,1)
#gère le moteur coude
if pygame.key.get_pressed()[pygame.K_UP]:
me.changeneg()
poppy.r_elbow_y.goto_position(me.angle,1)
poppy.l_elbow_y.goto_position(me.angle,1)
if pygame.key.get_pressed()[pygame.K_DOWN]:
me.changepos()
poppy.r_elbow_y.goto_position(me.angle,1)
poppy.l_elbow_y.goto_position(me.angle,1)
#Gère le buste de gauche à droite
if pygame.key.get_pressed()[pygame.K_RIGHT]:
maz.changeneg()
poppy.abs_z.goto_position(maz.angle,1)
if pygame.key.get_pressed()[pygame.K_LEFT]:
maz.changepos()
poppy.abs_z.goto_position(maz.angle,1)
#gère le moteur bras
if pygame.key.get_pressed()[pygame.K_q]:
ma.change1()
poppy.r_arm_z.goto_position(ma.anglea,1)
poppy.l_arm_z.goto_position(ma.angleb,1)
if pygame.key.get_pressed()[pygame.K_e]:
ma.change2()
poppy.r_arm_z.goto_position(ma.anglea,1)
poppy.l_arm_z.goto_position(ma.angleb,1)
#gère le moteur épaule X
if pygame.key.get_pressed()[pygame.K_a]:
msx.change1()
poppy.r_shoulder_x.goto_position(msx.anglea,1)
poppy.l_shoulder_x.goto_position(msx.angleb,1)
if pygame.key.get_pressed()[pygame.K_d]:
msx.change2()
poppy.r_shoulder_x.goto_position(msx.anglea,1)
poppy.l_shoulder_x.goto_position(msx.angleb,1)
#Remet les moteurs à 0 + réinitialise les angles
if pygame.key.get_pressed()[pygame.K_0]:
print("Remise à 0 des moteurs, ne touchez à rien svp !")
poppy.head_y.goto_position(0,2,wait=True)
poppy.head_z.goto_position(0,2,wait=True)
poppy.bust_x.goto_position(0,2,wait=True)
poppy.bust_y.goto_position(0,2,wait=True)
poppy.abs_z.goto_position(0,4,wait=True)
maz = moteur_absz()
poppy.r_arm_z.goto_position(0,2,wait=True)
poppy.l_arm_z.goto_position(0,2,wait=True)
ma = moteur_arm()
poppy.r_elbow_y.goto_position(0,2,wait=True)
poppy.l_elbow_y.goto_position(0,2,wait=True)
me = moteur_elbow()
poppy.r_shoulder_x.goto_position(0,2,wait=True)
poppy.l_shoulder_x.goto_position(0,2,wait=True)
msx = moteur_shoulderx()
poppy.r_shoulder_y.goto_position(0,2,wait=True)
poppy.l_shoulder_y.goto_position(0,2,wait=True)
msy = moteur_shouldery()
print("Moteur en position normale")
#Commande dab !
if pygame.key.get_pressed()[pygame.K_9]:
print("dab !")
poppy.r_shoulder_x.goto_position(-90,1)
poppy.r_elbow_y.goto_position(-50,1)
poppy.head_z.goto_position(-70,1)
poppy.head_y.goto_position(20,1)
poppy.l_shoulder_x.goto_position(90,1)
poppy.l_elbow_y.goto_position(90,1)
poppy.bust_x.goto_position(20,1)
poppy.bust_y.goto_position(30,1)
#Fermeture de la boucle
if pygame.key.get_pressed()[pygame.K_ESCAPE]:
print("Fin du programme !")
continuer = False
print("Veuillez arrêtez la simulation et redémmarez le noyau.")
print("A bientôt !")
pygame.quit()
Administrateur du Discord Monster Hunter dédié aux anciens opus émulés par RomStation.
Tu peux réduire les classes en faisant un truc comme ça :
CLASSE Moteur:
Construire(lui, type_moteur:str):
# les propriétés qu'il faut
Les MÉTHODES:
CHANGE1(lui):
SI lui.type_moteur est "épauleY":
# manipuler épauleY
Mais, à regarder un peu mieux ton code, les méthodes sont quasi équivalentes. Tu pourrais mettre dans 1 liste les articulations qui ont les mêmes méthodes et tu fais un if objet DANS cette liste Faire les manips.
La seule critique, que je pourrais vous faire serait:
Vous devez pas utiliser pygame.key.get_pressed(), dans la boucle FOR d'événements..
Surtout que vous exécutez la fonction, à chaque itération de la boucle FOR (Les parenthèses). Ce qui est pas très bon, pour les performances.
for event in pygame.event.get():
if event.type == KEYDOWN : #récupère les touches enfoncées
#Gère le moteur épaule Y
if pygame.key.get_pressed()[pygame.K_w]:
Puisque pygame.key.get_pressed() retourne une liste, contenant tous les touches en booléen.
pygame.key.get_pressed() <--- Une fonction, qui retourne une liste de tous les touches en booléen..
Ex: [True, False, False, False, False, False, False, False, ...]
Il y a plus de 100 touches..
Vous pouvez utiliser les deux en même temps, mais pygame.key.get_pressed() s'utilise à l'extérieur de la boucle FOR.
Voici comment cela devrait être:
while continuer:
## Méthode 1: Par la boucle FOR
for event in pygame.event.get():
if event.type == KEYDOWN : #récupère les touches enfoncées
#Gère le moteur épaule Y
if event.key == pygame.K_w:
...
## Méthode 2: Par une liste
keyboard = pygame.key.get_pressed()
#Gère le moteur épaule Y
if keyboard[pygame.K_w]:
...
De plus, le set_repeat() sert uniquement pour la boucle FOR.
Ensuite, ceci est un truc (Ce n'est pas une critique).
Vous pourriez avoir une méthode (fonction) dans votre classe, pour la remise à zéro des moteurs. Puisque, dans le fond, vous remettez l'angle à 0.
Pour finir, tout vos classes pourrait être qu'une seule classe.
C'est probablement ce que Le Corbiste128 , tente de vous expliquer.
Voici un exemple, d'une classe qui ferait tous les types de moteurs.
class Moteur(object):
names_deux_angles = ['arm', 'shoulderx']
step = 2
def __init__(self, nom):
self.nom = nom
self.anglea = 0 ## L'angle primaire (pour tous les moteurs)
self.angleb = 0 ## L'angle secondaire.
def changepos(self):
self.anglea += self.step ## Incrémente
if self.nom in self.names_deux_angles:
self.angleb -= self.step ## Décrémente
def changeneg(self):
self.anglea -= self.step ## Décrémente
if self.nom in self.names_deux_angles:
self.angleb += self.step ## Incrémente
def reset(self):
self.anglea = 0
self.angleb = 0
#initiation des moteurs
msy = Moteur('shouldery')
me = Moteur('elbow')
maz = Moteur('absz')
ma = Moteur('arm')
msx = Moteur('shoulderx')
Ensuite, il suffit de mettre toujours l'angle primaire (anglea), à la place de angle.
#Gère le moteur épaule Y
msy.changeneg()
poppy.r_shoulder_y.goto_position(msy.anglea,1)
poppy.l_shoulder_y.goto_position(msy.anglea,1)
....
#gère le moteur bras
ma.changepos() ## À la place de change1()
poppy.r_arm_z.goto_position(ma.anglea,1)
poppy.l_arm_z.goto_position(ma.angleb,1)
....
#Remet les moteurs à 0 + réinitialise les angles
print("Remise à 0 des moteurs, ne touchez à rien svp !")
poppy.r_elbow_y.goto_position(0,2,wait=True)
poppy.l_elbow_y.goto_position(0,2,wait=True)
me.reset() ## À la place de me = moteur_elbow()
Pour tout le reste, c'est super! Bravo!
J'espère que vous comprenez ce que j'essaye d'expliquer
N'hésitez pas pour les questions.
Bonne chance et bonne continuation.
A+
- Edité par nolimitech 3 juin 2018 à 16:55:51
Besoin d'aide pygame
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.