Python 为什么我要在PyGame中使用空白灰色背景而不是动画?

Python 为什么我要在PyGame中使用空白灰色背景而不是动画?,python,python-3.x,pygame,Python,Python 3.x,Pygame,我正在创建环境类。函数init应构建模拟环境,而函数run应在10秒内在此环境中执行不同的事件 下面我将分享我代码的一些主要部分。当我运行env=Environment(“TEST”)env.run()(见下文)时,会出现灰色屏幕的窗口。然后它在10秒内关闭。此屏幕中看不到任何内容。只是灰色的背景。但是,我没有收到任何错误消息 我在环境中做错了什么 只需提到,当我将Environment的整个代码直接放在main循环中时,即当Environment类不存在时,相同的代码工作得很好 import

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

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

我在
环境中做错了什么

只需提到,当我将
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.\uuuuu init\uuuuu
方法中的
所有\u Sprite
参数传递给
Sprite
类的
方法,以便将Sprite添加到此组中

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

在while循环中,您需要blit一个背景表面或每帧填充屏幕以清除它,然后绘制精灵,最后使用
pygame.display.flip()
(您需要在示例中缩进它)更新屏幕


请修复行的缩进
def reset(self,location):
。修复后,我得到了
AttributeError:“Worker”对象没有属性“get\u image”
。您正在运行的代码是否与发布的代码相同?@MichealO'Dwyer:已修复。在这里,我发布了我的代码的简化版本。抱歉,我错过了
get\u image
方法和
image\u CACHE
变量。现在它应该和我的笔记本电脑一样,你应该看到一个空白的灰色屏幕仍然有遗漏<代码>图像\u缓存
不在工作者类中,已设置了复制图片的功能,并且
地理围栏
不可用。这段代码没有多大帮助。而且你似乎还没有自己调试过。@colidyre:我刚刚在笔记本电脑上调试过。现在它正在运行并复制我在线程中评论的问题。只是想知道。您真的不应该保留在
\uuuu init\uuuu(…)
中创建的Worker对象的副本吗?似乎它应该作为env对象的成员添加到workers列表中。当您退出
\uuuu init\uuuu
时,工作对象可能会被销毁。只是一种预感,不确定。如果你需要计时器,请查看以下解决方案:谢谢。我听从了你的指示。我对所有精灵都有问题。如果我像你显示的那样在
列表中传递
all\u sprites
,那么在我的真实代码中,我会得到错误
NameError:name'all\u sprites'未定义在以下行中:
self.icon=icon(self.emo\u图像[self.emo\u state],self.rect.bottomright)。self.icon.add(所有精灵)
Worker
的init`函数中。然而,当我没有使用
Environment
class时,我并没有得到这个错误。您知道如何修复它吗?如果您需要
\uuuu init\uuuu
方法中的
所有精灵
参数,请将其作为单独的参数再次传递,或者将
所有精灵
替换为
组[0]
groups
参数实际上是一个列表,星号
*
表示在
位置
之后传递的所有参数都将附加到此列表中。因此,如果将
self.all_sprites,self.workers
作为第六个和第七个参数传递,则组将是一个列表,其中
self.all_sprites
作为第一个元素,而
self.workers
作为第二个元素。
# 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 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)