1import pygame
2from pygame.locals import *
3
4def _pixelPerfectCollisionDetection(sp1,sp2):
5    """
6    Internal method used for pixel perfect collision detection.
7    """
8    rect1 = sp1.rect;
9    rect2 = sp2.rect;
10    rect  = rect1.clip(rect2)
11
12    #hm1 = sp1.hitmask
13    #hm2 = sp2.hitmask
14
15    x1 = rect.x-rect1.x
16    y1 = rect.y-rect1.y
17    x2 = rect.x-rect2.x
18    y2 = rect.y-rect2.y
19
20    for r in range(0,rect.height):
21        for c in range(0,rect.width):
22            # I changed this for the 1.5 release of Funny Boat,
23            # because generating hitmasks is a bit problematic
24            # now that Numeric is outdated and surfarrays don't work.
25            # It's not an optimal solution, but is good enough for
26            # this game.
27
28            #if hm1[c+x1][r+y1] & hm2[c+x2][r+y2]:
29            if sp1.image.get_at((c+x1, r+y1))[3] & sp2.image.get_at((c+x2, r+y2))[3]:
30                return 1
31
32    return 0
33
34def spritecollide_pp(sprite, group, dokill):
35    """pygame.sprite.spritecollide_pp(sprite, group, dokill) -> list
36       pixel perfect collision detection between sprite and group
37
38       given a sprite and a group of sprites, this will
39       return a list of all the sprites that intersect
40       the given sprite.
41       all sprites must have a "hitmap" value, which is a 2d array
42       that contains a value larger than zero for all pixels that
43       can collide. the "hitmap" 2d array can be set by using
44       pygame.surfarray.array_colorkey() or pygame.surfarray.array_alpha().
45       all sprites must have a "rect" value, which is a
46       rectangle of the sprite area.if the dokill argument
47       is true, the sprites that do collide will be
48       automatically removed from all groups."""
49    crashed = []
50    spritecollide = sprite.rect.colliderect
51    ppcollide = _pixelPerfectCollisionDetection
52    if dokill:
53        for s in group.sprites():
54            if spritecollide(s.rect):
55                if ppcollide(sprite,s):
56                    s.kill()
57                    crashed.append(s)
58    else:
59        for s in group.sprites():
60            if spritecollide(s.rect):
61                if ppcollide(sprite,s):
62                    crashed.append(s)
63    return crashed
64
65
66def groupcollide_pp(groupa, groupb, dokilla, dokillb):
67    """pygame.sprite.groupcollide_pp(groupa, groupb, dokilla, dokillb) -> dict
68       collision detection between group and group by using pixel perfect
69       collision detection
70
71       given two groups, this will find the intersections
72       between all sprites in each group. it returns a
73       dictionary of all sprites in the first group that
74       collide. the value for each item in the dictionary
75       is a list of the sprites in the second group it
76       collides with. the two dokill arguments control if
77       the sprites from either group will be automatically
78       removed from all groups."""
79    crashed = {}
80    SC = spritecollide_pp
81    if dokilla:
82        for s in groupa.sprites():
83            c = SC(s, groupb, dokillb)
84            if c:
85                crashed[s] = c
86                s.kill()
87    else:
88        for s in groupa.sprites():
89            c = SC(s, groupb, dokillb)
90            if c:
91                crashed[s] = c
92    return crashed
93
94def spritecollideany_pp(sprite, group):
95    """pygame.sprite.spritecollideany_pp(sprite, group) -> sprite
96       finds any sprites that collide by using pixel perfect
97       collision detection
98
99       given a sprite and a group of sprites, this will
100       return return any single sprite that collides with
101       with the given sprite. If there are no collisions
102       this returns None.
103
104       if you don't need all the features of the
105       spritecollide function, this function will be a
106       bit quicker.
107
108       all sprites must have a "hitmap" value, which is a 2d array
109       that contains a value larger than zero for all pixels that
110       can collide. the "hitmap" 2d array can be set by using
111       pygame.surfarray.array_colorkey() or pygame.surfarray.array_alpha().
112
113       all sprites must have a "rect" value, which is a
114       rectangle of the sprite area.
115       """
116    spritecollide = sprite.rect.colliderect
117    ppcollide = _pixelPerfectCollisionDetection
118    for s in group.sprites():
119        if spritecollide(s.rect):
120            if ppcollide(sprite,s):
121                return s
122    return None
123