# HG changeset patch # User Simon Cross # Date 1302046520 -7200 # Node ID bf144d817113f264e052f3c8abd8ced3ae0e6b90 # Parent 13e10b877f6cfa14b9c510d7200f800215f45bc9 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor? diff -r 13e10b877f6c -r bf144d817113 skaapsteker/physics.py --- a/skaapsteker/physics.py Wed Apr 06 01:04:43 2011 +0200 +++ b/skaapsteker/physics.py Wed Apr 06 01:35:20 2011 +0200 @@ -30,7 +30,7 @@ collision_layer = None # never collides with anything collides_with = set() # nothing collides with this - # set to True to have .update() called once per tick + # set to True to have .update() called once per tick (and have .collision_group set) wants_updates = False debug_color = (240, 0, 0) @@ -46,6 +46,7 @@ self.collide_rect = pygame.Rect(0, 0, 10, 10) # rectangle we use for collisions self.image = pygame.Surface((10, 10)) self.image.fill((0, 0, 200)) + self.collision_group = None self._mask_cache = {} # image id -> collision bit mask def init_pos(self): @@ -133,6 +134,35 @@ def update(self): pass # only called in wants_update = True + def check_collide_rect(self, new_collide_rect, new_rect, new_image): + if self.collision_group is None: + return True + + # TODO: decide whether to throw out checking of existing + # collisions. Doesn't seem needed at the moment and takes + # time. + old_image = self.image + old_rect = self.rect + #rect_collides = self.collide_rect.colliderect + old_collisions = set() + #for other in self.collision_group: + # if rect_collides(other.collide_rect) \ + # and self.check_collides(other): + # old_collisions.add(other) + + self.image = new_image + self.rect = new_rect + new_rect_collides = new_collide_rect.colliderect + new_collisions = set() + for other in self.collision_group: + if new_rect_collides(other.collide_rect) \ + and self.check_collides(other): + new_collisions.add(other) + + self.image = old_image + self.rect = old_rect + return not bool(new_collisions - old_collisions) + class World(object): @@ -165,6 +195,9 @@ for layer in sprite.collides_with: self._add_collision_group(layer) self._collision_groups[layer].add(sprite) + if sprite.wants_updates: + self._updaters.add(sprite) + sprite.collision_group = self._collision_groups[sprite.collision_layer] def _add_collision_group(self, layer): if layer in self._collision_groups: diff -r 13e10b877f6c -r bf144d817113 skaapsteker/sprites/player.py --- a/skaapsteker/sprites/player.py Wed Apr 06 01:04:43 2011 +0200 +++ b/skaapsteker/sprites/player.py Wed Apr 06 01:35:20 2011 +0200 @@ -22,7 +22,6 @@ self.rect = None self._image_dict = {} self._animation_frame = 0.0 - self._recent_collisions = [] self._last_time = time.time() # State flags and such self.running = False @@ -45,19 +44,21 @@ cur_pos = self.collide_rect.midbottom else: cur_pos = (0, 0) + + # TODO: can save a lot of calculation here by caching collision rects cand_image = images[int(self._animation_frame)] - cand_collide_rect = cand_image.get_bounding_rect(1) + cand_collide_rect = cand_image.get_bounding_rect(1).inflate(-2,-2) + cand_rect = cand_image.get_rect() + cand_rect_offset = cand_rect.centerx - cand_collide_rect.centerx, cand_rect.bottom - cand_collide_rect.bottom + cand_rect.midbottom = cur_pos[0] + cand_rect_offset[0], cur_pos[1] + cand_rect_offset[1] cand_collide_rect.midbottom = cur_pos - if cand_collide_rect.collidelist(self._recent_collisions) != -1 \ - and self.collide_rect.collidelist(self._recent_collisions) == -1: - # We introduce a new collision, so don't update the image + if not self.check_collide_rect(cand_collide_rect, cand_rect, cand_image): return - self.image = images[int(self._animation_frame)] - self.collide_rect = self.image.get_bounding_rect(1) - self.rect = self.image.get_rect() - self.rect_offset = self.rect.centerx - self.collide_rect.centerx, self.rect.bottom - self.collide_rect.bottom - self.collide_rect.midbottom = cur_pos - self.rect.midbottom = cur_pos[0] + self.rect_offset[0], cur_pos[1] + self.rect_offset[1] + + self.image = cand_image + self.collide_rect = cand_collide_rect + self.rect = cand_rect + self.rect_offset = cand_rect_offset self.init_pos() def update(self): @@ -89,9 +90,7 @@ self.facing = new_facing def collided(self, other): - self._recent_collisions.append(other.collide_rect) - while len(self._recent_collisions) > 10: - self._recent_collisions.pop(0) + pass def set_pos(self, pos): self.starting_tile_pos = pos