PYGAME: как сопоставить 2 группы спрайтов из 2 классов и «AttributeError: тип объекта« Player »не имеет атрибута« rect »» - PullRequest
1 голос
/ 20 апреля 2020

Я хотел бы столкнуть cible и снаряд, когда они сталкиваются, они исчезли. Чтобы узнать, обнаружено ли столкновение, я положил отпечаток. Если вы знаете команду для удаления двух столкнувшихся объектов, это было бы круто:)

There is also an error :"AttributeError: type object 'Player' has no attribute 'rect'"

Вот мой код:

#                     --- Import des bibliothèques utilisées (dont pygame) ---
import pygame
from pygame import*
from pygame.locals import *
pygame.init()
from random import *


#                                      --- Classe du jeu ---

class Jeux:

    def __init__(self):
        # generer notre joueur
        self.all_players = pygame.sprite.Group()
        self.player = Player()
        self.all_players.add(self.player)
        # groupe de cible
        self.all_cibles = pygame.sprite.Group()
        self.all_projectiles = pygame.sprite.Group()
        self.pressed = {}

        collisions = pygame.sprite.spritecollide(Cible, Projectile, False)
        if collisions:
            print('collision')

#                                     --- Classe du joueur ---

class Player(pygame.sprite.Sprite):

    def __init__(self):
        super().__init__()
        self.attack = 10
        self.velocity = 7
        """self.all_players = pygame.sprite.Group()
        self.all_projectiles = pygame.sprite.Group()"""
        self.all_cibles = pygame.sprite.Group()
        self.image = pygame.image.load("F:/ISN/game/ressource/vaisseau1.png")
        self.rect = self.image.get_rect()
        self.rect.x = 0
        self.rect.y = 600

    def launch_projectile(self):
        self.all_projectiles.add(Projectile(self))

    def launch_cible(self):
        self.all_cibles.add(Cible(self))

# fonction pour aller a droite
    def move_right(self):
        self.rect.x += self.velocity

# fonction pour aller a gauche
    def move_left(self):
        self.rect.x -= self.velocity


#                                 --- Classe du projectile ---

class Projectile(pygame.sprite.Sprite):
    def __init__(self, player, game):
        super().__init__()
        self.velocity = 7
        self.player = player
        self.projectile = projectile
        self.image = pygame.image.load("F:/ISN/game/ressource/projectile-png-2.png")
        self.image = pygame.transform.scale(self.image, (10, 20))
        self.rect = self.image.get_rect()
        self.all_projectiles.add(self.projectile)
        self.rect.x = player.rect.x + 59
        self.rect.y = player.rect.y

    # fonction servant à détruire le projectile quand il est hors de la fenêtre
    def remove_projectile(self):
        self.player.all_projectiles.remove(self)

    def move(self):
        self.rect.y -= self.velocity

    # vérifier si notre projectile n'est plus présent sur l'écran
        if self.rect.y < 0:
            # supprimer le projectile
            self.remove_projectile()


#                                 --- Classe de la cible ---

class Cible(pygame.sprite.Sprite):
    def __init__(self, game, player):
        super().__init__()
        self.game = game
        self.cible = cible
        self.image = pygame.image.load("F:/ISN/game/ressource/catalan.png")
        self.image = pygame.transform.scale(self.image, (40, 40))
        self.rect = self.image.get_rect()
        self.all_cibles.add(self.cible)
        self.rect.x = randint(50, 1000)
        self.rect.y = randint(0, 400)

    def remove_cible(self):
        self.player.all_cibles.remove(self)

    if pygame.sprite.spritecollide(Player, Projectile, False):
        print('Collide')



#                      --- Gestion des touches et de la fenêtre de jeu ---

clock = pygame.time.Clock()

# generer la fenetre du jeu
pygame.display.set_caption("SPACE INVADERS V2")
screen = pygame.display.set_mode((1080, 720))

# importer charger l'arriere plan
background = pygame.image.load("F:/ISN/game/ressource/BACKGROUND.jpg")

# charger notre jeu
game = Jeux()


running = True
# boucle tant que cette condition est vrai
while running:

    # appliquer l'arriere plan de notre jeu
    screen.blit(background, (0, 0))

    # appliquer l'image de notre joueur sur la fenetre de jeu
    screen.blit(game.player.image, game.player.rect)

    # afficher la cible 
    game.player.all_cibles.draw(screen)

    # recuperer les projectiles du joueur
    for projectile in game.player.all_projectiles:
        projectile.move()

    # appliquer l'ensemble des images de mon groupe de projectiles
    game.player.all_projectiles.draw(screen)

    # mouvements du joueur
    if game.pressed.get(pygame.K_RIGHT) and game.player.rect.x + game.player.rect.width < screen.get_width():
        game.player.move_right()
    elif game.pressed.get(pygame.K_LEFT) and game.player.rect.x > 0:
        game.player.move_left()

    # mettre a jour l'ecran
    pygame.display.flip()

    # si le joueur ferme cette fenetre
    for event in pygame.event.get():
        # que l'evenement est fermeture de fenetre
        if event.type == pygame.QUIT:
            running = False
            pygame.quit()
            print("Fermeture du jeu")
        # detecter si un joueur lache une touche du clavier
        elif event.type == pygame.KEYDOWN:
           game.pressed[event.key] = True
           if event.key == pygame.K_SPACE:
               game.player.launch_projectile()
           elif event.key == pygame.K_DOWN:
               game.player.launch_cible()
        elif event.type == pygame.KEYUP:
            game.pressed[event.key] = False

Надеюсь не знаю, как это сделать, пожалуйста, помогите мне

1 Ответ

2 голосов
/ 21 апреля 2020

1-й аргумент pygame.sprite.spritecollide() должен быть экземпляром pygame.sprite.Sprite, а 2-й аргумент должен быть экземпляром pygame.sprite.Group .
Таким образом, pygame.sprite.spritecollide(Cible, Projectile, False) не имеет никакого смысла, потому что Cible и Projectile являются классами.

self.all_cibles и self.all_projectiles являются экземплярами pygame.sprite.Group. Столкновение групп можно оценить по pygame.sprite.groupcollide(). Например:

collisions = pygame.sprite.groupcollide(
    self.all_projectiles, self.all_cibles, False, False)

Передав True аргументу dokill1 соответственно dokill2, Sprites можно удалить из всех Groups и, таким образом, уничтожить.
Например, передать False до dokill1 и True до dokill2, таким образом, снаряды будут уничтожать библии:

collisions = pygame.sprite.groupcollide(
    self.all_projectiles, self.all_cibles, False, True)      

Если вы хотите выполнить тест на столкновение, то вы должны сделать это в Основное применение л oop. Например:

running = True
# boucle tant que cette condition est vrai
while running:
    # [...]

    collisions = pygame.sprite.groupcollide(game.all_projectiles, game.all_cibles, False, True)
    if collisions:
        print('collision')

    if pygame.sprite.spritecollide(game.player, game.all_projectiles, False):
        print('Collide')

Полный код может выглядеть следующим образом:

#                     --- Import des bibliothèques utilisées (dont pygame) ---
import pygame
from pygame import*
from pygame.locals import *
pygame.init()
from random import *

#                                      --- Classe du jeu ---
class Jeux:

    def __init__(self):
        # generer notre joueur
        self.all_players = pygame.sprite.Group()
        self.player = Player()
        self.all_players.add(self.player)
        # groupe de cible
        self.all_cibles = pygame.sprite.Group()
        self.all_projectiles = pygame.sprite.Group()
        self.pressed = {}

#                                     --- Classe du joueur ---
class Player(pygame.sprite.Sprite):

    def __init__(self):
        super().__init__()
        self.attack = 10
        self.velocity = 7
        """self.all_players = pygame.sprite.Group()
        self.all_projectiles = pygame.sprite.Group()"""
        self.image = pygame.image.load("F:/ISN/game/ressource/vaisseau1.png")
        self.rect = self.image.get_rect()
        self.rect.x = 0
        self.rect.y = 600

    def launch_projectile(self):
        game.all_projectiles.add(Projectile(self, game))

    def launch_cible(self):
        game.all_cibles.add(Cible(self, game))

# fonction pour aller a droite
    def move_right(self):
        self.rect.x += self.velocity

# fonction pour aller a gauche
    def move_left(self):
        self.rect.x -= self.velocity


#                                 --- Classe du projectile ---
class Projectile(pygame.sprite.Sprite):
    def __init__(self, player, game):
        super().__init__()
        self.velocity = 7
        self.game = game
        self.player = player
        self.image = pygame.image.load("F:/ISN/game/ressource/projectile-png-2.png")
        self.image = pygame.transform.scale(self.image, (10, 20))
        self.rect = self.image.get_rect()
        self.game.all_projectiles.add(self)
        self.rect.x = player.rect.x + 59
        self.rect.y = player.rect.y

    # fonction servant à détruire le projectile quand il est hors de la fenêtre
    def remove_projectile(self):
        self.game.all_projectiles.remove(self)

    def move(self):
        self.rect.y -= self.velocity

    # vérifier si notre projectile n'est plus présent sur l'écran
        if self.rect.y < 0:
            # supprimer le projectile
            self.remove_projectile()


#                                 --- Classe de la cible ---
class Cible(pygame.sprite.Sprite):
    def __init__(self, player, game):
        super().__init__()
        self.game = game
        self.image = pygame.image.load("F:/ISN/game/ressource/catalan.png")
        self.image = pygame.transform.scale(self.image, (40, 40))
        self.rect = self.image.get_rect()
        self.game.all_cibles.add(self)
        self.rect.x = randint(50, 1000)
        self.rect.y = randint(0, 400)

    def remove_cible(self):
        self.game.all_cibles.remove(self)


#                      --- Gestion des touches et de la fenêtre de jeu ---
clock = pygame.time.Clock()

# generer la fenetre du jeu
pygame.display.set_caption("SPACE INVADERS V2")
screen = pygame.display.set_mode((1080, 720))

# importer charger l'arriere plan
background = pygame.image.load("F:/ISN/game/ressource/BACKGROUND.jpg")

# charger notre jeu
game = Jeux()


running = True
# boucle tant que cette condition est vrai
while running:

    # appliquer l'arriere plan de notre jeu
    screen.blit(background, (0, 0))

    # appliquer l'image de notre joueur sur la fenetre de jeu
    screen.blit(game.player.image, game.player.rect)

    # afficher la cible 
    game.all_cibles.draw(screen)

    # recuperer les projectiles du joueur
    for projectile in game.all_projectiles:
        projectile.move()

    # appliquer l'ensemble des images de mon groupe de projectiles
    game.all_projectiles.draw(screen)

    # mouvements du joueur
    if game.pressed.get(pygame.K_RIGHT) and game.player.rect.x + game.player.rect.width < screen.get_width():
        game.player.move_right()
    elif game.pressed.get(pygame.K_LEFT) and game.player.rect.x > 0:
        game.player.move_left()

    # mettre a jour l'ecran
    pygame.display.flip()

    # si le joueur ferme cette fenetre
    for event in pygame.event.get():
        # que l'evenement est fermeture de fenetre
        if event.type == pygame.QUIT:
            running = False
            pygame.quit()
            print("Fermeture du jeu")
        # detecter si un joueur lache une touche du clavier
        elif event.type == pygame.KEYDOWN:
           game.pressed[event.key] = True
           if event.key == pygame.K_SPACE:
               game.player.launch_projectile()
           elif event.key == pygame.K_DOWN:
               game.player.launch_cible()
        elif event.type == pygame.KEYUP:
            game.pressed[event.key] = False

    collisions = pygame.sprite.groupcollide(game.all_projectiles, game.all_cibles, False, True)
    if collisions:
        print('collision')

    if pygame.sprite.spritecollide(game.player, game.all_projectiles, False):
        print('Collide')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...