亲宝软件园·资讯

展开

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

peanutfish 人气:0

前言

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)

总结

加载全部内容

相关教程
猜你喜欢
用户评论