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 »).

Mais, je ne vois pas comment y arriver.
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 » :

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
        pygame.display.update()

Le script « plateforme_du_jeu » :

import time
import plateforme_du_jeu

game = plateforme_du_jeu.Game()

game.deplacement(10)
time.sleep(.5)
game.deplacement(10)
time.sleep(.5)
game.deplacement(-10)
time.sleep(.5)

Sinon, au début j’avais fait ce script pour la « plateforme_du_jeu » mais le problème c’est qu’il y apparaît un « import circulaire ». Comment pourrais-je éviter ça ?

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()

Un TP ?

Euh, non, c’est juste un petit projet perso.

Ton script reste bloqué dans le While True: de lancement_jeu.

Les fonctions après :
game = plateforme_du_jeu.Game()
Ne sont jamais appelées.

Si tu veux déplacer le carré, tu peux ajouter les lignes suivantes dans ta boucle d’événement pour lire le clavier et déplacer le carré avec les flèches :

      while True:
          for event in pygame.event.get():
              if event.type == pygame.QUIT:
                  pygame.quit()
                  sys.exit()

              # checking if keydown event happened or not
              if event.type == pygame.KEYDOWN:
                     
                  if event.key == pygame.K_LEFT:
                      self.x -= 10

                  if event.key == pygame.K_RIGHT:
                      self.x += 10

                  if event.key == pygame.K_UP:
                      self.y -= 10

                  if event.key == pygame.K_DOWN:
                      self.y += 10

Oui, je vous remercie pour votre réponse Zoomastigophore mais je voudrais vraiment pouvoir déplacer mon carré à partir d’un script extérieur et non à partir des touches du clavier.

je cherche une sorte de « event » qui me permettrait d’envoyer une information dans la boucle While du jeu afin que cette information soit « répercutée » dans la fenêtre de jeu.

Encore merci pour votre réponse.

Ah OK j’avais pas bien lu la question.

Il faut lancer pygame dans un thread.

Tu peux remplacer self.lancement_jeu() dans ta fonction init par ça :

        self.thread = threading.Thread(target = self.lancement_jeu, args = [])
        self.thread.start()

Il faut ajouter import threading au début.

Ajoute aussi une fonction quitter à ta classe :

    def quitter(self):
        pygame.quit()
        sys.exit()

Que tu appelles à la fin de gestion_du_jeu.py

game.quit()

C’est probablement pas très propre comme solution*, mais ça fera ce que tu demandes (si j’ai bien compris cette fois).

(*) La preuve, ça lance une exception en quittant…

En effet, ça marche super bien !

J’avoue que je ne connais pas le « thread » même si j’en ai déjà entendu parler mais en tout cas ça fonctionne comme par magie pour paraphraser Arthur C. Clarke avec sa troisième loi concernant les technologies très avancées :slight_smile:

Encore mille mercis pour votre aide et au plaisir Zoomastigophore !

Sinon. J’ai fait un « squelette » pour utiliser pygame plus facilement :

Vu que c’est pour des étudiants pas du tout info, c’est ultra simplifié.

La (non) doc est un peu à la rache mais y a une dizaine d’exemples.

Bonsoir,

C’est un code très impressionnant et j’avoue ne pas avoir saisi toutes les possibilités de ce squelette.

Notamment, est ce que j’aurais pu utiliser votre code « Update core.py » pour envoyer des informations (requêtes) à partir du script « gestion_du_jeu » afin de modifier la position du carré ?

En tout cas, je vous remercie pour le partage de vos créations.

import core


def setup():
    print("Setup START---------")
    core.fps = 30
    core.WINDOW_SIZE = [400, 400]
    core.memory(« position »,Vector2(200,200)
    print("Setup END-----------")


def run():
    core.cleanScreen()
    core.Draw.rect((255,0,0),(core.memory(« position »),50,50))
    core.memory(« position »).x+=10

core.main(setup, run)


Et c’est tout.

Bonjour Ewi,

Je vous remercie pour votre réponse.

Lorsque j’essaie le code suivant, j’obtiens le message d’erreur :
File « c:\Users\Poncho\Desktop\core.py », line 239, in rect
pygame.draw.rect(core.screen, color, rect, width)
TypeError: rect argument is invalid

import core
from pygame.math import Vector2

def setup():
print(« Setup START--------- »)
core.fps = 30
core.WINDOW_SIZE = [400, 400]
core.memory(« position », Vector2(200,200))
print(« Setup END----------- »)

def run():
core.cleanScreen()
core.Draw.rect((255,0,0),(core.memory(« position »),50,50))
core.memory(« position »).x+=10

core.main(setup, run)

Pourriez-vous me dire comment corriger ce problème ?

A opui, faut décomposer le x et le y.
core.Draw.rect((255,0,0),(core.memory(« position »).x,core.memory(« position »).y,50,50))

Je le changerai a l’occaz.

Ca fonctionne effectivement très bien avec cette modification.

Il faut donc que je remplace mon script « plateforme_du_jeu » par votre script.

En revanche, je ne vois pas comment gérer cette nouvelle « plateforme_du_jeu » avec le premier script « gestion_du_jeu » sans avoir le message d’erreur « import circulaire ».
En effet, pour envoyer la nouvelle position à « plateforme_du_jeu », il faut que j’importe ce dernier dans « gestion_du_jeu ».

Mais pour connaître la nouvelle position souhaitée du carré, il faut que « plateforme_du_jeu » fasse appel à « gestion_du_jeu » et donc importe ce dernier d’où l’apparition du message d’erreur « import circulaire ».

Je ne vois pas comment résoudre ce problème ?

Regarde l’exemple « pong ». Ça t’aidera.

D’accord, je regarde ça mais ça risque d’être un peu long.

Merci pour la réponse Ewi !

(:joy:)

J’ai réutilisé vos deux scripts pour faire ce que je souhaitais obtenir comme résultat.

Le script « Pong »

import core
from player import Player


def setup():
    core.WINDOW_SIZE = [600,400]
    core.fps = 30
    core.memory("j1",Player("J1",200,200))


def run():
    core.cleanScreen()
    if core.getKeyPressList("r"):
        core.memory("j1", Player("J1", 10, 200))

    core.memory("j1").show()

    programme_principal2.instruction()

    if core.getKeyPressList("a"):
        core.memory("j1").up()
    if core.getKeyPressList("q"):
        core.memory("j1").down()

    edge(core.memory("j1"))

core.main(setup,run)

Le script « Player »

from pygame import Rect
from pygame.math import Vector2
import core

class Player:
    def __init__(self,j="J0",x=10,y=300):
        self.position = Vector2(x,y)
        self.largeur = 50
        self.hauteur = 50
        self.couleur = (255,255,255)
        self.score = 0
        self.name = j

    def up(self):
        self.position.x += 10

    def down(self):
        self.position.x -= 10

    def show(self):
        core.Draw.rect(self.couleur,(self.position.x,self.position.y,self.largeur,self.hauteur))

Ca fonctionne très bien quand j’utilise les touches du clavier.

Mais comme je souhaite que ce soit un script extérieur qui gère les déplacements, j’ai rajouté un « programme_principal » et j’ai remplacé la détection des touches « a » et « q » dans « Pong » par un appel à la fonction « instruction() » du nouveau script « programme_principal ».
Et là le carré ne bouge plus.

Le script « programme_principal »

from ctypes import windll

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

Le « nouveau » script « Pong »

import core
from player import Player
import programme_principal2


def setup():
    core.WINDOW_SIZE = [600,400]
    core.fps = 30
    core.memory("j1",Player("J1",200,200))


def run():
    core.cleanScreen()
    if core.getKeyPressList("r"):
        core.memory("j1", Player("J1", 10, 200))

    core.memory("j1").show()

    programme_principal2.instruction()

core.main(setup,run)

Y aurait-il un moyen d’envoyer la nouvelle position du carré à partir du script « programme_principal » ?

Tu as accès n’importe où à core.memory et n’importe où à core.getMouse…

D’accord, je vous remercie pour votre aide.

Je vous souhaite une bonne soirée.

3 « J'aime »