python - pygame sprite.spritecollide() 不适用于移动 Sprite 组

标签 python pygame sprite

当我的玩家 Sprite 与硬币组碰撞时,硬币会按需要消失,但是当它与敌人组碰撞时,什么也不会发生。代码是一样的。我不知道我做错了什么,因为我做了两次同样的事情,但只成功了一次。和敌人的移动有关系吗?这是代码:

import pygame as pg
import random

a_white = (245, 245, 245)
a_red = (10, 0, 0)
black = (0, 0, 0)
white = (255, 255, 255)
blue_grey = (51, 93, 127)
dark_red = (85, 0, 0)
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
yellow = (255, 255, 0)
bg_color = dark_red

width = 600
height = 500
FPS = 60

p_width = 70
p_height = 70
c_width = 35
c_height = 35
score = 0
level = 0
lives = 3

title = 'This Is My Game!'
pg.init()
pg.mixer.init()
clock = pg.time.Clock()
screen = pg.display.set_mode((width, height))
pg.display.set_caption(title)
font_name = pg.font.match_font("arial")
coin_img = pg.image.load('coin3.png').convert()
player_img = pg.image.load('smiley.png').convert_alpha()
gegner_1 = pg.image.load('gegner_black.png').convert_alpha()
coin_snd = pg.mixer.Sound('coin_snd_2.ogg')


def new_coin():
    x = random.randrange(c_width, width - c_width)
    y = random.randrange(c_height, height - c_height)
    coins = Coin(x, y)
    all_sprites.add(player, coins)
    coin_group.add(coins)


def draw_text(screen, text, t_color, size, t_x, t_y):
    font = pg.font.Font(font_name, size)
    text_surface = font.render(text, True, t_color)
    text_rect = text_surface.get_rect()
    text_rect.midtop = (t_x, t_y)
    screen.blit(text_surface, text_rect)


def start_screen():
    screen.fill(bg_color)
    draw_text(screen, 'Welcome... !', white, 75, width / 2, height / 4 - 100)
    draw_text(screen, 'ready to play my game*?', white, 24, width - 150, height / 4 - 20)
    draw_text(screen, "Press any key to begin", white, 20, width / 2 + 60, height / 4 + 10)
    draw_text(screen, "*The  name of the game is \'MY GAME\'  but  that ",
              white, 16, width / 2, height - 150)
    draw_text(screen, " has nothing to do  with the fact, that the game is", white, 16, width / 2, height - 130)
    draw_text(screen, "  my  game. Yes, the  game is actually  my game, ", white, 16, width / 2, height - 110)
    draw_text(screen, " but  that\'s not the reason I named  it  my  game. ", white, 16, width / 2, height - 90)
    draw_text(screen, "...or is it?", white, 13, width - 28, height - 20)
    pg.display.update()
    waiting = True
    while waiting:
        clock.tick(FPS)
        for event in pg.event.get():
            if event.type == pg.QUIT:
                pg.quit()
            if event.type == pg.KEYUP:
                waiting = False


class Player(pg.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image_orig = pg.transform.scale(player_img, (p_width, p_height))
        self.image = self.image_orig.copy()
        self.rect = self.image.get_rect()
        self.rect.center = (width / 2), (height / 2)
        self.radius = 35

    def update(self):
        keys = pg.key.get_pressed()
        if keys[pg.K_RIGHT]:
            self.rect.x += 5
        if keys[pg.K_LEFT]:
            self.rect.x -= 5
        if keys[pg.K_UP]:
            self.rect.y -= 5
        if keys[pg.K_DOWN]:
            self.rect.y += 5

        if self.rect.right > width:
            self.rect.right = width
        if self.rect.left < 0:
            self.rect.left = 0
        if self.rect.top < 0:
            self.rect.top = 0
        if self.rect.bottom > height:
            self.rect.bottom = height


class Coin(pg.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pg.transform.scale(coin_img, (c_width, c_height))
        self.image.set_colorkey(white)
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.radius = 18


class Gegner_1(pg.sprite.Sprite):
    def __init__(self, x, y, yon):
        super().__init__()
        self.image_orig = pg.transform.scale(gegner_1, (p_width, p_height))
        self.image_orig.set_colorkey(white)
        self.image = self.image_orig.copy()
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.radius = 35
        self.yon = yon
        if yon == 'yes':
            self.speedx = 5
            self.speed = self.speedx
        elif yon == 'no':
            self.speedy = 5
            self.speed = self.speedy

    def update(self):
        if self.yon == 'yes':
            self.rect.x += self.speed
        if self.yon == 'no':
            self.rect.y += self.speed
        if self.rect.right > width:
            self.speed = -5
        if self.rect.left == 0:
            self.speed = 5
        if self.rect.bottom > height:
            self.speed = -5
        if self.rect.top < 0:
            self.speed = 5


all_sprites = pg.sprite.Group()
coin_group = pg.sprite.Group()
enemys_group = pg.sprite.Group()
player = Player()
gegner1 = Gegner_1(0, 60, 'yes')
gegner2 = Gegner_1(width, 350, 'yes')
gegner3 = Gegner_1(50, p_height, 'no')
gegner4 = Gegner_1(width - p_width - 20, p_height, 'no')

enemys_group.add(gegner1, gegner2, gegner3, gegner4)
all_sprites.add(player)

for c in range(3):
    new_coin()

start_game = True
game_over = False
done = False

while not done:
    for event in pg.event.get():
        if event.type == pg.QUIT:
            done = True
    if start_game:
        start_screen()
        start_game = False

    screen.fill(bg_color)
    if score >= 5:
        all_sprites.add(gegner1)
        if score >= 10:
            all_sprites.add(gegner2)
            if score >= 15:
                all_sprites.add(gegner3)
                if score >= 20:
                    all_sprites.add(gegner4)

    all_sprites.draw(screen)
    all_sprites.update()

    draw_text(screen, 'SCORE: ' + str(score), white, 20, 55, 10)

    hits = pg.sprite.spritecollide(player, coin_group, True, pg.sprite.collide_circle)
    for hit in hits:
        score += 1
        coin_snd.play()
        new_coin()

    hits = pg.sprite.spritecollide(player, enemys_group, True, pg.sprite.collide_circle)
    for hit in hits:
        lives -= 1

    pg.display.update()
    clock.tick(FPS)

pg.quit()

我也没有因此而收到任何错误。

最佳答案

添加和删除 gegner 实例的方式会导致此问题。 enemys_group 在开头包含 gegner,用于碰撞检测。这意味着您可以在它们可见之前与它们发生碰撞(在 for hit in attempts: 循环中打印组和 hit 来检查这一点)。如果您击中一个实例,它会被正确地从 enemys_group 中删除。

然后,如果您达到 5 分或更高的分数,您将继续将仍绑定(bind)到 gegner1 等变量的实例添加到 all_sprites 组中帧,因此 Sprite 变得可见,但如果它们不在 enemys_group 中,它们就不能再发生碰撞。

您需要重构代码。我会在开始时将 enemys_group 留空,然后在硬币碰撞循环中添加 gegner 实例:

hits = pg.sprite.spritecollide(player, coin_group, True, pg.sprite.collide_circle)
for hit in hits:
    score += 1
    new_coin()
    if score == 5:
        gegner = Gegner_1(0, 60, 'yes')
        all_sprites.add(gegner)
        enemys_group.add(gegner)
    elif score == 10:
        gegner = Gegner_1(width, 350, 'yes')
        all_sprites.add(gegner)
        enemys_group.add(gegner)
    elif score == 15:
        gegner = Gegner_1(50, p_height, 'no')
        all_sprites.add(gegner)
        enemys_group.add(gegner)
    elif score == 20:
        gegner = Gegner_1(width - p_width - 20, p_height, 'no')
        all_sprites.add(gegner)
        enemys_group.add(gegner)

关于python - pygame sprite.spritecollide() 不适用于移动 Sprite 组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46613533/

相关文章:

python - Python高效处理邮件列表

python - 字典的打印与返回功能

python - 简单函数内的意外行为,找不到原因

java - 将图像移动到新位置后删除图像

python - 将 RethinkDB 用于 "Full Text Search"

python 3.3 : Unable to load an image using Pygame if game folder is not in C drive

python - 为什么我的 pygame 圈子不断消失并重新产生?

Java CSS Sprite 库

javascript - 如何将我的代码重构为游戏循环?

python - 无法在 ubuntu 中安装 pip?