[英]pygame sprite.Group - passing arguments out of a Group
I'm trying out pygame, using Sprites & Groups, and getting myself a little confused around passing arguments.我正在尝试 pygame,使用 Sprites & Groups,并且让自己对通过 arguments 感到有些困惑。
Basically I have a wrapper class MyGame() as my_game().基本上我有一个包装器 class MyGame() 作为 my_game()。 In that I have pygame.sprite.Group() - all_sprites.
我有 pygame.sprite.Group() - all_sprites。
I then have a class Alien(pygame.sprite.Sprite) for my aliens, and I add each alien to my all_sprites Group.然后我有一个 class Alien(pygame.sprite.Sprite) 用于我的外星人,我将每个外星人添加到我的 all_sprites 组中。
I want my Group of aliens to track across the screen (which they do) and then all drop as a block, a group (which they don't).我希望我的外星人小组在屏幕上跟踪(他们这样做),然后全部作为一个块下降,一个小组(他们没有)。
I can loop through my all_sprites.Group in my main loop after the self.all_sprites.update() and see if alien.rect.right > WIDTH or alien.rect.left < 0, then loop through the Group again calling alien.end_row() then break the loop so it doesn't run for each alien on the screen edge, but that seems very clunky.我可以在 self.all_sprites.update() 之后在我的主循环中循环我的 all_sprites.Group 并查看是否 alien.rect.right > WIDTH 或 alien.rect.left < 0,然后再次循环通过 Group 调用 alien.end_row () 然后打破循环,这样它就不会为屏幕边缘的每个外星人运行,但这看起来很笨拙。
I've tried setting a flag in MyGame self.alien_drop = False but when I try to set my_game.alien_drop = True in the Alien class, it doesn't recognise my_game - not defined.我尝试在 MyGame self.alien_drop = False 中设置一个标志,但是当我尝试在 Alien class 中设置 my_game.alien_drop = True 时,它无法识别 my_game - 未定义。 I'm a little confused as MyGame is creating the instances of Alien, so they should be enclosed by the scope of MyGame?
我有点困惑,因为 MyGame 正在创建 Alien 的实例,所以它们应该被 MyGame 的 scope 包围?
I can pass MyGame self.alien_drop into my Alien init() but when I update the Alien self.alien_drop it doesn't update MyGame.alien_drop.我可以将 MyGame self.alien_drop 传递给 Alien init(),但是当我更新 Alien self.alien_drop 时,它不会更新 MyGame.alien_drop。 Which I get because it's created a new variable local to Alien.
我得到它是因为它创建了 Alien 本地的一个新变量。
There doesn't seem to be a way to pass an argument through Group.update() which I guess is because it's just calling the.update() on all Sprite inside the group.似乎没有办法通过 Group.update() 传递参数,我猜这是因为它只是在组内的所有 Sprite 上调用 the.update() 。 I can't see an easy way to modify the Group.update() function so that I can pass values, and in fairness I probably don't want to go mucking around in there anyway.
我看不到一种简单的方法来修改 Group.update() function 以便我可以传递值,而且公平地说,我可能不想 go 在那里乱七八糟。
I also can't return True back through update().我也无法通过 update() 返回 True。
I'm kinda stuck at this point...我有点卡在这一点上......
I know the self.aliens.row_end() probably won't work, I'll have to loop through self.aliens and call each alien.row_end(), but at the moment it's not even getting to that point.我知道 self.aliens.row_end() 可能不起作用,我将不得不遍历 self.aliens 并调用每个 alien.row_end(),但目前它甚至还没有达到这一点。
import pygame
WIDTH = 360 # width of our game window
HEIGHT = 480 # height of our game window
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
class MyGame():
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
self.clock = pygame.time.Clock()
self.all_sprites = pygame.sprite.Group()
self.alien_drop = False
for row_index in range(4):
for column_index in range(6):
alien = Alien(20 + (column_index * 40), 20 + (row_index *40))
alien.add(self.all_sprites)
while True:
self.screen.fill(BLACK)
self.all_sprites.update()
if self.alien_drop:
self.aliens.row_end()
self.all_sprites.draw(self.screen)
pygame.display.update()
self.clock.tick(60)
class Alien(pygame.sprite.Sprite):
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((25, 25))
self.rect = self.image.get_rect()
self.rect.center = (x, y)
self.image.fill(GREEN)
self.dx = 1
def update(self):
self.rect.x += self.dx
if self.rect.right >= WIDTH or self.rect.left <= 0:
my_game.alien_drop = True
def row_end(self):
self.dx *= -1
self.rect.y += 40
if __name__ == "__main__":
my_game = MyGame()
So to do the traditional Space Invaders move and drop, the entire row drops when any of the invaders hits either side.因此,要让传统的太空入侵者移动和下降,当任何入侵者击中任一侧时,整排都会下降。
In the example below I have modified the Alien.update()
to detect when the screen-side is hit, but if-so, only set a Boolean flag Alien.drop
to True.在下面的示例中,我修改了
Alien.update()
以检测屏幕侧何时被击中,但如果是这样,只需将 Boolean 标志Alien.drop
设置为 True。
The algorithm becomes: First move all the aliens.算法变为:首先移动所有的外星人。 Next, check if any alien hit the side-wall by checking this flag.
接下来,通过检查此标志检查是否有外星人撞到侧壁。 If so, move every alien down 1 step & stop checking.
如果是这样,请将每个外星人向下移动 1 步并停止检查。
The Alien.row_end()
function moves the aliens down. Alien.row_end()
function 将外星人向下移动。 It also needs to clear the Alien.drop
flag, so they don't all move down again.它还需要清除
Alien.drop
标志,因此它们不会再次向下移动。
import pygame
WIDTH = 360 # width of our game window
HEIGHT = 480 # height of our game window
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
class MyGame():
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
self.clock = pygame.time.Clock()
self.all_sprites = pygame.sprite.Group()
self.alien_drop = False
for row_index in range(4):
for column_index in range(6):
alien = Alien(20 + (column_index * 40), 20 + (row_index *40))
alien.add(self.all_sprites)
exiting = False
while not exiting:
# Handle events
for event in pygame.event.get():
if ( event.type == pygame.QUIT ):
exiting = True # exit this loop
self.screen.fill(BLACK)
self.all_sprites.update()
for alien1 in self.all_sprites:
if ( alien1.shouldDrop() ):
### If any alien drops, we all drop
for alien2 in self.all_sprites:
alien2.row_end()
break # only drop once
if self.alien_drop:
self.aliens.row_end()
self.all_sprites.draw(self.screen)
pygame.display.update()
self.clock.tick(60)
class Alien(pygame.sprite.Sprite):
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((25, 25))
self.rect = self.image.get_rect()
self.rect.center = (x, y)
self.image.fill(GREEN)
self.dx = 1
self.drop = False # should I drop-down a level
def update(self):
self.rect.x += self.dx
if self.rect.right >= WIDTH or self.rect.left <= 0:
self.drop = True
else:
self.drop = False
def shouldDrop( self ):
""" In this alien in a position where it should drop down
one row in the screen-space (i.e.: it's hit a side) """
return self.drop
def row_end(self):
self.dx *= -1
self.rect.y += 40
self.drop = False # drop drop again just yet
if __name__ == "__main__":
my_game = MyGame()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.