【问题标题】:Why does .kill() leave sprites on screen instead of destroying?为什么 .kill() 将精灵留在屏幕上而不是销毁?
【发布时间】:2020-05-22 23:51:38
【问题描述】:

我正在为精灵编写代码,一旦它离开屏幕,.kill() 命令就会将其删除。相反,它只是打印出值,它仍然会下降。我提到的部分包括 run.play 和 Note 类的更新,其中代码包含 .kill()

代码:

import pygame, sys, time, os

os.environ["SDL_VIDEO_CENTERED"] = "1"

win_width = 900
win_height = 700
fps = 60
white = (255, 255, 255)
black = (0, 0, 0)
grey = (80, 80, 80)
q_note = 98
w_note = 188
o_note = 278
p_note = 368


class Game:
    def __init__(self):
        self.clock = pygame.time.Clock()
        self.fps = 60
        self.init = pygame.init()
        self.caption = pygame.display.set_caption("BYOG")
        self.screen = pygame.display.set_mode((win_width, win_height), pygame.SRCALPHA)
        self.intro = True
        self.how_2_play = self.play = False


class Text:
    def __init__(self, size, text, color, xpos, ypos):
        self.font = pygame.font.SysFont("Roboto Mono", size)
        self.image = self.font.render(text, 1, color)
        self.rect = self.image.get_rect()
        self.rect = self.rect.move(xpos, ypos)


class Outline(pygame.sprite.Sprite):
    def __init__(self, x, y, x_pos, y_pos):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((x, y)).convert()
        self.image.fill(white)
        self.rect = self.image.get_rect()
        self.rect = pygame.Rect(x_pos, y_pos, x, y)


class Notes(pygame.sprite.Sprite):
    def __init__(self, x_pos, y_pos, side):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load("images/q_rectangle.png").convert_alpha()
        self.image = pygame.transform.scale(self.image, (97, 55))
        self.rect = self.image.get_rect()
        self.rect = pygame.Rect(x_pos, y_pos, 90, 50)
        self.close = 0
        self.type = side

    def update(self, screen_group):
        self.rect.y += 6

        if 300 <= self.rect.y <= 460:
            self.close = 1
        if 461 <= self.rect.y <= 480:
            self.close = 2
        if 481 <= self.rect.y <= 500:
            self.close = 3
        if self.rect.y > 500:
            self.close = 4

        if self.rect.bottom > 0:
            screen_group.add(self)
        elif self.rect.top > win_height:
            self.kill()


def main():
    # Initial Variable
    run = Game()
    run.screen.fill(white)
    run.clock.tick(fps)
    pygame.display.flip()
    intro_music = pygame.mixer.Sound("Sounds/intro_song.ogg")
    game_music = pygame.mixer.Sound("Sounds/back_song.ogg")

    # Group
    note_group = pygame.sprite.Group()
    note_screen_group = pygame.sprite.Group()
    bracket_group = pygame.sprite.Group()

    # Objects
    boundary1 = Outline(2, 600, 100, 0)
    boundary2 = Outline(2, 600, 190, 0)
    boundary3 = Outline(2, 600, 280, 0)
    boundary4 = Outline(2, 600, 370, 0)
    boundary5 = Outline(2, 600, 460, 0)
    boundary6 = Outline(360, 2, 100, 450)
    boundary7 = Outline(360, 2, 100, 500)
    boundary8 = Outline(360, 2, 100, 600)

    n1 = Notes(q_note, -200, "q")
    n2 = Notes(w_note, -800, "w")
    n3 = Notes(o_note, -600, "o")
    n4 = Notes(p_note, -400, "p")

    intro_back = pygame.image.load("images/intro_back.jpg")
    intro_back = pygame.transform.scale(intro_back, (win_width, win_height))
    intro_rect = intro_back.get_rect()

    play_back = pygame.image.load("images/background_game.jpg")
    play_back = pygame.transform.scale(play_back, (win_width, win_height))
    play_rect = play_back.get_rect()

    intro_title = Text(150, "Osu!Mania", white, win_width / 5, win_height / 2 - 250)
    start_button = Text(75, "Start", white, win_width / 5 + 210, win_height / 2 + 175)
    start = run.screen.blit(start_button.image, start_button.rect)
    how_to_play = Text(75, "How to Play", white, win_width / 5 + 125, win_height / 2 + 250)
    question = run.screen.blit(how_to_play.image, how_to_play.rect)

    note_all_array = [n1, n2, n3, n4]
    bracket_group.add(boundary1, boundary2, boundary3, boundary4, boundary5, boundary6, boundary7, boundary8)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                pygame.quit()
                sys.exit()

    intro_music.play(-1)
    intro_music.set_volume(0.3)
    run.clock.tick(fps)
    pygame.display.flip()

    while run.intro:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            if event.type == pygame.MOUSEBUTTONUP:
                mouse = pygame.mouse.get_pos()
                if question.collidepoint(mouse):
                    run.intro = False
                    run.how_2_play = True
                elif start.collidepoint(mouse):
                    run.intro = False
                    run.play = True
                    intro_music.stop()
                    game_music.play(0)
                    game_music.set_volume(0.3)
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    pygame.quit()
                    sys.exit()

        run.screen.blit(intro_back, intro_rect)
        run.screen.blit(start_button.image, start_button.rect)
        run.screen.blit(intro_title.image, intro_title.rect)
        run.screen.blit(how_to_play.image, how_to_play.rect)

        run.clock.tick(fps)
        pygame.display.flip()

    while run.how_2_play:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    pygame.quit()
                    sys.exit()

        run.screen.fill(grey)
        run.clock.tick(fps)
        pygame.display.flip()

    while run.play:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                for n in note_screen_group:
                    if event.key == pygame.K_q:
                        if n.close == 1 and n.type == "q":
                            print("one")
                            n.kill()
                        elif n.close == 2 and n.type == "q":
                            print("two")
                            n.kill()
                        elif n.close == 3 and n.type == "q":
                            print("three")
                            n.kill()
                        elif n.close == 4 and n.type == "q":
                            print("four")
                            n.kill()
                    elif event.type == pygame.KEYDOWN and event.key == pygame.K_w:
                        if n.close == 1 and n.type == "w":
                            print("one")
                            n.kill()
                        elif n.close == 2 and n.type == "w":
                            print("two")
                            n.kill()
                        elif n.close == 3 and n.type == "w":
                            print("three")
                            n.kill()
                        elif n.close == 4 and n.type == "w":
                            print("four")
                            n.kill()
                    elif event.type == pygame.KEYDOWN and event.key == pygame.K_o:
                        if n.close == 1 and n.type == "o":
                            print("one")
                            n.kill()
                        elif n.close == 2 and n.type == "o":
                            print("two")
                            n.kill()
                        elif n.close == 3 and n.type == "o":
                            print("three")
                            n.kill()
                        elif n.close == 4 and n.type == "o":
                            print("four")
                            n.kill()
                    elif event.type == pygame.KEYDOWN and event.key == pygame.K_p:
                        if n.close == 1 and n.type == "p":
                            print("one")
                            n.kill()
                        elif n.close == 2 and n.type == "p":
                            print("two")
                            n.kill()
                        elif n.close == 3 and n.type == "p":
                            print("three")
                            n.kill()
                        elif n.close == 4 and n.type == "p":
                            print("four")
                            n.kill()

        run.screen.blit(play_back, play_rect)

        for n in note_all_array:
            n.update(note_screen_group)

        note_screen_group.draw(run.screen)

        bracket_group.draw(run.screen)
        run.clock.tick(fps)
        pygame.display.flip()


if __name__ == "__main__":
    while True:
        main()

感谢任何帮助,我正在 python 3 上运行 pygame 1.9.6。谢谢!

【问题讨论】:

    标签: python pygame sprite kill


    【解决方案1】:

    没有在屏幕上绘制您未绘制的内容。

    如果你想从屏幕上移除一个图像,你必须在它的位置画一些东西。通常你会重绘部分背景。

    当您kill() 一个精灵时,它会从所有精灵组中删除,因此不会被调用,但这就是所有发生的事情。 kill() 不会导致任何其他操作 - 例如以某种方式从显示表面移除其图像。除非重新绘制整个屏幕(通过背景填充或其他方式),否则kill()ed 精灵图像将保留在屏幕上,直到有东西覆盖它。如果每帧不重绘背景,则需要重绘精灵用来覆盖的背景部分,或者在此处绘制其他东西来覆盖旧的精灵图像。

    【讨论】:

    • 对不起,大部分代码由于某种原因丢失了,这是没有有效使用kill的代码。
    • 我使用图像作为背景和注释。 screen.blit in while play 放置背景。
    【解决方案2】:

    您每帧都将精灵添加回组中(在Notes .update() 方法中)。因此,当您调用 .kill()(从组中删除精灵)时,您会立即将其添加回来。

    # Up here you kill the note.
    
    for n in note_all_array:
        n.update(note_screen_group)  # Here you add the note back.
    
    note_screen_group.draw(run.screen)  # Here you draw the note
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-05
      • 1970-01-01
      • 2014-08-26
      • 2014-10-11
      • 1970-01-01
      • 1970-01-01
      • 2020-04-20
      • 2011-11-06
      相关资源
      最近更新 更多