# HG changeset patch # User Simon Cross # Date 1301864207 -7200 # Node ID 12ec95a2e8ea8465a17c092c994222887e126746 # Parent bcf3d0b2a6d83ae7a18df8515e1d889d95b49a16 Bouncing. diff -r bcf3d0b2a6d8 -r 12ec95a2e8ea skaapsteker/constants.py --- a/skaapsteker/constants.py Sun Apr 03 22:46:25 2011 +0200 +++ b/skaapsteker/constants.py Sun Apr 03 22:56:47 2011 +0200 @@ -9,6 +9,8 @@ DEBUG = True +EPSILON = 1e-10 + # Layer defination class Layers(object): BACKGROUND = 0 # Absolute background diff -r bcf3d0b2a6d8 -r 12ec95a2e8ea skaapsteker/physics.py --- a/skaapsteker/physics.py Sun Apr 03 22:46:25 2011 +0200 +++ b/skaapsteker/physics.py Sun Apr 03 22:56:47 2011 +0200 @@ -7,7 +7,7 @@ import pygame.draw import pygame import time -from constants import DEBUG, Layers +from constants import DEBUG, EPSILON class Sprite(pygame.sprite.DirtySprite): @@ -25,7 +25,9 @@ self.visible = 1 self.dirty = 1 self.blendmode = 0 - self._layer = Layers.BACKGROUND + + def init_pos(self): + self._float_pos = self.rect.topleft def draw_debug(self, surface): pygame.draw.rect(surface, (240, 0, 0), self.rect, 1) @@ -42,8 +44,24 @@ def deltap(self, dt): v_x, v_y = self.velocity + f_x, f_y = self._float_pos d_x, d_y = v_x * dt, v_y * dt - self.rect.move_ip(d_x, d_y) + f_x, f_y = f_x + d_x, f_y + d_y + self._float_pos = f_x, f_y + self.rect.topleft = int(f_x), int(f_y) + + def collide(self, other): + print "Collided:", self, other + + def collide_immobile(self, immobile): + print "Collided with immobile:", self, immobile + v_x, v_y = self.velocity + clip = self.rect.clip(immobile.rect) + frac_x = clip.width / abs(v_x) if abs(v_x) > EPSILON else 0.0 + frac_y = clip.height / abs(v_y) if abs(v_y) > EPSILON else 0.0 + frac = max(frac_x, frac_y) + self.velocity = (-v_x, -v_y) + self.deltap(frac) class World(object): @@ -53,13 +71,17 @@ def __init__(self): self._all = pygame.sprite.LayeredUpdates() self._mobiles = pygame.sprite.Group() + self._immobiles = pygame.sprite.Group() self._gravitators = pygame.sprite.Group() self._last_time = None def add(self, sprite): + sprite.init_pos() self._all.add(sprite) if sprite.mobile: self._mobiles.add(sprite) + else: + self._immobiles.add(sprite) if sprite.gravitates: self._gravitators.add(sprite) @@ -82,10 +104,24 @@ sprite.deltap(dt) # check for collisions - for sprite1, sprites in pygame.sprite.groupcollide(self._mobiles, self._all, False, False).iteritems(): - for sprite2 in sprites: - if sprite1 is sprite2: - continue + collisions = [] + collide = collisions.append + for sprite1 in self._mobiles.sprites(): + spritecollide = sprite1.rect.colliderect + for sprite2 in self._mobiles.sprites(): + if id(sprite1) < id(sprite2) and spritecollide(sprite2): + collide((sprite1, sprite2)) + for sprite2 in self._immobiles.sprites(): + if spritecollide(sprite2): + collide((sprite1, sprite2)) + self.dispatch_collisions(collisions) + + def dispatch_collisions(self, collisions): + for s1, s2 in collisions: + if not s2.mobile: + s1.collide_immobile(s2) + else: + s1.collide(s2) def draw(self, surface): self._all.draw(surface)