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 :

Déplacer un carré dans Pygame à partir d’un autre script


Sujet :

Python

  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes de Haute Provence (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2011
    Messages : 58
    Par défaut Déplacer un carré dans Pygame à partir d’un autre script
    Bonjour,

    Je souhaiterais déplacer un carré dans une fenêtre Pygame (« plateforme_du_jeu ») à partir d’un autre script (« gestion_du_jeu »).

    Le problème c’est qu’il apparaît un « import circulaire ». Comment pourrais-je éviter ça ?
    Une personne pourrait-elle me donner un conseil pour modifier les scripts ?
    En vous remerciant par avance.

    Voici, ci-dessous, les deux scripts.


    Le script « gestion_du_jeu » :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    import time
    import plateforme_du_jeu
     
     
     
    game = plateforme_du_jeu.Game()
     
    time.sleep(.5)
    game.deplacement(10)
    time.sleep(.5)
    game.deplacement(10)
    time.sleep(.5)
    game.deplacement(-10)

    Le script « plateforme_du_jeu » :

    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
    import pygame, sys
    import gestion_du_jeu
     
    class Game:
     
        def __init__(self):
            pygame.init()
            self.screen = pygame.display.set_mode((1000,600))
            self.x, self.y = 500, 300
            self.lancement_jeu()
     
        def lancement_jeu(self):
            while True:
                for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                        pygame.quit()
                        sys.exit()
     
                # efface l'ancien rectangle
                self.screen.fill((0,0,0))
                # dessine le nouveau rectangle
                pygame.draw.rect(self.screen, (255,255,255), (self.x,self.y,50,40))
     
                pygame.display.update()
     
        def deplacement(self, valeur_deplacement):
            self.x += valeur_deplacement
            # efface l'ancien rectangle
            self.screen.fill((0,0,0))
            # dessine le nouveau rectangle
            pygame.draw.rect(self.screen, (255,255,255), (self.x,self.y,50,40))
            pygame.display.update()

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 715
    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 715
    Par défaut
    Salut,

    Citation Envoyé par sancho.poncho Voir le message
    Le problème c’est qu’il apparaît un « import circulaire ». Comment pourrais-je éviter ça ?
    Une personne pourrait-elle me donner un conseil pour modifier les scripts ?
    Ce n'est pas une mauvaise herbe qui apparait juste pour vous embêter: c'est vous qui l'avez écrit cet import circulaire!
    Pour moi, l'import gestion_du_jeu dans plateforme_du_jeu ne sert à rien.

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

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 827
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 827
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par sancho.poncho Voir le message
    Le problème c’est qu’il apparaît un « import circulaire »
    Hé oui. A importe B et B importe A.

    Citation Envoyé par sancho.poncho Voir le message
    Comment pourrais-je éviter ça ?
    Pourquoi le script "plateforme_du_jeu" importe le script "gestion" alors qu'il ne l'utilise pas?

    Tu dois avoir un code principal qui fait tous les imports nécessaires, puis des codes annexes qui reçoivent les éléments du script principal.
    Ainsi le script principal pourra créer un objet "plateforme", un objet "gestion", et si la plateforme a besoin de la gestion il lui la passe, et si la gestion a besoin de la plateforme il lui la passe pareillement. Et plus de souci d'import circulaire.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes de Haute Provence (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2011
    Messages : 58
    Par défaut
    Merci pour vos réponses et effectivement, il y a un problème avec l'import d'un script que je n'utilise pas.

    Mais j'ai tellement modifié mes deux scripts pour que ça fonctionne que je me suis mélangé les pinceaux.

    Le problème est que je voudrais lancer une fenêtre Pygame et gérer le déplacement d'un carré dans cette fenêtre à partir d'un autre script "gestion_du_jeu".

    Mais une fois la fenêtre créée dans "plateforme_du_jeu", je n'ai plus la main au niveau de "gestion_du_jeu" pour modifier la position du carré car la position du carré est enfermée dans la boucle While de Pygame.

    J'ai suivi votre conseil Sve@r et j'ai fait un programme_principal qui gère les deux autres (le but étant de déplacer un carré avec la flèche "haut" pour avancer et "bas" pour reculer mais à partir d'un script extérieur à la boucle While de la fenêtre Pygame).

    "programme_principal"

    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
    import time
    from ctypes import windll
    import plateforme_du_jeu
     
    game = plateforme_du_jeu.Game()
     
    def instruction():
        """ Retourne +10 si on appuie sur la flèche "haut" et -10 si on appuie sur la flèche "bas" """
        GetAsyncKeyState = windll.user32.GetAsyncKeyState
        run = True
        while run:
            if GetAsyncKeyState(0x26):      # si on appuie sur la flèche du haut
                x = 10
                run = False     # permet de sortir de la boucle ès l'appui sur la flèche du haut
            elif GetAsyncKeyState(0x28):    # si on appuie sur la flèche du bas
                x = -10
                run = False     # permet de sortir de la boucle ès l'appui sur la flèche du bas
        return x

    "gestion_du_jeu"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    import programme_principal
     
     
    def deplacement_x(deplacement):
        return programme_principal.instruction()

    "plateforme_du_jeu"

    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
    import pygame, sys
    import gestion_du_jeu
     
    class Game:
     
        def __init__(self):
            pygame.init()
            self.screen = pygame.display.set_mode((1000,600))
            self.x, self.y = 500, 300
            self.lancement_jeu()
     
        def lancement_jeu(self):
            while True:
                for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                        pygame.quit()
                        sys.exit()
     
                # demande la nouvelle position du carré suivant les "x"
                deplacement = 0
                while deplacement == 0:
                    deplacement = gestion_du_jeu.deplacement_x()
                # efface l'ancien rectangle
                self.screen.fill((0,0,0))
                # dessine le nouveau rectangle
                pygame.draw.rect(self.screen, (255,255,255), (self.x,self.y,50,40))
     
                pygame.display.update()

    Le problème est que lorsque je lance le le "programme_principal" il y a toujours le message d'erreur :
    File "c:\Users\Poncho\Desktop\programme_principal.py", line 5, in <module>
    game = plateforme_du_jeu.Game()
    ^^^^^^^^^^^^^^^^^^^^^^
    AttributeError: partially initialized module 'plateforme_du_jeu' has no attribute 'Game' (most likely due to a circular import)

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 827
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 827
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par sancho.poncho Voir le message
    Le problème est que lorsque je lance le le "programme_principal" il y a toujours le message d'erreur :
    File "c:\Users\Poncho\Desktop\programme_principal.py", line 5, in <module>
    game = plateforme_du_jeu.Game()
    ^^^^^^^^^^^^^^^^^^^^^^
    AttributeError: partially initialized module 'plateforme_du_jeu' has no attribute 'Game' (most likely due to a circular import)
    Mal découpé. Pourquoi séparer "saisie" et "affichage"? Et surtout pourquoi la saisie est dans le programme principal (alors qu'une saisie n'a rien de fondamental pour qu'un programme fonctionne).
    En programmation professionnelle, les deux éléments font partie du même ensemble qui est appelé "la Vue". La Vue c'est comment sortir des valeurs sur un périphérique de sortie (généralement l'écran) et/ou comment récupérer des valeurs d'un périphérique d'entrée (généralement le clavier). Normalement ce principe doit être implémenté dans Pygame donc il doit te permettre à la fois de récupérer une touche flèche et te permettre de la traiter pour déplacer ton carré.

    Citation Envoyé par sancho.poncho Voir le message
    Mais j'ai tellement modifié mes deux scripts pour que ça fonctionne que je me suis mélangé les pinceaux.
    Tu as parfaitement le droit de dire "ok je repars à zéro en plus propre". Ce n'est absolument pas déshonorant et on l'a tous fait. Même les concepteurs d'Unix l'ont fait au début (ils ont bossé dessus pendant 5 ans en "s'emmélant les pinceaux" de plus en plus puis un jour ont tout bazardé et tout repris. Et ils ont sorti le truc en 2 ans.

    Citation Envoyé par sancho.poncho Voir le message
    Mais une fois la fenêtre créée dans "plateforme_du_jeu", je n'ai plus la main au niveau de "gestion_du_jeu" pour modifier la position du carré car la position du carré est enfermée dans la boucle While de Pygame.
    Pas normal. Je ne connais pas Pygame mais si c'est un truc dédié à afficher des objets il doit posséder des opérations de saisie. Il ne peut pas ne pas en avoir (sinon il n'aurait jamais tenu la distance). Peut-être que ton problème c'est que tu cherches à récupérer toi-même les flèches au lieu d'utiliser Pygame...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  6. #6
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes de Haute Provence (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2011
    Messages : 58
    Par défaut
    [Mal découpé. Pourquoi séparer "saisie" et "affichage"? Et surtout pourquoi la saisie est dans le programme principal (alors qu'une saisie n'a rien de fondamental pour qu'un programme fonctionne).
    En programmation professionnelle, les deux éléments font partie du même ensemble qui est appelé "la Vue". La Vue c'est comment sortir des valeurs sur un périphérique de sortie (généralement l'écran) et/ou comment récupérer des valeurs d'un périphérique d'entrée (généralement le clavier). Normalement ce principe doit être implémenté dans Pygame donc il doit te permettre à la fois de récupérer une touche flèche et te permettre de la traiter pour déplacer ton carré.
    Effectivement, il existe des fonctions propres à Pygame pour détecter l'enfoncement de touches du clavier pour déplacer le carré mais dans mon cas je ne voudrais pas que le déplacement se fasse par la détection des touches enfoncées par un utilisateur mais par un script qui gère le déplacement du carré d'où mon impossibilité d'utiliser cette technique de détection des touches propre à Pygame (l'utilisation de cette même technique de détection des touches dans "programme_principal" n'est là que pour illustrer le fait que je souhaite que ce soit un script extérieur mais le but final est que ce soit des choix propres au script "programme_principal" qui gère le déplacement du carré et non le choix d'un utilisateur en appuyant sur des touches (flèches) du clavier).

    Pas normal. Je ne connais pas Pygame mais si c'est un truc dédié à afficher des objets il doit posséder des opérations de saisie. Il ne peut pas ne pas en avoir (sinon il n'aurait jamais tenu la distance). Peut-être que ton problème c'est que tu cherches à récupérer toi-même les flèches au lieu d'utiliser Pygame...
    J'avoue ne connaître que les fonctions de base de Pygame et peut-être y a t-il une méthode qui permet d'attendre une instruction d'un autre script plutôt que l'appui sur une touche du clavier.
    Si une personne connaît cette méthode cela m'intéresse car je ne l'ai pas trouvée.

  7. #7
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 715
    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 715
    Par défaut
    Citation Envoyé par sancho.poncho Voir le message
    mais dans mon cas je ne voudrais pas que le déplacement se fasse par la détection des touches enfoncées par un utilisateur mais par un script qui gère le déplacement du carré d'où mon impossibilité d'utiliser cette technique de détection des touches propre à Pygame
    Techniquement, ça pourrait se faire via des événements (pygame) utilisateurs. L'autre script a un minimum à connaître côté application pygame qui récupère les events dans sa boucle principale.... mais un script n'est pas un thread! Les fonctions qui sont dedans ne vont pas s'activer toutes seules: soit elles sont appelées depuis la boucle evenementielle de pygame, soit elles sont exécutées via un thread (et ça peut devenir "compliqué"... inutilement si c'est juste parce qu'on ne sait pas faire simple).

    Une bibliothèque comme pygame a été conçue pour résoudre ce genre de problème...
    A vous d'apprendre à vous en servir plutôt que d'essayer de réinventer une solution (et nous demander de la coder).

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

  8. #8
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 827
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 827
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par sancho.poncho Voir le message
    mais dans mon cas je ne voudrais pas que le déplacement se fasse par la détection des touches enfoncées par un utilisateur mais par un script qui gère le déplacement du carré
    C'est un peu la même chose. Si on enfonce la flèche gauche, soit on code le déplacement du carré soi-même (mise à jour des coordonnées, effacement du carré, affichage du carré un cran plus à gauche), soit on appelle la fonction qui gère le déplacement (fonction qui met à jour les coordonnées, qui efface le carré et qui l'affiche un cran plus à gauche).
    Ton souci principal est que tu te sens "enfermé" dans la boucle Pygame alors que cette boucle Pygame inclus la gestion d'évènements comme "flèche appuyée" ou autre. Il faut juste que tu regardes dans Pygame comment récupérer cet évènement. Ensuite, une fois récupéré, que cet évènement soit associé à une fonction de ton script ou une fonction importée depuis un autre script change peu de chose (sauf que si elle est importée, elle ne fait donc pas partie de l'objet "jeu" et n'a pas accès à ses paramètres comme la position du carré donc devra recevoir cette info d'une façon ou une autre).
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  9. #9
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes de Haute Provence (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2011
    Messages : 58
    Par défaut
    D'accord, je vous remercie beaucoup pour votre aide et votre bienveillance Sve@r.

    Je vous souhaite une bonne soirée et au plaisir.

  10. #10
    Membre Expert
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 068
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 068
    Par défaut
    j'ai pas compris s'il s'agit d'envoyer des commandes d'un script à un autre ou de faire tourner deux boucles while dans un même script ... ?

  11. #11
    Membre confirmé
    Homme Profil pro
    Ingénieur Système
    Inscrit en
    Novembre 2019
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur Système

    Informations forums :
    Inscription : Novembre 2019
    Messages : 20
    Par défaut
    Citation Envoyé par sancho.poncho Voir le message
    Effectivement, il existe des fonctions propres à Pygame pour détecter l'enfoncement de touches du clavier pour déplacer le carré mais dans mon cas je ne voudrais pas que le déplacement se fasse par la détection des touches enfoncées par un utilisateur mais par un script qui gère le déplacement du carré d'où mon impossibilité d'utiliser cette technique de détection des touches propre à Pygame (l'utilisation de cette même technique de détection des touches dans "programme_principal" n'est là que pour illustrer le fait que je souhaite que ce soit un script extérieur mais le but final est que ce soit des choix propres au script "programme_principal" qui gère le déplacement du carré et non le choix d'un utilisateur en appuyant sur des touches (flèches) du clavier).



    J'avoue ne connaître que les fonctions de base de Pygame et peut-être y a t-il une méthode qui permet d'attendre une instruction d'un autre script plutôt que l'appui sur une touche du clavier.
    Si une personne connaît cette méthode cela m'intéresse car je ne l'ai pas trouvée.

    Bonjour,

    Si je comprends bien le besoin, tu souhaites avoir un joueur qui joue "automatiquement" (sans notion de détection d'évènements clavier). Généralement pour ça, tu crées une classe Joueur que tu instancies dans ton jeu. C'est dans ta boucle de lecture des évènements que tu gères les actions de ton joueur..

    Un exemple vraiment basique ci-dessous (tu peux sans problème mettre la classe Joueur dans un autre fichier).
    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
     
    import pygame, sys
    import random
     
     
    class Joueur:
     
        def __init__(self):
            self.x, self.y = 500, 300
     
        def deplacement(self):
            # deplacement aléatoire soit en x, soit en y
            # dans cet exemple aucun test n'est fait pour vérifier que le joueur ne quitte pas l'écran
            if random.randint(0, 1) == 0:
                self.x += random.randint(-10, 10)
            else:
                self.y += random.randint(-10, 10)
     
     
    class Game:
     
        def __init__(self):
            pygame.init()
            self.joueur = Joueur()
            self.screen = pygame.display.set_mode((1000, 600))
            self.lancement_jeu()
     
        def update_screen(self):
            # efface l'ancien rectangle
            self.screen.fill((0, 0, 0))
            # dessine le nouveau rectangle
            pygame.draw.rect(self.screen, (255, 255, 255), (self.joueur.x, self.joueur.y, 50, 40))
            pygame.display.update()
     
        def lancement_jeu(self):
            while True:
                for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                        pygame.quit()
                        sys.exit()
     
                # mise à jour de la position du joueur
                self.joueur.deplacement()
                # mise à joueur de l'affichage
                self.update_screen()
     
     
    if __name__ == '__main__':
        game=Game()

Discussions similaires

  1. [XL-2010] Récupérer l’adresse mail dans Outlook à partir d’un nom
    Par stdonat dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 20/06/2019, 11h22
  2. [XL-2010] Fonctionnement d’une macro à partir d’un autre classeur actif
    Par matysek dans le forum Macros et VBA Excel
    Réponses: 0
    Dernier message: 17/02/2016, 20h28
  3. [XL-2007] [Débutant] Remplir un tableau à partir d’un autre tableau
    Par DerJul dans le forum Macros et VBA Excel
    Réponses: 0
    Dernier message: 05/07/2011, 11h37
  4. Insertion donnée dans DBGrid à partir d'autre(s) table(s)
    Par compdev dans le forum Bases de données
    Réponses: 1
    Dernier message: 23/03/2009, 15h41
  5. Réponses: 11
    Dernier message: 09/08/2007, 00h33

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