python - 为什么我在 PyGame 中得到空白的灰色背景而不是动画?

标签 python python-3.x pygame

我正在创建Environment类。函数 init 应该构建模拟环境,而函数 run 应该在 10 秒内在此环境中执行不同的事件。

下面我分享我的代码的一些主要部分。当我运行 env = Environment("TEST") env.run() (见下文)时,出现灰屏窗口。然后它会在 10 秒后关闭。此屏幕中看不到任何内容。这只是一个灰色的背景。但是,我没有收到任何错误消息。

我在Environment类中做错了什么?

只需提一下,当我将Environment的整个代码直接放置在main循环中时,即当Environment时,相同的代码工作得很好类不存在。

import numpy as np
import pygame
import random

WHITE = (255, 255, 255)
GREEN = (20, 255, 140)
GREY = (210, 210, 210)

SCREENWIDTH = 1000
SCREENHEIGHT = 578

IMG_WORKER_RUNNING = "images/workers/worker_1.png"
IMG_WORKER_IDLE = "images/workers/worker_2.png"
IMG_WORKER_ACCIDENT = "images/workers/accident.png"


class Worker(pygame.sprite.Sprite):
    RUNNING = 0
    IDLE = 1
    ACCIDENT = 2
    NUMBER_OF_ACCIDENTS = 0
    IMAGE_CACHE = {}

    def __init__(self, idw, image_running, image_idle, image_accident,
                 all_sprites, location, *groups):
        # Each state has it's own image
        self.images = {
            Worker.RUNNING: pygame.transform.scale(
                self.get_image(image_running),
                (45, 45)
            ),
            Worker.IDLE: pygame.transform.scale(
                self.get_image(image_idle),
                (20, 45)
            ),
            Worker.ACCIDENT: pygame.transform.scale(
                self.get_image(image_accident),
                (40, 40)
            )
        }

        self._layer = 2
        pygame.sprite.Sprite.__init__(self, groups)
        self.idw = idw
        self.reset(location)

    def reset(self, location):
        self.state = Worker.IDLE
        self.ticks_in_state = 0

        self.location = location
        self.image = self.images[self.state]
        self.rect = self.image.get_rect(topleft=location)

        self.direction = pygame.math.Vector2(0, 0)
        self.speed = random.randint(1, 3)

    def get_image(self, key):
        if not key in Worker.IMAGE_CACHE:
            Worker.IMAGE_CACHE[key] = pygame.image.load(key)
        return Worker.IMAGE_CACHE[key]


class Environment:
    def __init__(self, title):
        pygame.init()

        self.screen = pygame.display.set_mode((SCREENWIDTH, SCREENHEIGHT))
        pygame.display.set_caption(title)

        self.all_sprites = pygame.sprite.LayeredUpdates()
        self.workers = pygame.sprite.Group()
        self.fences = pygame.sprite.Group()

        # create a worker
        idw = 1
        Worker(idw, IMG_WORKER_RUNNING, IMG_WORKER_IDLE,
               IMG_WORKER_ACCIDENT, self.all_sprites, (50, 50), 
               self.workers)

    def run(self):
        carry_on = True
        clock = pygame.time.Clock()
        simulation_time = 10  # time in seconds

        while carry_on:
            for event in pygame.event.get():
                if (event.type == pygame.QUIT) or (simulation_time == 0):
                    carry_on = False
                    pygame.display.quit()
                    pygame.quit()
                    quit()

                simulation_time -= 1

            agent_action = 0
            send_alert = np.random.normal(0, 0.1, 1)

            if send_alert > 0.2:
                agent_action = 1

            self.all_sprites.update(self.screen, agent_action)
            self.all_sprites.draw(self.screen)

        pygame.display.flip()
        clock.tick(20)


if __name__ == "__main__":
    env = Environment("TEST")
    env.run()

最佳答案

您必须将 Worker.__init__ 方法中的 all_sprites 参数传递给 Sprite__init__ 方法> class,以便将 Sprite 添加到该组中。

pygame.sprite.Sprite.__init__(self, all_sprites, groups)

您还可以重新排列 __init__ 方法的参数,并将这两个组作为最后一个参数传递(它们将被添加到 groups 列表中)。

# In the Worker class.
def __init__(self, idw, image_running, image_idle, image_accident,
             location, *groups):

# Pass the two groups as the `groups` argument.
Worker(idw, IMG_WORKER_RUNNING, IMG_WORKER_IDLE,
       IMG_WORKER_ACCIDENT, (50, 50), self.all_sprites, 
       self.workers)

在 while 循环中,您需要位 block 传输背景表面或每帧填充屏幕以清除它,然后绘制 Sprite ,最后使用 pygame.display.flip() 更新屏幕(您需要在示例中缩进它)。

while carry_on:
    for event in pygame.event.get():
        if (event.type == pygame.QUIT) or (simulation_time == 0):
            carry_on = False
        # You probably don't want to decrement the
        # simulation_time once per event. Dedent
        # this line to decrement it once per frame.
        simulation_time -= 1

    agent_action = 0
    send_alert = np.random.normal(0, 0.1, 1)

    if send_alert > 0.2:
        agent_action = 1

    self.all_sprites.update(self.screen, agent_action)
    # Blit a background surface or fill the screen.
    self.screen.fill((0, 40, 0))  # Fill with dark green.
    # Blit all sprites.
    self.all_sprites.draw(self.screen)
    # Update the screen.
    pygame.display.flip()
    clock.tick(20)

关于python - 为什么我在 PyGame 中得到空白的灰色背景而不是动画?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51848277/

相关文章:

python - 如何增加 tkinter(Python) 中输入(显示)框的大小(高度)?

python - 如何在 python 中编写按钮(不使用 Tkinter)?

python - 打印图像时,什么决定了它在页面上的显示大小?

python - 替代WITH RECURSIVE 子句

python - 打字界面

Python 将 float 误认为字符串

python - 为什么 sympy.simplify 会改变随机状态

python - 检查一个点是否与pygame中的表面(像素完美)碰撞

python - 我应该将我的游戏放在 pygame 类中吗?

python - 在两个 for 循环中迭代列表元素