我怎样才能(轻松)检查两个精灵是否彼此靠近

时间:2017-04-05 10:26:53

标签: pygame sprite

我如何(轻松地)检查两个精灵是否彼此接近,就像它们之间有100像素差异一样,我需要它是不需要很多if的东西。我唯一能做的就是做很多if和我的游戏(六角形)我需要的不是那么多if ifs

def is_near(myPearl,bPearl):
    if (abs(myPearl.rect.x - bPearl.rect.x) == 100 and abs(myPearl.rect.y -       bPearl.rect.y) == 100) or abs(myPearl.rect.y - bPearl.rect.y) == 100 or  myPearl.rect.x == bPearl.rect.x:
      return 1  # 1 means that the pearl is near it and this pearl is next to the pushed pearl
    if abs(myPearl.rect.x - bPearl.rect.x) == 200 or abs(myPearl.rect.y - bPearl.rect.y) == 200 or myPearl.rect.x == bPearl.rect.x:
      return 2  # 2 means that the pearl is near it and this pearl is two slots near the pushed pearl

1 个答案:

答案 0 :(得分:1)

我会检查精灵的中心是否在另一个精灵的半径范围内。您可以使用pg.math.Vector和他们的distance_to方法获取距离,然后查看它是否小于半径。在下面的示例中,我在circle_collision函数中执行此操作,该函数作为回调传递给pg.sprite.groupcollide。我需要if left != right:测试,以便精灵不会与自己发生碰撞。

import sys
import pygame as pg
from pygame.math import Vector2
from pygame.color import THECOLORS


class Player(pg.sprite.Sprite):

    def __init__(self, pos, *groups):
        super().__init__(*groups)
        self.image = pg.Surface((50, 30))
        self.image.fill(THECOLORS['sienna1'])
        self.rect = self.image.get_rect(center=pos)
        self.radius = 100


def circle_collision(left, right):
    if left != right:
        distance = Vector2(left.rect.center).distance_to(right.rect.center)
        return distance < left.radius
    else:
        return False


def main():
    screen = pg.display.set_mode((640, 480))
    clock = pg.time.Clock()

    sprite_group = pg.sprite.Group()
    player1 = Player((100, 300), sprite_group)
    player2 = Player((400, 300), sprite_group)
    player3 = Player((100, 100), sprite_group)

    done = False

    while not done:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                done = True
            if event.type == pg.MOUSEMOTION:
                player1.rect.center = event.pos

        sprite_group.update()
        collided_sprites = pg.sprite.groupcollide(
            sprite_group, sprite_group, False, False,
            collided=circle_collision)

        # Draw everything.
        screen.fill(THECOLORS['lemonchiffon4'])
        sprite_group.draw(screen)

        for collided_sprite in collided_sprites:
            pg.draw.circle(screen, THECOLORS['lightcyan1'],
                           collided_sprite.rect.center,
                           collided_sprite.radius, 2)

        pg.display.flip()
        clock.tick(30)


if __name__ == '__main__':
    pg.init()
    main()
    pg.quit()
    sys.exit()

你也可以给精灵一个更大的矩形,看它是否与另一个精灵的矩形相撞。代码几乎相同,但使用pygame.rect.colliderect代替distance < radius检查。

import sys
import pygame as pg
from pygame.color import THECOLORS


class Player(pg.sprite.Sprite):

    def __init__(self, pos, *groups):
        super().__init__(*groups)
        self.image = pg.Surface((50, 30))
        self.image.fill(THECOLORS['sienna1'])
        self.rect = self.image.get_rect(center=pos)
        self.vicinity_rect = self.rect.inflate(200, 200)
        self.vicinity_rect.center = self.rect.center

    def update(self):
        self.vicinity_rect.center = self.rect.center


def vicinity_collision(left, right):
    if left != right:
        return left.vicinity_rect.colliderect(right.rect)
    else:
        return False


def main():
    screen = pg.display.set_mode((640, 480))
    clock = pg.time.Clock()

    sprite_group = pg.sprite.Group()
    player1 = Player((100, 300), sprite_group)
    player2 = Player((400, 300), sprite_group)
    player3 = Player((100, 100), sprite_group)

    done = False

    while not done:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                done = True
            if event.type == pg.MOUSEMOTION:
                player1.rect.center = event.pos

        sprite_group.update()
        collided_sprites = pg.sprite.groupcollide(
            sprite_group, sprite_group, False, False,
            collided=vicinity_collision)

        # Draw everything.
        screen.fill(THECOLORS['lemonchiffon4'])
        sprite_group.draw(screen)

        for collided_sprite in collided_sprites:
            pg.draw.rect(screen, THECOLORS['lightcyan1'],
                         collided_sprite.vicinity_rect, 2)

        pg.display.flip()
        clock.tick(30)


if __name__ == '__main__':
    pg.init()
    main()
    pg.quit()
    sys.exit()