Python et Pygame (débutant)


#1

Bon je galère depuis hier et google n’est pas mon ami sur le coup. Sans doute parce que mon erreur est trop débile pour avoir été commise avant :sweat_smile:

Bref, j’ai installé python et le module pygame. Je l’ai initialisé, je lui demande de me renvoyer le nombre de gamepad branchés via pygame.joystick.get_count() et il me renvoie “1” (tout va bien j’en ai effectivement 1). Dès que j’essaye de créer un nouvel objet via pygame.joystick.Joystick j’ai un retour “built-in function Joystick” (je ne sais pas ce que ça veut dire). Ensuite je voudrais appeler une des fonctions de cette page mais pour chacune j’ai une erreur. Par exemple si je tape pygame.joystick.Joystick.get_id j’ai “AttributeError: ‘builtin_function_or_method’ object has no attribute ‘get_id’” et je ne sais pas pourquoi

L’idée finale serait de pouvoir accéder aux données des axes et boutons du gamepad (genre comme ici).

Je pensais que ce serait “relativement” facile avec python et son module pygame mais visiblement je ne comprends pas comment fonctionne python :disappointed_relieved:


#2

tu n’aurais pas oublié un import ou des parenthèses dans tes appels de fonction ?


#3

Va falloir que tu donnes un exemple concret de code sinon ça va être compliqué. Colle ton code complet qui gère les joysticks, on y verra plus clair :slight_smile:


#4

La visiblement c’est parce que tu as une fonction en retour et pas un objet joystick si je dis pas de betise ,

a mon avais ici : pygame.joystick.Joystick tu as un joystick de trop ou tu as mal construit ton objet.

Mais comme le dit tout le monde fait peter ton code que l’on regarde un peu.


#5

Je ne pense pas que l’on puisse déjà parler de code, là je chipote juste dans l’IDLE de Python pour me faire une idée de comment ça marche (+ des vidéos d’introduction à python et des pages d’infos sur ce que je cherche à faire). Mon “code” :
>>> import pygame
>>> pygame.joystick.get_init()
0
>>> pygame.joystick.init()
>>> pygame.joystick.get_init()
1
>>> pygame.joystick.get_count()
1
>>> pygame.joystick.Joystick(0)
<Joystick object at 0x00000296BD581B70>
>>> pygame.joystick.Joystick.init()
Traceback (most recent call last):
File “<pyshell#30>”, line 1, in
pygame.joystick.Joystick.init()
AttributeError: ‘builtin_function_or_method’ object has no attribute ‘init’

Donc selon la page du module Pygame, en créant l’objet Joystick je devrais pouvoir appeler les fonctions qui me donnent son nom, son id, son nombre d’axes… mais je n’arrive à en faire fonctionner aucune…


#6

Cette erreur vient du fait que “pygame.joystick.Joystick” est une fonction, pas un objet.

Si tu appelles la fonction avec l’id du joystick que tu veux (“pygame.joystick.Joystick(0)” par exemple), tu récupéreras ton objet de type joystick et tu pourras faire ce que tu veux avec :

>>> pygame.joystick.Joystick(0).get_name()
'Controller (Xbox One For Windows)'

#7

Aaaaaaah ok… bon en plus je ne savais pas que tu pouvais mettre un paramètre autre part qu’à la fin de la fonction donc c’est bien j’ai appris 2 trucs ^^

Bon je teste et je reviens si/quand j’ai un nouveau soucis

Merci


#8

Je me comprend pas vraiment ce que tu entends par là.
“pygame” (et “pygame.joystick”) est un module et “Joystick()” une fonction de ce module retournant un objet de type Joystick (je sais pas trop pourquoi ils ont mis une majuscule au nom de cette fonction mais soit.).

Mon bout de code est équivalent à :

(pygame.joystick.Joystick(0)).get_name()

ou encore

joy_0 = pygame.joystick.Joystick(0)
joy_0.get_name()

#9

Non mais si tu essayes de mettre du sens sur ce qu’un débutant croit avoir compris tu risques de t’arracher les cheveux hein :wink:


#10

Bon alors j’ai testé un peu le code proposé en bas de la page de pygame et dans l’ensemble je pense comprendre ce qu’il se passe, sauf pour certains détails. Par exemple, dans la portion de code suivante, que représente le {:>6.3f} ?

for i in range( axes ):
axis = joystick.get_axis( i )
textPrint.print(screen, “Axis {} value: {:>6.3f}”.format(i, axis) )

Je me rends bien compte que les questions que je pose sont basiques et j’essaye vraiment d’en apprendre un maximum par moi-même mais par moment je bloque sur certains éléments qui ne sont pas explicités dans les cours ou exemples que je consulte.

Par exemple pour moi l’exercice suivant va être de comprendre comment formuler des valeurs pour les envoyer à un Arduino en USB. Je sais déjà que je dois passer par le module Serial en python mais j’en suis encore à essayer de comprendre quel format de données Arduino acceptera…

Et pour ceux qui se posent la question du pourquoi de ce thread un peu bizarre, ça fait longtemps que j’ai envie de tester des bricolages déco/robotique/… et j’ai décidé de me jeter à l’eau pour voir si ce serait dans le registre de mes compétences ou si c’est définitivement trop loin pour moi :thinking:


#11

est-ce que c’est pas la valeur en input de ton joy?


#12

Pas un spécialiste de Python, je m’y suis mis récemment et je ne maitrise pas grand chose encore.
Mais je dirais que c’est la valeur de “axis”, alignée à droite, et le 6.3f c’est le format : 6 chiffres entier, et 3 décimales.
https://www.python-course.eu/python3_formatted_output.php


#13

ouais ouais , tu veux surtout te fabriquer une manette à combo automatique pour SF ouais …


#14

Effectivement ça pourrait bien être le format…

EDIT: sauf que y a bien 3 décimales mais où vois-tu 6 chiffres entiers ? Chaque valeur d’axe est un .float non ?
Y a d’ailleurs un autre truc étrange pour les boutons, que représente le {:>2} ? C’est ce qui renvoie l’ID du bouton afin qu’elle soit .print non ?

for i in range( buttons ):
button = joystick.get_button( i )
textPrint.print(screen, “Button {:>2} value: {}”.format(i,button) )


#15

Ahahahaha, même comme ça je serais incapable de gagner le moindre match à SF :smile:


#16

C’est une question légitime et pas évidente de prime abord.

(aparté: attention au whitespace en python, là ton code il veut rien dire parce que tu as collé une citation en markdown. Pour afficher du code sur Discourse il faut l’entourer de triple accent grave (```)).

On peut décomposer

textPrint.print(screen, “Axis {} value: {:>6.3f}”.format(i, axis) )

en trois parties:

Première partie: Tu essaies d’afficher une chaine de caractère sur l’écran, du coup tu fais testPrint.print(screen, ma_chaine_de_caratere). Probablement pas besoin d’épiloguer dessus (ça tombe bien j’ai jamais touché à Pygame :smiley: )

Deuxième partie: Ta chaine de caractère est évaluée dynamiquement (càd tu vas pas faire une chaîne de caractère différentes pour chaque valeur de i ou de axis avec des if/else tentaculaires). Pour cela tu utilises la méthode .format qui permet de remplacer ce qui est entouré d’accolades par quelque chose d’autre, par exemple

my_str = "Prends ça, {} de malheur !".format("monstre")
print(my_str)
> Prend ça, monstre de malheur !

Tu peux aussi nommer les trucs à remplacer:

my_str = "{nom}, espèce de {insulte}!".format(nom="Valvert", insulte="sot")
print(my_str)
> Valvert, espèce de sot !

Troisième partie, le :>6.3f qui nous intéresse: on peut formatter les nombres qu’on remplace pour qu’ils soient plus jolis (par exemple il n’est nécessaire dit d’afficher les résultats d’un calcul avec toute la précision que permet Python).
Il y a plusieurs parties à cette chaîne:

  • : indique que tu veux formater ton nombre (tout ce qui est gauche de ces deux-points corresponds à son identifiant, si tu veux faire .format(identifiant=valeur), genre
    "Le taux de remplissage est de {rate:.1f} m/s".format(rate=get_rate())
  • 6 indique que ta chaîne de caractère va comporter au minimum 6 éléments. C’est surtout flagrant si tu as du contenu après ta variable, par exemple:
"La température au sol est de {temp:20.1f} degrés Celcius.".format(temp=get_temp())
> La température au sol est de                  7.3 degrés Celcius.
  • .3 indique que tu vas afficher trois chiffres après la décimale
  • f indique que tu vas afficher un float, ce qui ne change pas grand chose par rapport au truc par défaut (il y a d’autres modes: par exemple si tu mets e ça va t’afficher ta valeur en notation scientifique).

Je me base sur ce site dedié qui trouve lui aussi que la doc officiel de Python est trop obscure et manque de cas pratique et concret.


#17

Merci, c’est super bien expliqué ^^ J’ai depuis fait quelques tests sur le code fourni par Pygame et j’ai pu voir ce qu’entraînaient des modifications des valeurs dans le {:>6.3f}. Par exemple, quand je retire le “f”, le code ne renvoie plus un arrondi mais va remplacer les valeurs très faibles par une notification scientifique (genre e exposant -5). Donc si je comprends bien, sans précision du format du chiffre python va juste utiliser le format qui renvoie la valeur la plus proche de celle lue c’est ça ?

Bon, maintenant que c’est un peu plus clair, je vais aller voir du côté du module Serial…


#18

Je continue mon (lent et pénible) apprentissage en testant des morceaux de code par-ci par-là mais il y un truc qui m’ennuie : quand mon code est foireux (soit 9 fois sur 10) j’ai juste une fenêtre qui s’ouvre une demi-seconde sans avoir le temps de voir ce qui est écrit.

Est-ce qu’il y a moyen dans python (ou sublime text) de voir le message d’erreur ? Que je sache où les choses foirent ?


#19

Tu ne peux pas le lancer dans une ligne de commande windows ? C’est ce que je faisais. Après c’est une technique de noob, j’en suis au même niveau que toi ^^


#20

Grand noob en python, mais quand j’avais 2/3 trucs a faire, j’utilisais un vrai IDE (et pas un editeur de texte comme sublime, ceci n’est pas un troll), où je lancais le script directement a partir de celui-ci. La console reste bien ouverte et permet d’en savoir un peu plus.

Bonus, le debug pas a pas aide bien aussi :wink:

J’utilisais PyCharm en version “Community” (gratos)