我用python 2和pygame创建了一个简单的2D游戏,你必须避免向下移动的方块。我为'敌人'创建了这个类:
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 :(得分:0)
检查self.rect.y,WIDTH的值,也许是kill方法。它看起来像self.rect.y总是大于或等于WIDTH,这就是为什么它会杀死它们。
答案 1 :(得分:0)
如果self.kill()
的{{1}}不在屏幕内,敌人可以通过拨打rect
将自己从游戏中移除,例如:
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()