Pygame精�和碰撞检测

 
在开始学习相关知识点之�,我们有必�先学习精�和碰撞检测的�义。

ç²¾ç�µï¼ˆè‹±æ–‡è¯‘为 Sprite),其实在一个游æˆ�程åº�中,精ç�µæœ¬è´¨æŒ‡çš„æ˜¯ä¸€å¼ å¼ å°�尺寸的图片,比如游æˆ�中的å�„ç§�é�“å…·ã€�人物ã€�场景装饰等,它们都å�¯ä»¥çœ‹å�šæˆ�一张张å°�çš„“ç²¾ç�µ”图。除此之外,人物的移动也å�¯ä»¥çœ‹å�šæ˜¯ä¸€ç³»åˆ—å°�ç²¾ç�µå›¾æž„æˆ�çš„åº�列(按帧组æˆ�çš„åº�列),如下图所示:

pygame精�图
图1:动作�帧分解图

如果将�帧分解�的动作,按照一定的频率播放,那么就形�了动画精�,您将会看到雄鹰展翅高飞�人在策马奔腾��动员奋力跳远。

精�有个特点就是�许精�之间进行交互,也称之为碰撞,而碰撞检测,指的就是检测两个精�之间是��生了碰撞。比如在贪�蛇游�中蛇的头部是�与食物�生了碰撞,或者飞机大战游�中�弹是�击中了外星人等等。当检测到碰撞�生�,接下�会触��些事件,比如�弹击中外星人,外星人就会消失,玩家的得分也会�之增加,并且在游��幕上�会出现一个外星人。

Pygame 专门�供了一个处�精�的模�,也就是 sprite(pygame.sprite)模�。通常情况下,我们使用该模�的基类 Sprite �创建一个�类,从而达到处�精�的目的,该�类�供了�作精�的常用属性和方法,如下所示:

属性&方法 说明
self.image 加载�显示的精�图片,控制图片大�和填充色
self.rect 精�图片显示在哪个�置
Sprite.update() 刷新精�图,使其相应效果生效
Sprite.add() 添加精�图到精�组中(groups)
Sprite.remove() 从精�组中删除选中的精�图
Sprite.kill() 删除精�组中全部的精�
Sprite.alive() 判断�个精�是�属于精�组

注�,当游�中有大�的精�时,�作它们将�得��,此时通过构建精�容器(group 类)也就是精�组�统一管�这些精�。构建方法如下:
# 创建精�组
group = pygame.sprite.Group()
# �组内添加一个精�
group.add(sprite_one)
于此�时pygame.sprite模�也�供了多�检测精�是�碰撞的方法,如下所示:

方法 说明
pygame.sprite.collide_rect()  两个精ç�µä¹‹é—´çš„矩形检测,å�³çŸ©å½¢åŒºåŸŸæ˜¯å�¦æœ‰äº¤æ±‡ï¼Œè¿”回一个布尔值。
pygame.sprite.collide_circle() 两个精�之间的圆形检测,�圆形区域是�有交汇,返回一个布尔值。
pygame.sprite.collide_mask()  两个精ç�µä¹‹é—´çš„åƒ�素蒙版检测,更为精准的一ç§�检测方å¼�。
pygame.sprite.spritecollide()  ç²¾ç�µå’Œç²¾ç�µç»„之间的矩形碰撞检测,一个组内的所有精ç�µä¼šé€�一地对å�¦å¤–一个å�•个精ç�µè¿›è¡Œç¢°æ’žæ£€æµ‹ï¼Œè¿”回值是一个列表,包å�«äº†å�‘生碰撞的所有精ç�µã€‚
pygame.sprite.spritecollideany() 精�和精�组之间的矩形碰撞检测,上述函数的�体,当�生碰撞时,返回组内的一个精�,无碰撞�生时,返回 None。
pygame.sprite.groupcollide() 检测在两个组之间�生碰撞的所有精�,它返回值是一个字典,将第一组中�生碰撞的精�作为键,第二个组中�生碰撞的精�作为值。

下�看一组简�的示例,代�如下所示:
import pygame

class Snake(pygame.sprite.Sprite):
    #定义构造函数
    def __init__(self,filename,location):
        # 调父类��始化�类
        pygame.sprite.Sprite.__init__(self)
        # 加载图片
        self.image = pygame.image.load(filename)
        # 获�图片rect区域
        self.rect = self.image.get_rect()
        # 设置�置
        self.rect.topleft=location

# �始化pygame
pygame.init()
screen = pygame.display.set_mode((500,400))
pygame.display.set_caption('C语言中文网')
# 填充为白色�幕
screen.fill((255,255,255))
filename ="C:/Users/Administrator/Desktop/snake.png"

location =(100,150)
snake1 = Snake(filename,location)
# 碰撞检测,必须有两个精�,因此�创建一个精�,并使用location�控制第二个精�的�置
location_2 = (100,80)
snake2 = Snake('C:/Users/Administrator/Desktop/logo.png',location_2)
# 调用 collide_rect()进行矩形区域检测,返回一个布尔值,碰撞返回True,�则返回False
crash_result = pygame.sprite.collide_rect(snake1,snake2)
if crash_result:
    print("精�碰撞了!")
    pass
else:
    print('精�没碰撞')

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()
    # 绘制精�到�幕上
    screen.blit(snake1.image,snake1.rect)
    screen.blit(snake2.image,snake2.rect)
    # 刷新显示�幕
    pygame.display.update()
当精�没有�生碰撞时,程�的�行结果如下:

pygame sprite
图2:�行结果

接下�,我们将 snake2 的location_2�数�为 (100,140),然��次�行程�,这时两个精�就会�生碰撞,�行结果如下:

pygame sprite精�图
图3:�行结果

除上述内容外,Pygame 还æ��供许多其他模å�—,比如 mixer(声音)ã€�movie(播放视频)ã€�music(播放音频)ã€�sndarray(æ“�作声音数æ�®ï¼‰ç­‰æ¨¡å�—,由于这些模å�—使用起æ�¥è¾ƒä¸ºç®€å�•,因此这里ä¸�å†�é€�一介ç»�,感兴趣的朋å�‹å�¯ä»¥é˜…读 Pygame 官方文档 —>点击å‰�å¾€ï¼�

关注公众�「站长严长生�,在手机上阅读所有教程,�时�地都能学习。本公众�由C语言中文网站长亲自��,长期更新,��原创。

公众�二维�
微信扫�关注公众�

 

加入微信交�群,一起学习�枯燥。内�一款�索神器,�费下载全网书�和视频。