Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 09/01/2022, à 20:46

chris7522

[RESOLU]Accès a rect.x d'une autre classe (python)

Bonjour a toutes et a tous ,
J'essaie d'enrichir le code précédent , mais je me trouve confronter a un petit problème .
Depuis ma classe Monstres contenue dans CLASSES.py , je n'arrive pas a avoir acces au rect.x et rect.y de mon instance " _personnage" . Mon instance   _personnage n'est pas reconnu .

[pygame 2.1.2 (SDL 2.0.16, Python 3.8.10)
Hello from the pygame community. [url]https://www.pygame.org/contribute.html[/url]
Traceback (most recent call last):
  File "/home/chris/PycharmProjects/labyrinthe/main.py", line 83, in <module>
    LISTE_GLOBALE_SPRITES.update()
  File "/home/chris/PycharmProjects/labyrinthe/venv/lib/python3.8/site-packages/pygame/sprite.py", line 539, in update
    sprite.update(*args, **kwargs)
  File "/home/chris/PycharmProjects/labyrinthe/CLASSES.py", line 82, in update
    if self.rect.x < _personnage.rect.x:
NameError: name '_personnage' is not defined
C'est parti...

Process finished with exit code 1
  def update(self):
    X_courant = self.rect.x
    Y_courant = self.rect.y

    if self.rect.x < _personnage.rect.x:     < c'est ici que ca coince 
      self.rect.x += TUILE_TAILLE
    elif self.rect.x > _personnage.rect.x:    < c'est ici que ca coince
      self.rect.x -= TUILE_TAILLE
    elif self.rect.y < _personnage.rect.y:    < c'est ici que ca coince
      self.rect.y += TUILE_TAILLE
    elif self.rect.y > _personnage.rect.y:    < c'est ici que ca coince
      self.rect.y -= TUILE_TAILLE

Pour rappel , le code intégrale :
main.py :

import pygame
from CLASSES import *
from CONSTANTES import *

def AFFICHER_SCORE():
  font = pygame.font.SysFont('Arial', TUILE_TAILLE - 5)
  background = pygame.Surface((LARGEUR, SCORE_HAUTEUR))
  background = background.convert()
  background.fill(BLANC)
  text = font.render(_personnage.chrono.Timer.strftime("%H:%M:%S"), 1, NOIR)
  textpos = text.get_rect(centerx = LARGEUR / 2, centery = SCORE_HAUTEUR / 2)
  background.blit(text, textpos)
  screen.blit(background, (0, 0))

pygame.init()

screen = pygame.display.set_mode([LARGEUR, HAUTEUR])
pygame.display.set_caption('Le jeu du labyrinthe')

XX = 0
YY = 0
with open("Labyrinthe.txt", "r") as fichier:
  for ligne in fichier:
    for sprite in ligne:
      if sprite == 'M':
        _mur = MUR(XX, YY)
        LISTE_MURS.add(_mur)
        LISTE_GLOBALE_SPRITES.add(_mur)
      XX = XX + 1
    XX = 0
    YY = YY + 1

RECHERCHE_MONSTRES = True
while RECHERCHE_MONSTRES:
    _monstre = Monstres()
    LISTE_CONFLIT_MONSTRES = pygame.sprite.spritecollide(_monstre, LISTE_GLOBALE_SPRITES, False)
    if len(LISTE_CONFLIT_MONSTRES) == 0:
        LISTE_MONSTRES.add(_monstre)
        LISTE_GLOBALE_SPRITES.add(_monstre)
        RECHERCHE_MONSTRES = False

RECHERCHE_PERSONNAGE = True
while RECHERCHE_PERSONNAGE:
    _personnage = PERSONNAGE()
    LISTE_CONFLIT = pygame.sprite.spritecollide(_personnage, LISTE_MURS, False)
    if len(LISTE_CONFLIT) == 0:
        LISTE_GLOBALE_SPRITES.add(_personnage)
        RECHERCHE_PERSONNAGE = False

while len(LISTE_OBJETS) < 10:
    _objet = OBJET()
    LISTE_CONFLIT = pygame.sprite.spritecollide(_objet, LISTE_GLOBALE_SPRITES, False)
    if len(LISTE_CONFLIT) == 0:
        LISTE_GLOBALE_SPRITES.add(_objet)
        LISTE_OBJETS.add(_objet)

clock = pygame.time.Clock()

print("C'est parti...")

RUN = True

while RUN:
  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      RUN = False
    elif event.type == pygame.KEYDOWN:
      if event.key == pygame.K_LEFT:
        _personnage.DIRECTION = 'G'
        break
      elif event.key == pygame.K_RIGHT:
        _personnage.DIRECTION = 'D'
        break
      elif event.key == pygame.K_UP:
        _personnage.DIRECTION = 'H'
        break
      elif event.key == pygame.K_DOWN:
        _personnage.DIRECTION = 'B'
        break

  LISTE_GLOBALE_SPRITES.update()
  screen.fill(BLANC)

  LISTE_GLOBALE_SPRITES.draw(screen)
  AFFICHER_SCORE()

  if _personnage.TERMINE:
    RUN = False

  pygame.display.flip()

  dt = clock.tick(60)
  _personnage.chrono.update(dt)

print("Nombre d'objets ramassés : %d" % _personnage.POINTS)
pygame.quit()

CLASSES.py

import pygame, random
from CONSTANTES import *
from datetime import timedelta, datetime, date, time

LISTE_OBJETS = pygame.sprite.Group()
LISTE_MURS = pygame.sprite.Group()
LISTE_GLOBALE_SPRITES = pygame.sprite.Group()
LISTE_MONSTRES = pygame.sprite.Group()

class MUR(pygame.sprite.Sprite):
  def __init__(self, x, y):
    pygame.sprite.Sprite.__init__(self)
    self.image = pygame.image.load("MUR.png").convert_alpha()
    self.rect = self.image.get_rect()
    self.rect.y = TUILE_TAILLE * y + SCORE_HAUTEUR
    self.rect.x = TUILE_TAILLE * x

class OBJET(pygame.sprite.Sprite):
  def __init__(self):
    pygame.sprite.Sprite.__init__(self)
    self.image = pygame.image.load("OBJET.png").convert_alpha()
    self.rect = self.image.get_rect()
    self.rect.y = random.randint(0, TUILE_NOMBRE - 1) * TUILE_TAILLE + SCORE_HAUTEUR
    self.rect.x = random.randint(0, TUILE_NOMBRE - 1) * TUILE_TAILLE

class PERSONNAGE(pygame.sprite.Sprite):
  def __init__(self):
    pygame.sprite.Sprite.__init__(self)
    self.image = pygame.image.load("PERSONNAGE.png").convert_alpha()
    self.rect = self.image.get_rect()
    self.rect.y = random.randint(0, TUILE_NOMBRE - 1) * TUILE_TAILLE + SCORE_HAUTEUR
    self.rect.x = random.randint(0, TUILE_NOMBRE - 1) * TUILE_TAILLE
    self.POINTS = 0
    self.TERMINE = False
    self.DIRECTION = '-'
    self.chrono = Chrono()

  def update(self):
    X_COURANT = self.rect.x
    Y_COURANT = self.rect.y
    if self.DIRECTION == 'G':
      self.rect.x -= TUILE_TAILLE
      self.DIRECTION = '-'
    elif self.DIRECTION == 'D':
      self.rect.x += TUILE_TAILLE
      self.DIRECTION = '-'
    elif self.DIRECTION == 'H':
      self.rect.y -= TUILE_TAILLE
      self.DIRECTION = '-'
    elif self.DIRECTION == 'B':
      self.rect.y += TUILE_TAILLE
      self.DIRECTION = '-'

    LISTE_COLLISION_MUR = pygame.sprite.spritecollide(self, LISTE_MURS, False)
    if len(LISTE_COLLISION_MUR) > 0:
      self.rect.x = X_COURANT
      self.rect.y = Y_COURANT

    LISTE_COLLISION_MONSTRES = pygame.sprite.spritecollide(self,LISTE_MONSTRES,False)
    if len(LISTE_COLLISION_MONSTRES) > 0:
      self.TERMINE = True

    LISTE_COLLISION_OBJET = pygame.sprite.spritecollide(self, LISTE_OBJETS, False)
    for objet in LISTE_COLLISION_OBJET:
      objet.kill()
      self.POINTS += POINT_UNITE
      if self.POINTS == 10:
        self.chrono.stop()

class Monstres(pygame.sprite.Sprite):
  def __init__(self):
    pygame.sprite.Sprite.__init__(self)
    self.image = pygame.image.load("PERSONNAGE.png").convert_alpha()
    self.rect = self.image.get_rect()
    self.rect.y = random.randint(0,TUILE_NOMBRE -1) * TUILE_TAILLE + SCORE_HAUTEUR
    self.rect.x = random.randint(0,TUILE_NOMBRE - 1) * TUILE_TAILLE

  def update(self):
    X_courant = self.rect.x
    Y_courant = self.rect.y

    if self.rect.x < _personnage.rect.x:
      self.rect.x += TUILE_TAILLE
    elif self.rect.x > _personnage.rect.x:
      self.rect.x -= TUILE_TAILLE
    elif self.rect.y < _personnage.rect.y:
      self.rect.y += TUILE_TAILLE
    elif self.rect.y > _personnage.rect.y:
      self.rect.y -= TUILE_TAILLE

class Chrono:
  def __init__(self):
    self.Timer = datetime.combine(date.today(), time(0, 0))
    self.STOP = False

  def stop(self):
    self.STOP = True

  def update(self, dt):
    if self.STOP == False:
      self.Timer += timedelta(milliseconds=dt)

Merci de votre aide

Dernière modification par chris7522 (Le 13/01/2022, à 15:08)

Hors ligne

#2 Le 10/01/2022, à 08:45

Compte supprimé

Re : [RESOLU]Accès a rect.x d'une autre classe (python)

Bonjour Chris,
Ton souci est lié à ce qu'on appelle la portée de variable, qui est une notion de base à maitriser roll (normalement bien avant de vouloir jouer pygame):
Ton instance n'existe que dans le main, si tu ne la communiques pas à ta classe Monstre, celle-ci ne peut pas en avoir connaissance.

#3 Le 10/01/2022, à 09:25

chris7522

Re : [RESOLU]Accès a rect.x d'une autre classe (python)

Bonjour.
Merci de ton aide .
Oui j'y avais pensé bien sûr mais puis je importer le main.py dans classe.py sachant que classe.py est déjà importé dans main.py ?
Sinon , j'ai pensé a mettre une classe par fichier et pas toutes mes classes dans le même comme en ce moment , ainsi , il devient plus aisé de faire mes imports . J'importerai ma classe Personnage dans ma classe Monstre et ça devrait fonctionner .
Qu'en pensez-tu ?

Hors ligne

#4 Le 10/01/2022, à 10:24

Compte supprimé

Re : [RESOLU]Accès a rect.x d'une autre classe (python)

Tu te fais des nœuds. Il te suffit de transmettre ton instance à ta classe comme un argument.

class personnage:
    def __init__(self):
        self.attribut = "attribut youplaboum de la classe personnage"
class Monstre:
    def __init__(self,instance_pers):
        self.instance_pers = instance_pers
    def yop(self):
        print(f"Depuis ma classe Monstre j'accéde à l'{self.instance_pers.attribut}")

if __name__ == "__main__":
    p = personnage()
    m = Monstre(p)
    m.yop()

#5 Le 10/01/2022, à 14:50

chris7522

Re : [RESOLU]Accès a rect.x d'une autre classe (python)

Mille mercis !
Je me suis fatigué les yeux hier une bonne partie de l'après midi pour trouver une solution .
Pour ce qui est de l'objet , jusqu'à présent , je n'ai fait que de la théorie et peu de mise en pratique . Difficile de progresser sans mettre les mains dans le cambouis !
Avec toute l'aide que tu m'as déjà apporté , je vais devoir t'offrir une bonne bouteille big_smile
Arigato sensei !

Hors ligne

#6 Le 10/01/2022, à 15:18

Compte supprimé

Re : [RESOLU]Accès a rect.x d'une autre classe (python)

Oui oui offre moi une bouteille tongue . D'ailleurs je me demande bien ce que peut boire un breton japonais... lol

#7 Le 10/01/2022, à 23:05

Compte supprimé

Re : [RESOLU]Accès a rect.x d'une autre classe (python)

Pas la moindre idée. Regarde sur ton moteur de recherche avec un copier coller de ton erreur mis entre guillemet... (1er et 2eme ligne)