2016-11-23 282 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,這就是爲什麼它會殺死所有的。