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