Reputation: 11
how can i check (easily) if two sprites are near each other like they have a 100 pixels difference between them and i need it to be something that doesn't require a lot of if's. the only thing i got to is doing a lot of if's and for my game (hexagon) i need it to be with not so many if's
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
Upvotes: 1
Views: 908
Reputation: 20438
I'd check if the center of a sprite is within the radius of another sprite. You can use pg.math.Vector
s and their distance_to
method to get the distance and then look if it's less than the radius. In the following example I do this in the circle_collision
function which is passed as a callback to pg.sprite.groupcollide
. I needed the if left != right:
test, so that sprites don't collide with themselves.
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()
You could also give the sprites a second, larger rect and look if it collides with the rect of the other sprite. The code is pretty much the same, but pygame.rect.colliderect
is used instead of the distance < radius
check.
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()
Upvotes: 1