问题描述
我正在创建 Environment
类.函数init
应该构建模拟环境,而函数run
应该在10秒内在这个环境中执行不同的事件.
I am creating the Environment
class. The function init
should build the simulated environment, while the function run
should execute different events in this environment during 10 seconds.
下面我分享我的代码的一些主要部分.当我运行 env = Environment("TEST") env.run()
(见下文)时,出现灰屏窗口.然后它会在 10 秒内关闭.此屏幕中没有任何内容.这只是一个灰色的背景.但是,我没有收到任何错误消息.
Below I share some major parts of my code. When I run env = Environment("TEST") env.run()
(see below), the window with grey screen appears. Then it closes in 10 seconds. Nothing is visible in this screen. It's just a grey background. However, I do not get any error message.
我在 Environment
类中做错了什么?
What am I doing wrong in the Environment
class?
只是提一下,当我将 Environment
的整个代码直接放在 main
循环中时,相同的代码可以正常工作,即当 Environment
类不存在.
Just to mention that the same code worked fine when I had the whole code of Environment
placed directly in main
loop, i.e. when Environment
class has not existed.
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
参数传递给 __init__
方法,以便将精灵添加到该组中.Sprite
类的
You have to pass the all_sprites
argument in the Worker.__init__
method to the __init__
method of the Sprite
class, so that the sprite will be added to this group.
pygame.sprite.Sprite.__init__(self, all_sprites, groups)
您还可以重新排列 __init__
方法的参数并将这两个组作为最后一个参数传递(它们将被添加到 groups
列表中).
You could also rearrange the parameters of the __init__
method and pass the two groups as the last arguments (they will be added to the groups
list).
# 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 循环中,您需要在每一帧中对背景表面进行 blit 或填充屏幕以清除它,然后绘制精灵,最后使用 pygame.display.flip()
更新屏幕(您需要在示例中缩进).
In the while loop you need to blit a background surface or fill the screen every frame in order to clear it, then draw the sprites and finally update the screen with pygame.display.flip()
(you need to indent it in your example).
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)
这篇关于为什么我在 PyGame 中得到空白的灰色背景而不是动画?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!