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