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)