python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > pygame.sprite精灵碰撞

一文详解pygame.sprite的精灵碰撞

作者:peanutfish

精灵其实在一个游戏程序中,精灵本质指的是一张张小尺寸的图片,比如游戏中的各种道具、人物、场景装饰等,它们都可以看做成一张张小的“精灵”图,下面这篇文章主要给大家介绍了关于pygame.sprite精灵碰撞的相关资料,需要的朋友可以参考下

前言

pygame中的精灵碰撞是可见游戏中用的最基础的东西,这里结合官方文档和小甲鱼的网站上的内容做个小总结,方便日后使用。

pygame.sprite.Sprite - 可见游戏对象的简单基类。

Sprite(*groups) -> Sprite

pygame.sprite.Group - 用于保存和管理多个 Sprite 对象的容器类。

Group(*sprites) -> Group

上面两个基类是pygame中最常用,相当轻量级,只为大多数游戏常见的代码提供了一个起始点。

Sprite 类旨在用作游戏中不同类型对象的基类,为我们碰撞检测做准备。还有一个基本的 Group 类,它只存储 sprite 对象, 这样方便不同类型的精灵进行碰撞检测, 通常的操作 in / len / bool / iter 都对这个group使用。

in      test if a Sprite is contained
len     the number of Sprites contained
bool    test if any Sprites are contained
iter    iterate through all the Sprites

pygame.sprite.spritecollide() - 在与另一个精灵相交的组中查找精灵

spritecollide(sprite, group, dokill, collided = None) -> Sprite_list

可用的回调函数

collide_rect, collide_rect_ratio, collide_circle,
collide_circle_ratio, collide_mask

collide_rect(left, right) -> bool

collide_rect_ratio(ratio) -> collided_callable

如果精灵具有 radius(半径) 属性,用于创建圆,否则会创建一个足够大的圆,以完全包围由 rect 属性给出的精灵矩形。作为碰撞回调函数传递给 *collide 函数。精灵必须具有 rect 和可选的 radius 属性

请添加图片描述

collide_circle(left, right) -> bool

两个精灵之间的碰撞创建的可调用测试,通过测试以查看以精灵为中心的两个圆是否重叠,在通过存储的比例缩放圆半径之后。如果精灵具有 radius 半径属性,用于创建圆,否则会创建一个足够大的圆,以完全包围由 rect 属性给出的精灵矩形。打算作为碰撞回调函数传递给 *collide 函数。

精灵必须具有 rect 和可选的 radius 属性

collide_circle_ratio(ratio) -> collided_callable

通过测试它们的 bitmasks( pygame.mask.Mask.overlap()) 是否重叠来测试两个精灵之间的碰撞。 如果精灵具有 mask 属性,该属性用作 mask,否则将从精灵图像创建 mask 。 作为碰撞回调函数传递给 *collide 函数。

精灵必须具有 rect 和可选的 mask 属性

如果要多次检查碰撞,应该考虑在加载时为精灵创建一个mask。这将提高性能,否则这可能是一个昂贵的功能,因为它会在每次检查碰撞时创建 mask 。

# Example of mask creation for a sprite.
sprite.mask = pygame.mask.from_surface(sprite.image)

collide_mask(sprite1, sprite2) -> (int, int)

collide_mask(sprite1, sprite2) -> None

pygame.sprite.groupcollide - 查找在两个组之间发生碰撞的所有精灵。

groupcollide(group1, group2, dokill1, dokill2, collided = None) -> Sprite_dict

EG:
class Block(pygame.sprite.Sprite):

    # Constructor. Pass in the color of the block,
    # and its x and y position
    def __init__(self, color, width, height):
       # Call the parent class (Sprite) constructor
       pygame.sprite.Sprite.__init__(self)

       # Create an image of the block, and fill it with a color.
       # This could also be an image loaded from the disk.
       self.image = pygame.Surface([width, height])
       self.image.fill(color)

       # Fetch the rectangle object that has the dimensions of the image
       # Update the position of this object by setting the values of rect.x and rect.y
       # give radius and mask attribute
       self.rect = self.image.get_rect()
       self.radius = self.rect.width / 2
       self.mask = pygame.image.from_surface(self.image)


class File(pygame.sprite.Sprite):

    # Constructor. Pass in the color of the block,
    # and its x and y position
    def __init__(self, color, width, height):
       # Call the parent class (Sprite) constructor
       pygame.sprite.Sprite.__init__(self)

       # Create an image of the block, and fill it with a color.
       # This could also be an image loaded from the disk.
       self.image = pygame.Surface([width, height])
       self.image.fill(color)

       # Fetch the rectangle object that has the dimensions of the image
       # Update the position of this object by setting the values of rect.x and rect.y
       self.rect = self.image.get_rect()
       self.radius = self.rect.width / 2
       self.mask = pygame.image.from_surface(self.image)
    
block_group = pygame.sprite.Group()
for i in range(5):
    block = Block(color, width, height)
    block_group.add(block)
    
    # there is another sprite group called file_group, which have same setting as block_group.
file_group = pygame.sprite.Group()
for i in range(5):
    file = File(color, width, height)
    file_group.add(file)
    
    # the collide check will like:
    hit_list1 = pygame.sprite.spritecollide(block, file_group, False, pygame.sprite.collide_rect
    hit_list2 = pygame.sprite.spritecollide(block, file_group, False, pygame.sprite.collide_rect_ratio(.75))
    hit_list3 = pygame.sprite.spritecollide(block, file_group, False, pygame.sprite.collide_circle
    hit_list4 = pygame.sprite.spritecollide(block, file_group, False, pygame.sprite.collide_circle_ratio(.25))
    hit_list5 = pygame.sprite.spritecollide(block, file_group, False, pygame.sprite.collide_mask
    # select the collided function whatever you like
    hit_list6 = pygame.sprite.spritecollide(block_group, file_group, False, False, pygame.sprite.collide_XXX)

总结

到此这篇关于pygame.sprite精灵碰撞的文章就介绍到这了,更多相关pygame.sprite精灵碰撞内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文