Mercurial > skaapsteker
changeset 39:34038447be23
Very basic world physics.
author | Simon Cross <hodgestar@gmail.com> |
---|---|
date | Sun, 03 Apr 2011 20:24:17 +0200 |
parents | 38d7670a469a |
children | fa1bb94cfa76 |
files | skaapsteker/physics.py |
diffstat | 1 files changed, 48 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/skaapsteker/physics.py Sun Apr 03 20:22:56 2011 +0200 +++ b/skaapsteker/physics.py Sun Apr 03 20:24:17 2011 +0200 @@ -4,6 +4,8 @@ """ import pygame.sprite +import pygame +import time class Sprite(pygame.sprite.Sprite): @@ -11,13 +13,38 @@ mobile = True # whether the velocity may be non-zero gravitates = True # whether gravity applies to the sprite + terminal_velocity = (100.0, 100.0) # maximum horizontal and vertial speeds + + def __init__(self, *args, **kwargs): + super(Sprite, self).__init__(*args, **kwargs) + self.velocity = (0.0, 0.0) + self.rect = pygame.Rect(0, 0, 10, 10) # sub-classes should override + + def deltav(self, dv): + v_x, v_y = self.velocity + v_x, v_y = v_x + dv[0], v_y + dv[1] + + t_v = self.terminal_velocity + v_x = max(min(v_x, t_v[0]), -t_v[0]) + v_y = max(min(v_y, t_v[1]), -t_v[1]) + + self.velocity = (v_x, v_y) + + def deltap(self, dt): + v_x, v_y = self.velocity + d_x, d_y = v_x * dt, v_y * dt + self.rect.move(d_x, d_y) + class World(object): + GRAVITY = -9.8 # m/s^2 + def __init__(self): self._all = pygame.sprite.Group() self._mobiles = pygame.sprite.Group() self._gravitators = pygame.sprite.Group() + self._last_time = None def add(self, sprite): self._all.add(sprite) @@ -25,3 +52,24 @@ self._mobiles.add(sprite) if sprite.gravitates: self._gravitators.add(sprite) + + def update(self): + if self._last_time is None: + self._last_time = time.time() + return + + # find dt + now = time.time() + self._last_time, dt = now, now - self._last_time + + # gravity + dv = (0, self.GRAVITY * dt) + for sprite in self._gravitators: + sprite.deltav(dv) + + # position update (do last) + for sprite in self._mobiles: + sprite.deltap(dt) + + def draw(self, surface): + self._all.draw(surface)