在pygame.sprite模块里面包含了一个名为Sprite类,他是pygame本身自带的一个精灵
在pygame里,sprite通常是一个二维的图片。比如一辆汽车、一个狐狸、一条小狗等
使用sprites的主要好处是我们可以把游戏里的所有角色在一个组里做统一处理。我们可以同时渲染、移动他们。我们还可以检测一个角色是否和组里的任何一个角色发生碰撞
游戏开发最核心的就是碰撞检测了,子弹击中敌人、足球射进门、吃加血包这些都是通过碰撞检测完成的
碰撞实例一:红方块吃黑方块
import pygame import random BLACK = ( 0, 0, 0) #黑色 WHITE = (255, 255, 255) #白色 RED = (255, 0, 0) #红色 class Block(pygame.sprite.Sprite): """ 定义一个Block类,这个类继承了:pygame.sprite.Sprite 因此,这个类具有了sprite类的所有属性和方法 """ def __init__(self, color, width, height): """ 在Block类的init方法里,我们传入了颜色、宽度、高度三个属性。这里需要注意的是,我们通过super().__init__()调用了父类的初始化方法来初始化sprite的属性 """ super().__init__() self.image = pygame.Surface([width, height]) #创建指定宽高的图像 self.image.fill(color) #用指定颜色填充图像 self.rect = self.image.get_rect() pygame.init() b=pygame.mouse.set_visible(False) #隐藏鼠标 screen_width = 700 screen_height = 400 screen = pygame.display.set_mode([screen_width, screen_height]) block_list = pygame.sprite.Group() #定义精灵组 # group代表多个sprite为一组被同时管理,比如头、身、手、脚组合成一个大怪 #block_list用来存储游戏里的碰撞目标 all_sprites_list = pygame.sprite.Group() #all_sprites_list用来存储所有的角色 for i in range(50): #使用for循环来初始化黑色的块,,我们把所有黑色的块放到block_list和all_sprites_list里 block = Block(BLACK, 20, 15) #定义黑色精灵 block.rect.x = random.randrange(screen_width) #随机坐标--通过draw指令画到对应的位置 block.rect.y = random.randrange(screen_height) block_list.add(block) #加入组 all_sprites_list.add(block) player = Block(RED, 20, 15) #定义红色精灵 all_sprites_list.add(player) done = False clock = pygame.time.Clock() score = 0 #存储游戏得分 while not done: for event in pygame.event.get(): if event.type == pygame.QUIT: done = True screen.fill(WHITE) #背景白色 pos = pygame.mouse.get_pos() #获取鼠标位置 player.rect.x = pos[0] #修改红色方块的位置 player.rect.y = pos[1] blocks_hit_list = pygame.sprite.spritecollide(player, block_list, True) #检查红色块是否和黑色块发生碰撞 #参数1:检测对象--红色精灵 #参数2:检测目标--黑色精灵组 #参数3:如果group里的元素和player碰撞后,是否移除这个元素(True移除) #返回被碰撞到的黑色精灵列表 for block in blocks_hit_list: score += 1 print('得分:',score) all_sprites_list.draw(screen) #将所有角色渲染到screen上 #group对象里有个draw方法,这个方法会循环group里的每个sprite,并调用sprite的draw方法。这样,我们只需要使用一行代码就可以将所有sprite渲染到screen上了 pygame.display.flip() #更新整个屏幕 clock.tick(60) pygame.quit()
到目前为止,只有player sprite可以移动。接下来我们让游戏里的所有块都可以移动,有了上面的基础,让所有角色一起移动也非常方便
import pygame import random BLACK = ( 0, 0, 0) WHITE = (255, 255, 255) RED = (255, 0, 0) class Block(pygame.sprite.Sprite): def __init__(self, color, width, height): super().__init__() self.image = pygame.Surface([width, height]) self.image.fill(color) self.rect = self.image.get_rect() def update(self):#更新函数 #当使用组的update方法时,这个函数会自动被调用 self.rect.y += 1 # if self.rect.y > screen_height: #精灵移出屏幕后再次重新定位到屏幕上 self.rect.y = random.randrange(-100, -10) self.rect.x = random.randrange(0, screen_width) pygame.init() b=pygame.mouse.set_visible(False) screen_width = 700 screen_height = 400 screen = pygame.display.set_mode([screen_width, screen_height]) block_list = pygame.sprite.Group() all_sprites_list = pygame.sprite.Group() for i in range(50): block = Block(BLACK, 20, 15) block.rect.x = random.randrange(screen_width) block.rect.y = random.randrange(screen_height) block_list.add(block) all_sprites_list.add(block) player = Block(RED, 20, 15) all_sprites_list.add(player) done = False clock = pygame.time.Clock() score = 0 while not done: for event in pygame.event.get(): if event.type == pygame.QUIT: done = True screen.fill(WHITE) pos = pygame.mouse.get_pos() player.rect.x = pos[0] player.rect.y = pos[1] blocks_hit_list = pygame.sprite.spritecollide(player, block_list, True) for block in blocks_hit_list: score += 1 print('得分:',score) all_sprites_list.draw(screen) pygame.display.flip() block_list.update() #更新组内的所有精灵 #自动调用Block类的update方法,更新一次调用一次 clock.tick(60) pygame.quit()