annotate skaapsteker/physics.py @ 627:35919d12b792

Path-based collision minimisation and axis-projection backout.
author Jeremy Thurgood <firxen@gmail.com>
date Sat, 07 May 2011 20:28:06 +0200
parents 1abb53ae1a6a
children 59556235dec7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
22
b815471d4b95 Move sprite base class into physics since they're tightly coupled.
Simon Cross <hodgestar@gmail.com>
parents: 18
diff changeset
1 """Model of gravity, acceleration, velocities and collisions.
b815471d4b95 Move sprite base class into physics since they're tightly coupled.
Simon Cross <hodgestar@gmail.com>
parents: 18
diff changeset
2
b815471d4b95 Move sprite base class into physics since they're tightly coupled.
Simon Cross <hodgestar@gmail.com>
parents: 18
diff changeset
3 Works very closely with sprites/base.py.
b815471d4b95 Move sprite base class into physics since they're tightly coupled.
Simon Cross <hodgestar@gmail.com>
parents: 18
diff changeset
4 """
b815471d4b95 Move sprite base class into physics since they're tightly coupled.
Simon Cross <hodgestar@gmail.com>
parents: 18
diff changeset
5
105
c455b7925212 Global options in skaapsteker.__init__
Stefano Rivera <stefano@rivera.za.net>
parents: 104
diff changeset
6 import time
c455b7925212 Global options in skaapsteker.__init__
Stefano Rivera <stefano@rivera.za.net>
parents: 104
diff changeset
7
39
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
8 import pygame
105
c455b7925212 Global options in skaapsteker.__init__
Stefano Rivera <stefano@rivera.za.net>
parents: 104
diff changeset
9 import pygame.draw
c455b7925212 Global options in skaapsteker.__init__
Stefano Rivera <stefano@rivera.za.net>
parents: 104
diff changeset
10 import pygame.sprite
155
b2e0f1246c38 Hook up bitmasked based collisions (mask caching may be unnecessary, please comment on whether this effects performance for you).
Simon Cross <hodgestar@gmail.com>
parents: 152
diff changeset
11 from pygame.mask import from_surface
105
c455b7925212 Global options in skaapsteker.__init__
Stefano Rivera <stefano@rivera.za.net>
parents: 104
diff changeset
12
c455b7925212 Global options in skaapsteker.__init__
Stefano Rivera <stefano@rivera.za.net>
parents: 104
diff changeset
13 from . import options
c455b7925212 Global options in skaapsteker.__init__
Stefano Rivera <stefano@rivera.za.net>
parents: 104
diff changeset
14 from .constants import EPSILON
627
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
15 from .utils import (cadd, csub, cmul, cdiv, cclamp, cabsmax, cint, cneg, cabs,
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
16 rect_projection)
22
b815471d4b95 Move sprite base class into physics since they're tightly coupled.
Simon Cross <hodgestar@gmail.com>
parents: 18
diff changeset
17
128
36267deaccd8 Add friction. Remove old dirty sprite attributes.
Simon Cross <hodgestar@gmail.com>
parents: 122
diff changeset
18 class Sprite(pygame.sprite.Sprite):
22
b815471d4b95 Move sprite base class into physics since they're tightly coupled.
Simon Cross <hodgestar@gmail.com>
parents: 18
diff changeset
19
97
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
20 # physics attributes
22
b815471d4b95 Move sprite base class into physics since they're tightly coupled.
Simon Cross <hodgestar@gmail.com>
parents: 18
diff changeset
21 mobile = True # whether the velocity may be non-zero
b815471d4b95 Move sprite base class into physics since they're tightly coupled.
Simon Cross <hodgestar@gmail.com>
parents: 18
diff changeset
22 gravitates = True # whether gravity applies to the sprite
267
3bee081ad4ac Bump up horizontal terminal velocity so sprinting is interesting
Neil Muller <drnlmuller@gmail.com>
parents: 211
diff changeset
23 terminal_velocity = (900.0, 500.0) # maximum horizontal and vertial speeds (pixels / s)
112
394a032aeac7 Reduce bouncing.
Simon Cross <hodgestar@gmail.com>
parents: 105
diff changeset
24 bounce_factor = (0.95, 0.95) # bounce factor
121
5f5e43391395 Ramming speed, Mr Sulu\!
Simon Cross <hodgestar@gmail.com>
parents: 117
diff changeset
25 mass = 1.0 # used for shared collisions and applying forces
128
36267deaccd8 Add friction. Remove old dirty sprite attributes.
Simon Cross <hodgestar@gmail.com>
parents: 122
diff changeset
26 friction_coeff = (0.99, 0.99) # friction factor
39
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
27
97
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
28 # collision attributes
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
29 # Sprite X collides with Y iff (X.collision_layer in Y.collides_with) and X.check_collides(Y)
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
30 # Collisions result in the colliding movement being partially backed out, a call to X.bounce(frac) and a call to X.collided(Y)
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
31 # X.bounce(frac) is only called for the first (as determined by backing out distance) collision in a multi-collision event
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
32 collision_layer = None # never collides with anything
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
33 collides_with = set() # nothing collides with this
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
34
172
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
35 # set to True to have .update() called once per tick (and have .collision_group set)
116
69a97094417a Hook up per-tick sprite animations.
Simon Cross <hodgestar@gmail.com>
parents: 112
diff changeset
36 wants_updates = False
69a97094417a Hook up per-tick sprite animations.
Simon Cross <hodgestar@gmail.com>
parents: 112
diff changeset
37
146
5eb51736464c Use floor flag
Neil Muller <drnlmuller@gmail.com>
parents: 144
diff changeset
38 floor = False # We special case collisions with ground objects
155
b2e0f1246c38 Hook up bitmasked based collisions (mask caching may be unnecessary, please comment on whether this effects performance for you).
Simon Cross <hodgestar@gmail.com>
parents: 152
diff changeset
39 block = False
144
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
40
39
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
41 def __init__(self, *args, **kwargs):
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
42 super(Sprite, self).__init__(*args, **kwargs)
152
60138b935bc0 Make enemies block by default, so we can jump off them
Neil Muller <drnlmuller@gmail.com>
parents: 146
diff changeset
43 self.on_solid = False
39
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
44 self.velocity = (0.0, 0.0)
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
45 self.rect = pygame.Rect(0, 0, 10, 10) # sub-classes should override
122
51bcc909873d Saner, buggier collision rectangles
Neil Muller <drnlmuller@gmail.com>
parents: 121
diff changeset
46 self.collide_rect = pygame.Rect(0, 0, 10, 10) # rectangle we use for collisions
186
72e92893ccb8 Use layers for floor check
Neil Muller <drnlmuller@gmail.com>
parents: 177
diff changeset
47 self.floor_rect = self.collide_rect
43
abbc9ada8dc4 Enemies must fall
Simon Cross <hodgestar@gmail.com>
parents: 39
diff changeset
48 self.image = pygame.Surface((10, 10))
abbc9ada8dc4 Enemies must fall
Simon Cross <hodgestar@gmail.com>
parents: 39
diff changeset
49 self.image.fill((0, 0, 200))
172
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
50 self.collision_group = None
155
b2e0f1246c38 Hook up bitmasked based collisions (mask caching may be unnecessary, please comment on whether this effects performance for you).
Simon Cross <hodgestar@gmail.com>
parents: 152
diff changeset
51 self._mask_cache = {} # image id -> collision bit mask
66
12ec95a2e8ea Bouncing.
Simon Cross <hodgestar@gmail.com>
parents: 59
diff changeset
52
12ec95a2e8ea Bouncing.
Simon Cross <hodgestar@gmail.com>
parents: 59
diff changeset
53 def init_pos(self):
625
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
54 self._float_pos = cadd(self.rect.center, 0.0) # To make it a float
121
5f5e43391395 Ramming speed, Mr Sulu\!
Simon Cross <hodgestar@gmail.com>
parents: 117
diff changeset
55
39
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
56 def deltav(self, dv):
624
83569a6b3ad8 Fix StartingDoorway and velocity clamping.
Jeremy Thurgood <firxen@gmail.com>
parents: 623
diff changeset
57 self.velocity = cadd(self.velocity, dv)
39
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
58
625
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
59 def get_vectors(self):
624
83569a6b3ad8 Fix StartingDoorway and velocity clamping.
Jeremy Thurgood <firxen@gmail.com>
parents: 623
diff changeset
60 self.velocity = cclamp(self.velocity, self.terminal_velocity)
625
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
61 return (self.velocity, self._float_pos)
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
62
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
63 def update_position(self, float_pos):
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
64 self._float_pos = float_pos
622
da331c80ec08 Clean up sprite inheritance hierarchy a bit.
Jeremy Thurgood <firxen@gmail.com>
parents: 619
diff changeset
65 old_pos = self.rect.center
625
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
66 self.rect.center = cint(float_pos)
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
67 displacement = csub(self.rect.center, old_pos)
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
68 self.collide_rect.move_ip(displacement)
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
69 self.floor_rect.move_ip(displacement)
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
70
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
71 def apply_velocity(self, dt):
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
72 velocity, pos = self.get_vectors()
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
73 new_pos = cadd(pos, cmul(velocity, dt))
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
74 self.update_position(new_pos)
66
12ec95a2e8ea Bouncing.
Simon Cross <hodgestar@gmail.com>
parents: 59
diff changeset
75
155
b2e0f1246c38 Hook up bitmasked based collisions (mask caching may be unnecessary, please comment on whether this effects performance for you).
Simon Cross <hodgestar@gmail.com>
parents: 152
diff changeset
76 def _check_mask(self):
161
134ed5e026ae Neatean _check_mask a bit.
Simon Cross <hodgestar@gmail.com>
parents: 159
diff changeset
77 mask = self._mask_cache.get(id(self.image))
155
b2e0f1246c38 Hook up bitmasked based collisions (mask caching may be unnecessary, please comment on whether this effects performance for you).
Simon Cross <hodgestar@gmail.com>
parents: 152
diff changeset
78 if mask is None:
161
134ed5e026ae Neatean _check_mask a bit.
Simon Cross <hodgestar@gmail.com>
parents: 159
diff changeset
79 mask = self._mask_cache[id(self.image)] = from_surface(self.image)
155
b2e0f1246c38 Hook up bitmasked based collisions (mask caching may be unnecessary, please comment on whether this effects performance for you).
Simon Cross <hodgestar@gmail.com>
parents: 152
diff changeset
80 self.mask = mask
b2e0f1246c38 Hook up bitmasked based collisions (mask caching may be unnecessary, please comment on whether this effects performance for you).
Simon Cross <hodgestar@gmail.com>
parents: 152
diff changeset
81
97
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
82 def check_collides(self, other):
155
b2e0f1246c38 Hook up bitmasked based collisions (mask caching may be unnecessary, please comment on whether this effects performance for you).
Simon Cross <hodgestar@gmail.com>
parents: 152
diff changeset
83 # check bitmasks for collision
b2e0f1246c38 Hook up bitmasked based collisions (mask caching may be unnecessary, please comment on whether this effects performance for you).
Simon Cross <hodgestar@gmail.com>
parents: 152
diff changeset
84 self._check_mask()
b2e0f1246c38 Hook up bitmasked based collisions (mask caching may be unnecessary, please comment on whether this effects performance for you).
Simon Cross <hodgestar@gmail.com>
parents: 152
diff changeset
85 other._check_mask()
b2e0f1246c38 Hook up bitmasked based collisions (mask caching may be unnecessary, please comment on whether this effects performance for you).
Simon Cross <hodgestar@gmail.com>
parents: 152
diff changeset
86 return pygame.sprite.collide_mask(self, other)
97
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
87
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
88 def collided(self, other):
98
449a9579ec7a Remove a debugging print.
Simon Cross <hodgestar@gmail.com>
parents: 97
diff changeset
89 pass
66
12ec95a2e8ea Bouncing.
Simon Cross <hodgestar@gmail.com>
parents: 59
diff changeset
90
401
55e00f186c6f imported patch floor_checks
Neil Muller <drnlmuller@gmail.com>
parents: 273
diff changeset
91 def check_floors(self, floors):
55e00f186c6f imported patch floor_checks
Neil Muller <drnlmuller@gmail.com>
parents: 273
diff changeset
92 """Trigger of the current set of floors"""
55e00f186c6f imported patch floor_checks
Neil Muller <drnlmuller@gmail.com>
parents: 273
diff changeset
93 pass
55e00f186c6f imported patch floor_checks
Neil Muller <drnlmuller@gmail.com>
parents: 273
diff changeset
94
128
36267deaccd8 Add friction. Remove old dirty sprite attributes.
Simon Cross <hodgestar@gmail.com>
parents: 122
diff changeset
95 def apply_friction(self):
619
4ffa9d159588 Some coordinate operators, to reduce foo_x, foo_y everywhere.
Jeremy Thurgood <firxen@gmail.com>
parents: 553
diff changeset
96 self.velocity = cmul(self.velocity, self.friction_coeff)
128
36267deaccd8 Add friction. Remove old dirty sprite attributes.
Simon Cross <hodgestar@gmail.com>
parents: 122
diff changeset
97
97
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
98 def bounce(self, other, normal):
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
99 """Alter velocity after a collision.
78
f29b7ada68c1 Fix bouncing and tweak universal constants to show it off.
Simon Cross <hodgestar@gmail.com>
parents: 68
diff changeset
100
97
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
101 other: sprite collided with
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
102 normal: unit vector (tuple) normal to the collision
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
103 surface.
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
104 """
619
4ffa9d159588 Some coordinate operators, to reduce foo_x, foo_y everywhere.
Jeremy Thurgood <firxen@gmail.com>
parents: 553
diff changeset
105 bounce_factor = cadd(cmul(self.bounce_factor, other.bounce_factor), 1)
4ffa9d159588 Some coordinate operators, to reduce foo_x, foo_y everywhere.
Jeremy Thurgood <firxen@gmail.com>
parents: 553
diff changeset
106 deltav = cmul(cneg(normal), cmul(self.velocity, bounce_factor))
121
5f5e43391395 Ramming speed, Mr Sulu\!
Simon Cross <hodgestar@gmail.com>
parents: 117
diff changeset
107
619
4ffa9d159588 Some coordinate operators, to reduce foo_x, foo_y everywhere.
Jeremy Thurgood <firxen@gmail.com>
parents: 553
diff changeset
108 if normal == (0, 1) and (other.floor or other.block) and self.velocity[1] > 0 and self.collide_rect.top < other.collide_rect.top:
144
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
109 # Colliding with the ground from above is special
152
60138b935bc0 Make enemies block by default, so we can jump off them
Neil Muller <drnlmuller@gmail.com>
parents: 146
diff changeset
110 self.on_solid = True
619
4ffa9d159588 Some coordinate operators, to reduce foo_x, foo_y everywhere.
Jeremy Thurgood <firxen@gmail.com>
parents: 553
diff changeset
111 deltav = (deltav[0], -self.velocity[1])
144
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
112
121
5f5e43391395 Ramming speed, Mr Sulu\!
Simon Cross <hodgestar@gmail.com>
parents: 117
diff changeset
113 if other.mobile:
5f5e43391395 Ramming speed, Mr Sulu\!
Simon Cross <hodgestar@gmail.com>
parents: 117
diff changeset
114 total_mass = self.mass + other.mass
5f5e43391395 Ramming speed, Mr Sulu\!
Simon Cross <hodgestar@gmail.com>
parents: 117
diff changeset
115 f_self = self.mass / total_mass
5f5e43391395 Ramming speed, Mr Sulu\!
Simon Cross <hodgestar@gmail.com>
parents: 117
diff changeset
116 f_other = other.mass / total_mass
5f5e43391395 Ramming speed, Mr Sulu\!
Simon Cross <hodgestar@gmail.com>
parents: 117
diff changeset
117
619
4ffa9d159588 Some coordinate operators, to reduce foo_x, foo_y everywhere.
Jeremy Thurgood <firxen@gmail.com>
parents: 553
diff changeset
118 self.deltav(cmul(deltav, f_self))
4ffa9d159588 Some coordinate operators, to reduce foo_x, foo_y everywhere.
Jeremy Thurgood <firxen@gmail.com>
parents: 553
diff changeset
119 self.deltav(cmul(cneg(deltav), f_other))
121
5f5e43391395 Ramming speed, Mr Sulu\!
Simon Cross <hodgestar@gmail.com>
parents: 117
diff changeset
120 else:
619
4ffa9d159588 Some coordinate operators, to reduce foo_x, foo_y everywhere.
Jeremy Thurgood <firxen@gmail.com>
parents: 553
diff changeset
121 self.deltav(deltav) # oof
39
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
122
116
69a97094417a Hook up per-tick sprite animations.
Simon Cross <hodgestar@gmail.com>
parents: 112
diff changeset
123 def update(self):
69a97094417a Hook up per-tick sprite animations.
Simon Cross <hodgestar@gmail.com>
parents: 112
diff changeset
124 pass # only called in wants_update = True
69a97094417a Hook up per-tick sprite animations.
Simon Cross <hodgestar@gmail.com>
parents: 112
diff changeset
125
172
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
126 def check_collide_rect(self, new_collide_rect, new_rect, new_image):
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
127 if self.collision_group is None:
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
128 return True
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
129
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
130 # TODO: decide whether to throw out checking of existing
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
131 # collisions. Doesn't seem needed at the moment and takes
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
132 # time.
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
133 old_image = self.image
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
134 old_rect = self.rect
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
135 #rect_collides = self.collide_rect.colliderect
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
136 old_collisions = set()
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
137 #for other in self.collision_group:
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
138 # if rect_collides(other.collide_rect) \
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
139 # and self.check_collides(other):
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
140 # old_collisions.add(other)
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
141
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
142 self.image = new_image
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
143 self.rect = new_rect
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
144 new_rect_collides = new_collide_rect.colliderect
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
145 new_collisions = set()
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
146 for other in self.collision_group:
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
147 if new_rect_collides(other.collide_rect) \
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
148 and self.check_collides(other):
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
149 new_collisions.add(other)
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
150
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
151 self.image = old_image
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
152 self.rect = old_rect
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
153 return not bool(new_collisions - old_collisions)
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
154
422
7c0643e51f33 Pass bounds to sprite.fix_bounds
Neil Muller <drnlmuller@gmail.com>
parents: 416
diff changeset
155 def fix_bounds(self, bounds):
416
3db2fc263d11 Kill sprites that leave the level area.
Simon Cross <hodgestar@gmail.com>
parents: 401
diff changeset
156 self.kill()
3db2fc263d11 Kill sprites that leave the level area.
Simon Cross <hodgestar@gmail.com>
parents: 401
diff changeset
157
22
b815471d4b95 Move sprite base class into physics since they're tightly coupled.
Simon Cross <hodgestar@gmail.com>
parents: 18
diff changeset
158
b815471d4b95 Move sprite base class into physics since they're tightly coupled.
Simon Cross <hodgestar@gmail.com>
parents: 18
diff changeset
159 class World(object):
23
5c9f2eeeb629 Very start of world / physics engine.
Simon Cross <hodgestar@gmail.com>
parents: 22
diff changeset
160
619
4ffa9d159588 Some coordinate operators, to reduce foo_x, foo_y everywhere.
Jeremy Thurgood <firxen@gmail.com>
parents: 553
diff changeset
161 GRAVITY = cmul((0.0, 9.8), 80.0) # pixels / s^2
39
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
162
416
3db2fc263d11 Kill sprites that leave the level area.
Simon Cross <hodgestar@gmail.com>
parents: 401
diff changeset
163 def __init__(self, bounds):
57
e545236dd8f4 Change back to plain layered updater since everything is dirty all the time. Remove collision print since collisions appear to work.
Simon Cross <hodgestar@gmail.com>
parents: 53
diff changeset
164 self._all = pygame.sprite.LayeredUpdates()
23
5c9f2eeeb629 Very start of world / physics engine.
Simon Cross <hodgestar@gmail.com>
parents: 22
diff changeset
165 self._mobiles = pygame.sprite.Group()
5c9f2eeeb629 Very start of world / physics engine.
Simon Cross <hodgestar@gmail.com>
parents: 22
diff changeset
166 self._gravitators = pygame.sprite.Group()
116
69a97094417a Hook up per-tick sprite animations.
Simon Cross <hodgestar@gmail.com>
parents: 112
diff changeset
167 self._updaters = pygame.sprite.Group()
273
95e2ef31e714 Hit "down" to interact with things.
Jeremy Thurgood <firxen@gmail.com>
parents: 271
diff changeset
168 self._actionables = pygame.sprite.Group()
95e2ef31e714 Hit "down" to interact with things.
Jeremy Thurgood <firxen@gmail.com>
parents: 271
diff changeset
169 self._actors = pygame.sprite.Group()
97
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
170 self._collision_groups = { None: pygame.sprite.Group() }
39
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
171 self._last_time = None
416
3db2fc263d11 Kill sprites that leave the level area.
Simon Cross <hodgestar@gmail.com>
parents: 401
diff changeset
172 self._bounds = bounds
23
5c9f2eeeb629 Very start of world / physics engine.
Simon Cross <hodgestar@gmail.com>
parents: 22
diff changeset
173
104
12ce1d131a72 Hack in resume game option
Neil Muller <drnlmuller@gmail.com>
parents: 103
diff changeset
174 def freeze(self):
12ce1d131a72 Hack in resume game option
Neil Muller <drnlmuller@gmail.com>
parents: 103
diff changeset
175 self._last_time = None
12ce1d131a72 Hack in resume game option
Neil Muller <drnlmuller@gmail.com>
parents: 103
diff changeset
176
12ce1d131a72 Hack in resume game option
Neil Muller <drnlmuller@gmail.com>
parents: 103
diff changeset
177 def thaw(self):
12ce1d131a72 Hack in resume game option
Neil Muller <drnlmuller@gmail.com>
parents: 103
diff changeset
178 self._last_time = time.time()
12ce1d131a72 Hack in resume game option
Neil Muller <drnlmuller@gmail.com>
parents: 103
diff changeset
179
23
5c9f2eeeb629 Very start of world / physics engine.
Simon Cross <hodgestar@gmail.com>
parents: 22
diff changeset
180 def add(self, sprite):
66
12ec95a2e8ea Bouncing.
Simon Cross <hodgestar@gmail.com>
parents: 59
diff changeset
181 sprite.init_pos()
23
5c9f2eeeb629 Very start of world / physics engine.
Simon Cross <hodgestar@gmail.com>
parents: 22
diff changeset
182 self._all.add(sprite)
5c9f2eeeb629 Very start of world / physics engine.
Simon Cross <hodgestar@gmail.com>
parents: 22
diff changeset
183 if sprite.mobile:
5c9f2eeeb629 Very start of world / physics engine.
Simon Cross <hodgestar@gmail.com>
parents: 22
diff changeset
184 self._mobiles.add(sprite)
5c9f2eeeb629 Very start of world / physics engine.
Simon Cross <hodgestar@gmail.com>
parents: 22
diff changeset
185 if sprite.gravitates:
5c9f2eeeb629 Very start of world / physics engine.
Simon Cross <hodgestar@gmail.com>
parents: 22
diff changeset
186 self._gravitators.add(sprite)
116
69a97094417a Hook up per-tick sprite animations.
Simon Cross <hodgestar@gmail.com>
parents: 112
diff changeset
187 if sprite.wants_updates:
69a97094417a Hook up per-tick sprite animations.
Simon Cross <hodgestar@gmail.com>
parents: 112
diff changeset
188 self._updaters.add(sprite)
97
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
189 self._add_collision_group(sprite.collision_layer)
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
190 for layer in sprite.collides_with:
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
191 self._add_collision_group(layer)
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
192 self._collision_groups[layer].add(sprite)
172
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
193 if sprite.wants_updates:
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
194 self._updaters.add(sprite)
bf144d817113 if year in range(1980, 1990): continue # how can we sleep while the kitsune is stuck to the floor?
Simon Cross <hodgestar@gmail.com>
parents: 161
diff changeset
195 sprite.collision_group = self._collision_groups[sprite.collision_layer]
273
95e2ef31e714 Hit "down" to interact with things.
Jeremy Thurgood <firxen@gmail.com>
parents: 271
diff changeset
196 if getattr(sprite, 'player_action', None) is not None:
95e2ef31e714 Hit "down" to interact with things.
Jeremy Thurgood <firxen@gmail.com>
parents: 271
diff changeset
197 self._actionables.add(sprite)
95e2ef31e714 Hit "down" to interact with things.
Jeremy Thurgood <firxen@gmail.com>
parents: 271
diff changeset
198 if getattr(sprite, 'add_actionable', None) is not None:
95e2ef31e714 Hit "down" to interact with things.
Jeremy Thurgood <firxen@gmail.com>
parents: 271
diff changeset
199 self._actors.add(sprite)
97
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
200
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
201 def _add_collision_group(self, layer):
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
202 if layer in self._collision_groups:
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
203 return
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
204 self._collision_groups[layer] = pygame.sprite.Group()
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
205
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
206 def _backout_collisions(self, sprite, others, dt):
271
56a529a69e97 Only backout / move-off "solid" collisions
Neil Muller <drnlmuller@gmail.com>
parents: 267
diff changeset
207 frac, normal, idx = 0.0, None, None
619
4ffa9d159588 Some coordinate operators, to reduce foo_x, foo_y everywhere.
Jeremy Thurgood <firxen@gmail.com>
parents: 553
diff changeset
208 abs_v_x, abs_v_y = cabs(sprite.velocity)
97
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
209
271
56a529a69e97 Only backout / move-off "solid" collisions
Neil Muller <drnlmuller@gmail.com>
parents: 267
diff changeset
210 # We only backout of "solide" collisions
56a529a69e97 Only backout / move-off "solid" collisions
Neil Muller <drnlmuller@gmail.com>
parents: 267
diff changeset
211 if sprite.block:
56a529a69e97 Only backout / move-off "solid" collisions
Neil Muller <drnlmuller@gmail.com>
parents: 267
diff changeset
212 for i, other in enumerate(others):
56a529a69e97 Only backout / move-off "solid" collisions
Neil Muller <drnlmuller@gmail.com>
parents: 267
diff changeset
213 if other.block or other.floor:
56a529a69e97 Only backout / move-off "solid" collisions
Neil Muller <drnlmuller@gmail.com>
parents: 267
diff changeset
214 clip = sprite.collide_rect.clip(other.collide_rect)
56a529a69e97 Only backout / move-off "solid" collisions
Neil Muller <drnlmuller@gmail.com>
parents: 267
diff changeset
215 # TODO: avoid continual "if abs_v_? > EPSILON"
56a529a69e97 Only backout / move-off "solid" collisions
Neil Muller <drnlmuller@gmail.com>
parents: 267
diff changeset
216 frac_x = clip.width / abs_v_x if abs_v_x > EPSILON else dt
56a529a69e97 Only backout / move-off "solid" collisions
Neil Muller <drnlmuller@gmail.com>
parents: 267
diff changeset
217 frac_y = clip.height / abs_v_y if abs_v_y > EPSILON else dt
56a529a69e97 Only backout / move-off "solid" collisions
Neil Muller <drnlmuller@gmail.com>
parents: 267
diff changeset
218 if frac_x > frac_y:
56a529a69e97 Only backout / move-off "solid" collisions
Neil Muller <drnlmuller@gmail.com>
parents: 267
diff changeset
219 if frac_y > frac:
56a529a69e97 Only backout / move-off "solid" collisions
Neil Muller <drnlmuller@gmail.com>
parents: 267
diff changeset
220 frac, normal, idx = frac_y, (0, 1), i
56a529a69e97 Only backout / move-off "solid" collisions
Neil Muller <drnlmuller@gmail.com>
parents: 267
diff changeset
221 else:
56a529a69e97 Only backout / move-off "solid" collisions
Neil Muller <drnlmuller@gmail.com>
parents: 267
diff changeset
222 if frac_x > frac:
56a529a69e97 Only backout / move-off "solid" collisions
Neil Muller <drnlmuller@gmail.com>
parents: 267
diff changeset
223 frac, normal, idx = frac_x, (1, 0), i
97
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
224
271
56a529a69e97 Only backout / move-off "solid" collisions
Neil Muller <drnlmuller@gmail.com>
parents: 267
diff changeset
225 if idx is not None:
56a529a69e97 Only backout / move-off "solid" collisions
Neil Muller <drnlmuller@gmail.com>
parents: 267
diff changeset
226 # We can see no solide collisions now
625
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
227 sprite.apply_velocity(max(-1.1 * frac, -dt))
271
56a529a69e97 Only backout / move-off "solid" collisions
Neil Muller <drnlmuller@gmail.com>
parents: 267
diff changeset
228 sprite.bounce(others[idx], normal)
128
36267deaccd8 Add friction. Remove old dirty sprite attributes.
Simon Cross <hodgestar@gmail.com>
parents: 122
diff changeset
229
97
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
230 for other in others:
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
231 sprite.collided(other)
39
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
232
619
4ffa9d159588 Some coordinate operators, to reduce foo_x, foo_y everywhere.
Jeremy Thurgood <firxen@gmail.com>
parents: 553
diff changeset
233
625
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
234 def apply_gravity(self, dt):
619
4ffa9d159588 Some coordinate operators, to reduce foo_x, foo_y everywhere.
Jeremy Thurgood <firxen@gmail.com>
parents: 553
diff changeset
235 dv = cmul(self.GRAVITY, dt)
4ffa9d159588 Some coordinate operators, to reduce foo_x, foo_y everywhere.
Jeremy Thurgood <firxen@gmail.com>
parents: 553
diff changeset
236 for sprite in self._gravitators:
625
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
237 if not sprite.on_solid:
619
4ffa9d159588 Some coordinate operators, to reduce foo_x, foo_y everywhere.
Jeremy Thurgood <firxen@gmail.com>
parents: 553
diff changeset
238 sprite.deltav(dv)
4ffa9d159588 Some coordinate operators, to reduce foo_x, foo_y everywhere.
Jeremy Thurgood <firxen@gmail.com>
parents: 553
diff changeset
239
625
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
240 def apply_friction(self):
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
241 for sprite in self._mobiles:
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
242 sprite.apply_friction()
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
243
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
244 def handle_escaped_sprites(self):
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
245 inbound = self._bounds.colliderect
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
246 for sprite in self._mobiles:
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
247 if not inbound(sprite):
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
248 sprite.fix_bounds(self._bounds)
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
249
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
250 def get_dt(self):
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
251 now = time.time()
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
252 dt = now - self._last_time
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
253 self._last_time = now
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
254 return dt
619
4ffa9d159588 Some coordinate operators, to reduce foo_x, foo_y everywhere.
Jeremy Thurgood <firxen@gmail.com>
parents: 553
diff changeset
255
627
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
256
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
257 # def collide_sprite(self, dt, sprite):
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
258 # sprite.apply_velocity(dt)
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
259 # sprite_collides = sprite.collide_rect.colliderect
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
260 # collisions = []
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
261 # for other in self._collision_groups[sprite.collision_layer]:
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
262 # if sprite_collides(other.collide_rect) \
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
263 # and sprite.check_collides(other):
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
264 # collisions.append(other)
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
265 # if collisions:
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
266 # self._backout_collisions(sprite, collisions, dt)
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
267 # contact_rect = pygame.Rect(
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
268 # (sprite.collide_rect.left, sprite.collide_rect.bottom),
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
269 # (sprite.collide_rect.width, 1))
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
270 # return contact_rect.colliderect
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
271
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
272
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
273 def get_sprite_collisions(self, dt, sprite):
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
274 sprite.apply_velocity(dt)
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
275 sprite_collides = sprite.collide_rect.colliderect
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
276 collisions = []
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
277 for other in self._collision_groups[sprite.collision_layer]:
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
278 if (sprite_collides(other.collide_rect)
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
279 and sprite.check_collides(other)):
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
280 collisions.append(other)
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
281 return collisions
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
282
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
283
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
284 def path_collide(self, dt, sprite):
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
285 dts = [dt/10] * 9
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
286 dts.append(dt - sum(dts))
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
287 dtf_acc = 0
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
288 collisions = []
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
289 for dtf in dts:
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
290 dtf_acc += dtf
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
291 collisions = self.get_sprite_collisions(dtf, sprite)
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
292 for col in collisions:
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
293 if sprite.block and (col.floor or col.block):
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
294 return collisions, dtf_acc
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
295 return collisions, dt
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
296
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
297
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
298 def collide_sprite(self, dt, sprite):
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
299 initial_pos = sprite._float_pos
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
300 collisions = self.get_sprite_collisions(dt, sprite)
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
301 escape_vector = (0, 0)
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
302 if collisions:
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
303 # If we've collided, reset and try again with smaller time increments
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
304 sprite.update_position(initial_pos)
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
305 collisions, dtf = self.path_collide(dt, sprite)
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
306 for col in collisions:
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
307 if sprite.block and (col.floor or col.block):
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
308 escape_vector = cabsmax(escape_vector, rect_projection(sprite.collide_rect, col.collide_rect))
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
309 sprite.collided(col)
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
310 sprite.update_position(cadd(sprite._float_pos, escape_vector))
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
311 # if escape_vector[0] != 0:
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
312 # sprite.velocity = (0, sprite.velocity[1])
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
313 # if escape_vector[1] != 0:
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
314 # sprite.velocity = (sprite.velocity[0], 1)
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
315 # self._backout_collisions(sprite, collisions, dtf)
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
316 contact_rect = pygame.Rect(
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
317 cadd(sprite.collide_rect.bottomleft, (1, 0)),
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
318 (sprite.collide_rect.width, 1))
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
319 return contact_rect.colliderect
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
320
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
321
626
1abb53ae1a6a More mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 625
diff changeset
322 def update_sprite_positions(self, dt):
97
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
323 # position update and collision check (do last)
39
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
324 for sprite in self._mobiles:
627
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
325 collides = self.collide_sprite(dt, sprite)
626
1abb53ae1a6a More mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 625
diff changeset
326
1abb53ae1a6a More mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 625
diff changeset
327 # Are we currently in contact with the ground?
627
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
328 if not sprite.block:
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
329 continue
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
330 floors = []
626
1abb53ae1a6a More mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 625
diff changeset
331 sprite.on_solid = False
1abb53ae1a6a More mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 625
diff changeset
332 for other in self._collision_groups[sprite.collision_layer]:
1abb53ae1a6a More mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 625
diff changeset
333 if (other.floor or other.block) and collides(other.floor_rect):
1abb53ae1a6a More mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 625
diff changeset
334 sprite.on_solid = True
627
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
335 if sprite.velocity[1] > 0:
35919d12b792 Path-based collision minimisation and axis-projection backout.
Jeremy Thurgood <firxen@gmail.com>
parents: 626
diff changeset
336 sprite.velocity = (sprite.velocity[0], 0)
626
1abb53ae1a6a More mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 625
diff changeset
337 floors.append(other)
401
55e00f186c6f imported patch floor_checks
Neil Muller <drnlmuller@gmail.com>
parents: 273
diff changeset
338 sprite.check_floors(floors)
144
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
339
626
1abb53ae1a6a More mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 625
diff changeset
340 def update(self):
1abb53ae1a6a More mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 625
diff changeset
341 if self._last_time is None:
1abb53ae1a6a More mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 625
diff changeset
342 self._last_time = time.time()
1abb53ae1a6a More mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 625
diff changeset
343 return
1abb53ae1a6a More mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 625
diff changeset
344
1abb53ae1a6a More mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 625
diff changeset
345 dt = self.get_dt()
1abb53ae1a6a More mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 625
diff changeset
346
1abb53ae1a6a More mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 625
diff changeset
347 self.apply_gravity(dt)
1abb53ae1a6a More mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 625
diff changeset
348 self.apply_friction()
1abb53ae1a6a More mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 625
diff changeset
349 self.handle_escaped_sprites()
1abb53ae1a6a More mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 625
diff changeset
350 self.update_sprite_positions(dt)
116
69a97094417a Hook up per-tick sprite animations.
Simon Cross <hodgestar@gmail.com>
parents: 112
diff changeset
351 self._updaters.update()
625
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
352 self.handle_actions()
116
69a97094417a Hook up per-tick sprite animations.
Simon Cross <hodgestar@gmail.com>
parents: 112
diff changeset
353
625
65882990b9cf Some mild refactoring.
Jeremy Thurgood <firxen@gmail.com>
parents: 624
diff changeset
354 def handle_actions(self):
273
95e2ef31e714 Hit "down" to interact with things.
Jeremy Thurgood <firxen@gmail.com>
parents: 271
diff changeset
355 for sprite in self._actors:
460
8b9b4706a4d6 Blocking NPC's block
Neil Muller <drnlmuller@gmail.com>
parents: 422
diff changeset
356 actor_collide_rect = sprite.collide_rect.inflate((4, 4))
273
95e2ef31e714 Hit "down" to interact with things.
Jeremy Thurgood <firxen@gmail.com>
parents: 271
diff changeset
357 for other in self._actionables:
460
8b9b4706a4d6 Blocking NPC's block
Neil Muller <drnlmuller@gmail.com>
parents: 422
diff changeset
358 other_actor_collide_rect = other.collide_rect.inflate((4, 4))
8b9b4706a4d6 Blocking NPC's block
Neil Muller <drnlmuller@gmail.com>
parents: 422
diff changeset
359 if actor_collide_rect.colliderect(other_actor_collide_rect):
273
95e2ef31e714 Hit "down" to interact with things.
Jeremy Thurgood <firxen@gmail.com>
parents: 271
diff changeset
360 sprite.add_actionable(other)
95e2ef31e714 Hit "down" to interact with things.
Jeremy Thurgood <firxen@gmail.com>
parents: 271
diff changeset
361
95e2ef31e714 Hit "down" to interact with things.
Jeremy Thurgood <firxen@gmail.com>
parents: 271
diff changeset
362
39
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
363 def draw(self, surface):
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
364 self._all.draw(surface)
105
c455b7925212 Global options in skaapsteker.__init__
Stefano Rivera <stefano@rivera.za.net>
parents: 104
diff changeset
365 if options['debug_rects']:
53
01cfef3a5acf Add debugging rectangles.
Simon Cross <hodgestar@gmail.com>
parents: 51
diff changeset
366 for sprite in self._all:
01cfef3a5acf Add debugging rectangles.
Simon Cross <hodgestar@gmail.com>
parents: 51
diff changeset
367 sprite.draw_debug(surface)