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)