Mercurial > skaapsteker
changeset 66:12ec95a2e8ea
Bouncing.
author | Simon Cross <hodgestar@gmail.com> |
---|---|
date | Sun, 03 Apr 2011 22:56:47 +0200 |
parents | bcf3d0b2a6d8 |
children | 64b135316b80 |
files | skaapsteker/constants.py skaapsteker/physics.py |
diffstat | 2 files changed, 45 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- 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
--- 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)