def grow_rect(self, rect, growth, rects, direction): """Tries to grow a rectangle in the specified direction Returns whether the growth succeeded""" changed = False if growth[direction]: left, top, width, height = rect.x, rect.y, rect.w, rect.h if direction == LEFT: left -= 1 width += 1 elif direction == RIGHT: width += 1 elif direction == DOWN: height += 1 elif direction == UP: top -= 1 height += 1 new = Rect(left, top, width, height) if not (set(util.points_in(new)) - self.space) and len(new.collidelistall(rects)) == 1: rect.left = left rect.width = width rect.top = top rect.height = height changed = True #if rect.width >= 8 and rect.height >= 8 and random.randrange(5) == 0: # growth[direction] = False else: growth[direction] = False return changed
def grow_rect(self, i, rect, growth, adjacency, rects, direction): """Tries to grow a rectangle in the specified direction Returns whether the growth succeeded""" if rect.w > 100 or rect.h > 100: growth[direction] = False return False if growth[direction]: left, top, width, height = rect.x, rect.y, rect.w, rect.h if direction == LEFT: left -= 1 width += 1 if height > 1: collision = Rect(rect.x, rect.y+1, 1, rect.h-2) else: collision = Rect(rect.x, rect.y, 1, 1) elif direction == RIGHT: width += 1 if height > 1: collision = Rect(rect.right-1, rect.y+1, 1, rect.h-2) else: collision = Rect(rect.right-1, rect.y, 1, 1) elif direction == DOWN: height += 1 if width > 1: collision = Rect(rect.x+1, rect.bottom-1, rect.w-2, 1) else: collision = Rect(rect.x, rect.bottom-1, 1, 1) elif direction == UP: top -= 1 height += 1 if width > 1: collision = Rect(rect.x+1, rect.y, rect.w-2, 1) else: collision = Rect(rect.x, rect.y, 1, 1) building_collisions = collision.collidelistall(rects) try: building_collisions.remove(i) except ValueError: pass if not (set(Generator.get_rect(collision)) - self.space) and len(building_collisions) == 0: rect.left = left rect.width = width rect.top = top rect.height = height #if rect.width >= 8 and rect.height >= 8 and random.randrange(5) == 0: # growth[direction] = False return True else: growth[direction] = False if building_collisions: care_about = [j for j in building_collisions if j < len(self.points)] # If we collided with a building, make a note. adjacency[i] += care_about for j in care_about: adjacency[j].append(i) return False
def test_collidelistall(self): # __doc__ (as of 2008-08-02) for pygame.rect.Rect.collidelistall: # Rect.collidelistall(list): return indices # test if all rectangles in a list intersect # # Returns a list of all the indices that contain rectangles that # collide with the Rect. If no intersecting rectangles are found, an # empty list is returned. r = Rect(1, 1, 10, 10) l = [Rect(1, 1, 10, 10), Rect(5, 5, 10, 10), Rect(15, 15, 1, 1), Rect(2, 2, 1, 1)] self.assertEqual(r.collidelistall(l), [0, 1, 3]) f = [Rect(50, 50, 1, 1), Rect(20, 20, 5, 5)] self.assertFalse(r.collidelistall(f))
def grow_room(self, room, growing, max_size, pad_v=0, pad_h=0, space=None): """Tries to grow a room in the specified direction Returns whether the growth succeeded""" space = space if space is not None else self.interior_space for d, grow in enumerate(growing): if not grow: continue if (((d == LEFT or d == RIGHT) and room.w > max_size) or ((d == UP or d == DOWN) and room.h > max_size)): growing[d] = False continue left, top, width, height = room.x, room.y, room.w, room.h if d == LEFT: left -= 1 width += 1 if room.w <= 1: collision = None else: collision = Rect(room.x - pad_h, room.y + 1 - pad_v, 1 + pad_h, max(1, room.h + 2 * pad_v - 2)) elif d == RIGHT: width += 1 if room.w <= 1: collision = None else: collision = Rect(room.right - 1 - pad_h, room.y + 1, 1 + pad_h, max(1, room.h + 2 * pad_v - 2)) elif d == DOWN: height += 1 if room.h <= 1: collision = None else: collision = Rect(room.x + 1 - pad_h, room.bottom - 1, max(1, room.w - 2 + 2 * pad_h), 1 + pad_v) elif d == UP: top -= 1 height += 1 if room.h <= 1: collision = None else: collision = Rect(room.x + 1 - pad_h, room.y - pad_v, max(1, room.w - 2 + 2 * pad_h), 1 + pad_v) if collision is not None: building_collisions = collision.collidelistall([r.rect for r in self.shapes if isinstance(r, Room)]) else: building_collisions = [] if not (set(Generator.get_rect(collision)) - space) and len(building_collisions) == 0: room.left = left room.width = width room.top = top room.height = height else: print room.rect, collision, d, building_collisions, (set(Generator.get_rect(collision)) - space) growing[d] = False
def test_collidelistall(self): # __doc__ (as of 2008-08-02) for pygame.rect.Rect.collidelistall: # Rect.collidelistall(list): return indices # test if all rectangles in a list intersect # # Returns a list of all the indices that contain rectangles that # collide with the Rect. If no intersecting rectangles are found, an # empty list is returned. r = Rect(1, 1, 10, 10) l = [ Rect(1, 1, 10, 10), Rect(5, 5, 10, 10), Rect(15, 15, 1, 1), Rect(2, 2, 1, 1), ] self.assertEqual(r.collidelistall(l), [0, 1, 3]) f = [Rect(50, 50, 1, 1), Rect(20, 20, 5, 5)] self.assertFalse(r.collidelistall(f))
def collision(self, dx, dy): collide_objects = Bot.enemy + [Bot.hero] + [ ob for ob in Bot.objects if ob.Collide ] + Bot.bot for n in Rect.collidelistall(self.rect, collide_objects): if collide_objects[n] != self: if dx > 0: self.rect.right = collide_objects[n].rect.left self.dx = 0 self.x = self.rect.centerx if dx < 0: self.rect.left = collide_objects[n].rect.right self.dx = 0 self.x = self.rect.centerx if dy > 0: self.rect.bottom = collide_objects[n].rect.top self.dy = 0 self.y = self.rect.centery if dy < 0: self.rect.top = collide_objects[n].rect.bottom self.dy = 0 self.y = self.rect.centery for n in Bot.houses: num = self.rect.collidelist(n.rect) if num != -1: if dx > 0: self.rect.right = n.rect[num].left self.dx = 0 self.x = self.rect.centerx if dx < 0: self.rect.left = n.rect[num].right self.dx = 0 self.x = self.rect.centerx if dy > 0: self.rect.bottom = n.rect[num].top self.dy = 0 self.y = self.rect.centery if dy < 0: self.rect.top = n.rect[num].bottom self.dy = 0 self.y = self.rect.centery
def collision(self, dx, dy): collide_objects = [n for n in Player.enemy if n.visible] + [b for b in Player.bot if b.visible] + \ [ob for ob in Player.objects if ob.Collide] for n in Rect.collidelistall(self.rect, collide_objects): if dx > 0: self.rect.right = collide_objects[n].rect.left self.dx = 0 self.x = self.rect.centerx if dx < 0: self.rect.left = collide_objects[n].rect.right self.dx = 0 self.x = self.rect.centerx if dy > 0: self.rect.bottom = collide_objects[n].rect.top self.dy = 0 self.y = self.rect.centery if dy < 0: self.rect.top = collide_objects[n].rect.bottom self.dy = 0 self.y = self.rect.centery for n in Player.houses: num = self.rect.collidelist(n.rect) if num != -1: if dx > 0: self.rect.right = n.rect[num].left self.dx = 0 self.x = self.rect.centerx if dx < 0: self.rect.left = n.rect[num].right self.dx = 0 self.x = self.rect.centerx if dy > 0: self.rect.bottom = n.rect[num].top self.dy = 0 self.y = self.rect.centery if dy < 0: self.rect.top = n.rect[num].bottom self.dy = 0 self.y = self.rect.centery
def get_idx_at(self, pos): colliderect = Rect(pos, (0, 0)) return colliderect.collidelistall(self._spritelist)
class Tank(Sprite): All = [] def __init__(self, color, x, y): self.color = color self.x, self.y = x, y Sprite.__init__(self, y) Tank.All.append(self) self.bodies = load_multiimage('tank_body.png', 8, color) self.turrets = load_multiimage('tank_turret.png', 8, color) self.sx, self.sy = self.bodies[0].get_size() # size self.putface('happy') width = self.sx self.rect = Rect(x-width/2, y-width/2, width, width).inflate(-8,-8) self.heading = self.facing = 3 # SE self.sound = None self.mire = Mire(self.color, x, y) self.readyamo = 3 self.reloading = 0 # Controls: self.headto, self.fire, self.targetx, self.targety = None, 0, x, y def putface(self, face): self.faces = load_multiimage('memes/'+face+'8.png', 8, self.color) fw,fh = self.faces[0].get_size() self.faceoffset = XY((self.sx-fw)/2,16-fh) def dissapear(self): if self.sound: self.sound.stop() Sprite.dissapear(self) Tank.All.remove(self) #for t in self.trail: t.dissapear() def noise(self, sound): if self.sound != sound: if self.sound: self.sound.stop() self.sound = sound if sound: sound.play(-1) def update(self): if self.headto == self.heading: self.noise(SOUND_WALK) newxy = ( self.x + DIRECTIONS[self.heading][0] , self.y + DIRECTIONS[self.heading][1] ) self.rect.center = newxy # Check for obstacles: if self.rect.collidelist(Wall.All) != -1 or 1<len(self.rect.collidelistall(Tank.All)): self.rect.center = self.x, self.y else: self.x, self.y = newxy elif self.headto != None: self.noise(SOUND_TURN) if (self.headto+8-self.heading)&7 <= 4: self.heading += 1 else: self.heading -= 1 self.heading &= 7 else: self.noise(None) self.mire.aim(self.targetx, self.targety) dx,dy = self.targetx - self.x, self.targety - self.y self.facing = direction(dx, dy) if self.fire and self.readyamo: self.fire -= 1 self.readyamo -= 1 self.reloading = RELOAD_TIME # STRATEGY: Firing restarts reload Bullet(self.x, self.y, dx, dy) elif self.reloading: self.reloading -= 1 if not self.reloading: SOUND_RELOAD.play() self.readyamo += 1 if self.readyamo < MAX_BULLETS: self.reloading = RELOAD_TIME def render(self, xy): #draw.line(SCREEN, BLACK, (self.x-30, self.y/2), (self.x+30, self.y/2)) #draw.line(SCREEN, BLACK, (self.x, self.y/2-20), (self.x, self.y/2+20)) BLIT(self.bodies[self.heading], xy) BLIT(self.turrets[self.facing], xy) BLIT(self.faces[self.facing], self.faceoffset + xy) def draw(self): self.render(ints(self.x-self.sx/2,(self.y-self.sy-TANK_HEIGHT)/2)) def hit(self): Explosion(self.sx, self.rect.center) self.dissapear()
def sub_collide(rtrn: list, rect_list: list, chck: pygame.Rect): rtrn.extend(chck.collidelistall(rect_list))
def draw(self, surface, bgd=None): """ Draws all sprites on the surface you pass in. You can pass the background too. If a background is already set, then the bgd argument has no effect. """ # speedups _orig_clip = surface.get_clip() _clip = self._clip if _clip is None: _clip = _orig_clip _surf = surface _sprites = self._spritelist _old_rect = self.spritedict _update = self.lostsprites _update_append = _update.append _ret = None _surf_blit = _surf.blit _rect = pygame.Rect if bgd is not None: self._bgd = bgd _bgd = self._bgd _surf.set_clip(_clip) # ------- # 0. deside if normal render of flip start_time = get_ticks() if self._use_update: # dirty rects mode # 1. find dirty area on screen and put the rects into _update # still not happy with that part for spr in _sprites: if 0 < spr.dirty: if spr.source_rect is not None: _union_rect = Rect(spr.rect.topleft, spr.source_rect.size) else: _union_rect = _rect(spr.rect) _union_rect_collidelist = _union_rect.collidelist _union_rect_union_ip = _union_rect.union_ip i = _union_rect_collidelist(_update) while -1 < i: _union_rect_union_ip(_update[i]) del _update[i] i = _union_rect_collidelist(_update) _update_append(_union_rect.clip(_clip)) _union_rect = _rect(_old_rect[spr]) _union_rect_collidelist = _union_rect.collidelist _union_rect_union_ip = _union_rect.union_ip i = _union_rect_collidelist(_update) while -1 < i: _union_rect_union_ip(_update[i]) del _update[i] i = _union_rect_collidelist(_update) _update_append(_union_rect.clip(_clip)) # can it be done better? because that is an O(n**2) algorithm in # worst case # clear using background if _bgd is not None: for rec in _update: _surf_blit(_bgd, rec, rec) # 2. draw for spr in _sprites: if 1 > spr.dirty: if spr._visible: # sprite not dirty, blit only the intersecting part if spr.source_rect is not None: _spr_rect = Rect(spr.rect.topleft, spr.source_rect.size) else: _spr_rect = spr.rect _spr_rect_clip = _spr_rect.clip for idx in _spr_rect.collidelistall(_update): # clip clip = _spr_rect_clip(_update[idx]) _surf_blit(spr.image, clip, \ (clip[0]-_spr_rect[0], \ clip[1]-_spr_rect[1], \ clip[2], \ clip[3]))#, spr.blendmode) else: # dirty sprite if spr._visible: if spr.source_rect is not None: _old_rect[spr] = _surf_blit(spr.image, spr.rect, \ spr.source_rect)#, spr.blendmode) else: _old_rect[spr] = _surf_blit(spr.image, spr.rect) if spr.dirty == 1: spr.dirty = 0 _ret = list(_update) else: # flip, full screen mode if _bgd is not None: _surf_blit(_bgd, (0, 0)) for spr in _sprites: if spr.visible: if spr.source_rect is not None: _old_rect[spr] = _surf_blit( spr.image, spr.rect, spr.source_rect) #,spr.blendmode) else: _old_rect[spr] = _surf_blit( spr.image, spr.rect) #, spr.source_rect)#,spr.blendmode) _ret = [_rect(_clip)] # return only the part of the screen changed # timing for switching modes # how to find a good treshold? it depends on the hardware it runs on end_time = get_ticks() if end_time - start_time > self._time_threshold: self._use_update = False else: self._use_update = True ## # debug ## print " check: using dirty rects:", self._use_update # emtpy dirty reas list _update[:] = [] # ------- # restore original clip _surf.set_clip(_orig_clip) return _ret