changeset 427:3ee839f227ad

Special relativistic gravities.
author davidsharpe@185.4.16.172.in-addr.arpa
date Sat, 07 Sep 2013 13:34:19 +0200
parents a64d894aa1bd
children 6bbb0ac87acc
files nagslang/game_object.py
diffstat 1 files changed, 42 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/nagslang/game_object.py	Sat Sep 07 13:30:06 2013 +0200
+++ b/nagslang/game_object.py	Sat Sep 07 13:34:19 2013 +0200
@@ -99,6 +99,33 @@
         return self._shape
 
 
+class MultiShapePhysicser(Physicser):
+    def __init__(self, space, shape, *extra_shapes):
+        super(MultiShapePhysicser, self).__init__(space)
+        self._shape = shape
+        self._extra_shapes = extra_shapes
+        shape.physicser = self
+
+    def get_shape(self):
+        return self._shape
+
+    def add_to_space(self):
+        shape = self.get_shape()
+        self.get_space().add(shape)
+        if not shape.body.is_static:
+            self.get_space().add(shape.body)
+        for s in self._extra_shapes:
+            self.get_space().add(s)
+
+    def remove_from_space(self):
+        shape = self.get_shape()
+        self.get_space().remove(shape)
+        if not shape.body.is_static:
+            self.get_space().remove(shape.body)
+        for s in self._extra_shapes:
+            self.get_space().remove(s)
+
+
 def damping_velocity_func(body, gravity, damping, dt):
     """Apply custom damping to this body's velocity.
     """
@@ -211,10 +238,8 @@
     def collide_with_claw_attack(self, claw_attack):
         return True
 
-    def environmental_movement(self, dx, dy):
-        if (dx, dy) == (0, 0):
-            return
-        self.physicser.apply_impulse((dx, dy))
+    def environmental_movement(self, vec):
+        self.physicser.apply_impulse(vec)
 
     @classmethod
     def requires(cls):
@@ -605,16 +630,19 @@
     # How often to hit the player
     rate = 5
 
-    def __init__(self, space, position, size, force):
-        body = make_body(10, pymunk.inf, position)
+    def __init__(self, space, position, radius, force):
+        body = make_body(None, None, position)
         # Adjust shape relative to position
-        self.shape = pymunk.Circle(body, size)
+        self._radius = radius
+        self.shape = pymunk.Circle(body, radius)
+        self.centre = pymunk.Circle(body, 10)
+        self.centre.friction = pymunk.inf
         self._ticks = 0
         self.force = force
         self.shape.collision_type = COLLISION_TYPE_SWITCH
         self.shape.sensor = True
         super(GravityWell, self).__init__(
-            SingleShapePhysicser(space, self.shape),
+            MultiShapePhysicser(space, self.shape, self.centre),
             render.ImageRenderer(resources.get_image(
                 'objects', 'gravity_well.png')),
         )
@@ -624,25 +652,20 @@
         # There are timing issues with stepping on and
         # off terrian, but as long as the rate is reasonably
         # low, they shouldn't impact gameplay
-        if self._ticks == 0:
-            self.apply_effect(protagonist)
-        self._ticks += 1
-        if self._ticks > self.rate:
-            self._ticks = 0
+        self.apply_effect(protagonist)
 
     def collide_with_furniture(self, furniture):
         # We're called every frame we're colliding, so
         # There are timing issues with stepping on and
         # off terrian, but as long as the rate is reasonably
         # low, they shouldn't impact gameplay
-        if self._ticks == 0:
-            self.apply_effect(furniture)
-        self._ticks += 1
-        if self._ticks > self.rate:
-            self._ticks = 0
+        self.apply_effect(furniture)
 
     def apply_effect(self, object_to_move):
-        object_to_move.environmental_movement(self.force, self.force)
+        movement = self.physicser.position - object_to_move.physicser.position
+        force = self.force * (1 - (self._radius / movement.length))
+        movement.length = force
+        object_to_move.environmental_movement(-movement)
 
     @classmethod
     def requires(cls):