2016-11-23 141 views
0

我用python 2和pygame创建了一个简单的2D游戏,您必须避免正在向下移动的方块。我对“敌”创建这个类:Python pygame - 删除屏幕外精灵

class Enemy(pygame.sprite.Sprite): 

    def __init__(self, game): 
     self.groups = game.all_sprites 
     pygame.sprite.Sprite.__init__(self, self.groups) 
     self.game = game 
     self.image = pygame.Surface((TILESIZE + 10, TILESIZE + 10)) 
     self.image.fill(ENEMY_COLOR) 
     self.rect = self.image.get_rect() 
     self.x = random.uniform(0, WIDTH - TILESIZE) 
     self.rect.x = self.x 
     self.y = 0 

    def update(self): 
     if self.rect.colliderect(self.game.player.rect): 
      self.game.deaths += 1 
      self.game.score = 0 
      self.game.run() 
     self.rect.y += (self.game.score + 500)/50 

然后,我有一个创建了敌人的一个实例,一个线程:

class Create_Enemy(Thread): 

    def __init__(self): 
     Thread.__init__(self) 

    def run(self): 
     while True: 
      while not game.game_paused: 
       time.sleep((game.score + 1)/game.speed) 
       Enemy(game) 

然后在抽签方法我只是写self.all_sprites.draw() 游戏是一个无限的亚军,敌人的每一帧都会向下移动几个像素。问题在于,稍后游戏变得迟缓,因为当块离屏时,精灵不会被删除。 有没有办法自动删除屏幕外的实例?

我试过以下,但它只是删除屏幕上的所有敌人。

if self.rect.y >= WIDTH: 
    self.rect.kill() 

我想我可以做类似game.all_sprites.pop(1)(0位置是播放器),但我无法找到一个方法来存档类似的东西...

+0

您可以在没有'Thread'的情况下执行此操作,以获得更好的控制。 – furas

+0

在你的线程中运行'Enemy(游戏)'数百万次,所以你在内存中创建了数百万个对象。 – furas

+0

阅读[pygame.sprite.Group()](http://pygame.org/docs/ref/sprite.html)doc - 你有'self.all_sprites.sprites()'得到所有精灵的列表,'' self.all_sprites.remove(sprite_object)'从组中删除元素。 – furas

回答

0

敌人可以通过调用self.kill()如果他们的rect不再是里面的画面,如取出从游戏themselfs:

def update(self): 
    if self.rect.colliderect(self.game.player.rect): 
     self.game.restart() // reset score + count deaths 

    // we can simply use move_ip here to move the rect 
    self.rect.move_ip(0, (self.game.score + 500)/100) 

    // check if we are outside the screen 
    if not self.game.screen.get_rect().contains(self.rect): 
     self.kill() 

此外,而不是线程,你可以使用pygame中的事件系统产卵你敌人。下面是一个简单的,不完整但可运行的示例(注意注释):

import random 

import pygame 

TILESIZE = 32 
WIDTH, HEIGHT = 800, 600 

// a lot of colors a already defined in pygame 
ENEMY_COLOR = pygame.color.THECOLORS['red'] 
PLAYER_COLOR = pygame.color.THECOLORS['yellow'] 

// this is the event we'll use for spawning new enemies 
SPAWN = pygame.USEREVENT + 1 

class Enemy(pygame.sprite.Sprite): 

    def __init__(self, game): 

     // we can use multiple groups at once. 
     // for now, we actually don't need to 
     // but we could do the collision handling with pygame.sprite.groupcollide() 
     // to check collisions between the enemies and the playerg group 
     pygame.sprite.Sprite.__init__(self, game.enemies, game.all) 
     self.game = game 
     self.image = pygame.Surface((TILESIZE + 10, TILESIZE + 10)) 
     self.image.fill(ENEMY_COLOR) 

     // we can use named arguments to directly set some values of the rect 
     self.rect = self.image.get_rect(x=random.uniform(0, WIDTH - TILESIZE)) 
     // we dont need self.x and self.y, since we have self.rect already 
     // which is used by pygame to get the position of a sprite 


    def update(self): 
     if self.rect.colliderect(self.game.player.rect): 
      self.game.restart() // reset score + count deaths 

     // we can simply use move_ip here to move the rect 
     self.rect.move_ip(0, (self.game.score + 500)/100) 

     // check if we are outside the screen 
     if not self.game.screen.get_rect().contains(self.rect): 
      self.kill() 

class Player(pygame.sprite.Sprite): 

    def __init__(self, game): 
     pygame.sprite.Sprite.__init__(self, game.all, game.playerg) 
     self.game = game 
     self.image = pygame.Surface((TILESIZE, TILESIZE)) 
     self.image.fill(PLAYER_COLOR) 
     self.rect = self.image.get_rect(x=WIDTH/2 - TILESIZE/2, y=HEIGHT-TILESIZE*2) 

    def update(self): 
     // no nothing for now 
     pass 


class Game(object): 

    def __init__(self): 
     // for now, we actually don't need mujtiple groups 
     // but we could do the collision handling with pygame.sprite.groupcollide() 
     // to check collisions between the enemies and the playerg group 
     self.enemies = pygame.sprite.Group() 
     self.all = pygame.sprite.Group() 
     self.playerg = pygame.sprite.GroupSingle() 
     self.running = True 
     self.score = 0 
     self.deaths = -1 
     self.clock = pygame.time.Clock() 

    def restart(self): 
     // here we set the timer to create the SPAWN event 
     // every 1000 - self.score * 2 milliseconds 
     pygame.time.set_timer(SPAWN, 1000 - self.score * 2) 
     self.score = 0 
     self.deaths += 1 

    def run(self): 
     self.restart() 
     self.player = Player(self) 
     self.screen = pygame.display.set_mode((WIDTH, HEIGHT)) 

     while self.running: 
      for e in pygame.event.get(): 
       if e.type == pygame.QUIT: 
        self.running = False 
       // when the SPAWN event is fired, we create a new enemy 
       if e.type == SPAWN: 
        Enemy(self) 

      // draw and update everything 
      self.screen.fill(pygame.color.THECOLORS['grey']) 
      self.all.draw(self.screen) 
      self.all.update() 
      pygame.display.flip() 

      self.clock.tick(40) 

if __name__ == '__main__': 
    Game().run() 
0

检查self.rect的值.y,WIDTH,也许是杀死方法。它看起来像self.rect.y总是大于或等于WIDTH,这就是为什么它会杀死所有的。