Mercurial > skaapsteker
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 |
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 | 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 | 24 bounce_factor = (0.95, 0.95) # bounce factor |
121 | 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 | 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 | 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 | 41 def __init__(self, *args, **kwargs): |
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 | 44 self.velocity = (0.0, 0.0) |
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 | 48 self.image = pygame.Surface((10, 10)) |
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 | 52 |
53 def init_pos(self): | |
625 | 54 self._float_pos = cadd(self.rect.center, 0.0) # To make it a float |
121 | 55 |
39 | 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 | 58 |
625 | 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 | 61 return (self.velocity, self._float_pos) |
62 | |
63 def update_position(self, float_pos): | |
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 | 66 self.rect.center = cint(float_pos) |
67 displacement = csub(self.rect.center, old_pos) | |
68 self.collide_rect.move_ip(displacement) | |
69 self.floor_rect.move_ip(displacement) | |
70 | |
71 def apply_velocity(self, dt): | |
72 velocity, pos = self.get_vectors() | |
73 new_pos = cadd(pos, cmul(velocity, dt)) | |
74 self.update_position(new_pos) | |
66 | 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 | 89 pass |
66 | 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 | 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 | 113 if other.mobile: |
114 total_mass = self.mass + other.mass | |
115 f_self = self.mass / total_mass | |
116 f_other = other.mass / total_mass | |
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 | 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 | 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 | 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 | 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 | 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 | 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 | 232 |
619
4ffa9d159588
Some coordinate operators, to reduce foo_x, foo_y everywhere.
Jeremy Thurgood <firxen@gmail.com>
parents:
553
diff
changeset
|
233 |
625 | 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 | 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 | 240 def apply_friction(self): |
241 for sprite in self._mobiles: | |
242 sprite.apply_friction() | |
243 | |
244 def handle_escaped_sprites(self): | |
245 inbound = self._bounds.colliderect | |
246 for sprite in self._mobiles: | |
247 if not inbound(sprite): | |
248 sprite.fix_bounds(self._bounds) | |
249 | |
250 def get_dt(self): | |
251 now = time.time() | |
252 dt = now - self._last_time | |
253 self._last_time = now | |
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 | 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 | 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 | 326 |
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 | 331 sprite.on_solid = False |
332 for other in self._collision_groups[sprite.collision_layer]: | |
333 if (other.floor or other.block) and collides(other.floor_rect): | |
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 | 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 | 340 def update(self): |
341 if self._last_time is None: | |
342 self._last_time = time.time() | |
343 return | |
344 | |
345 dt = self.get_dt() | |
346 | |
347 self.apply_gravity(dt) | |
348 self.apply_friction() | |
349 self.handle_escaped_sprites() | |
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 | 352 self.handle_actions() |
116
69a97094417a
Hook up per-tick sprite animations.
Simon Cross <hodgestar@gmail.com>
parents:
112
diff
changeset
|
353 |
625 | 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 | 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 | 358 other_actor_collide_rect = other.collide_rect.inflate((4, 4)) |
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 | 363 def draw(self, surface): |
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 | 366 for sprite in self._all: |
367 sprite.draw_debug(surface) |