annotate skaapsteker/physics.py @ 146:5eb51736464c

Use floor flag
author Neil Muller <drnlmuller@gmail.com>
date Tue, 05 Apr 2011 16:35:30 +0200
parents 6b488e1351a5
children 60138b935bc0
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
c455b7925212 Global options in skaapsteker.__init__
Stefano Rivera <stefano@rivera.za.net>
parents: 104
diff changeset
11
c455b7925212 Global options in skaapsteker.__init__
Stefano Rivera <stefano@rivera.za.net>
parents: 104
diff changeset
12 from . import options
c455b7925212 Global options in skaapsteker.__init__
Stefano Rivera <stefano@rivera.za.net>
parents: 104
diff changeset
13 from .constants import EPSILON
22
b815471d4b95 Move sprite base class into physics since they're tightly coupled.
Simon Cross <hodgestar@gmail.com>
parents: 18
diff changeset
14
128
36267deaccd8 Add friction. Remove old dirty sprite attributes.
Simon Cross <hodgestar@gmail.com>
parents: 122
diff changeset
15 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
16
97
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
17 # physics attributes
22
b815471d4b95 Move sprite base class into physics since they're tightly coupled.
Simon Cross <hodgestar@gmail.com>
parents: 18
diff changeset
18 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
19 gravitates = True # whether gravity applies to the sprite
144
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
20 terminal_velocity = (450.0, 450.0) # maximum horizontal and vertial speeds (pixels / s)
112
394a032aeac7 Reduce bouncing.
Simon Cross <hodgestar@gmail.com>
parents: 105
diff changeset
21 bounce_factor = (0.95, 0.95) # bounce factor
121
5f5e43391395 Ramming speed, Mr Sulu\!
Simon Cross <hodgestar@gmail.com>
parents: 117
diff changeset
22 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
23 friction_coeff = (0.99, 0.99) # friction factor
39
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
24
97
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
25 # collision attributes
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
26 # 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
27 # 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
28 # 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
29 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
30 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
31
116
69a97094417a Hook up per-tick sprite animations.
Simon Cross <hodgestar@gmail.com>
parents: 112
diff changeset
32 # set to True to have .update() called once per tick
69a97094417a Hook up per-tick sprite animations.
Simon Cross <hodgestar@gmail.com>
parents: 112
diff changeset
33 wants_updates = False
69a97094417a Hook up per-tick sprite animations.
Simon Cross <hodgestar@gmail.com>
parents: 112
diff changeset
34
117
b361d9e17c26 Angry fruit salad debug boxes.
Jeremy Thurgood <firxen@gmail.com>
parents: 116
diff changeset
35 debug_color = (240, 0, 0)
b361d9e17c26 Angry fruit salad debug boxes.
Jeremy Thurgood <firxen@gmail.com>
parents: 116
diff changeset
36
146
5eb51736464c Use floor flag
Neil Muller <drnlmuller@gmail.com>
parents: 144
diff changeset
37 floor = False # We special case collisions with ground objects
144
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
38
39
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
39 def __init__(self, *args, **kwargs):
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
40 super(Sprite, self).__init__(*args, **kwargs)
144
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
41 self.on_ground = False
39
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
42 self.velocity = (0.0, 0.0)
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
43 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
44 self.collide_rect = pygame.Rect(0, 0, 10, 10) # rectangle we use for collisions
43
abbc9ada8dc4 Enemies must fall
Simon Cross <hodgestar@gmail.com>
parents: 39
diff changeset
45 self.image = pygame.Surface((10, 10))
abbc9ada8dc4 Enemies must fall
Simon Cross <hodgestar@gmail.com>
parents: 39
diff changeset
46 self.image.fill((0, 0, 200))
66
12ec95a2e8ea Bouncing.
Simon Cross <hodgestar@gmail.com>
parents: 59
diff changeset
47
12ec95a2e8ea Bouncing.
Simon Cross <hodgestar@gmail.com>
parents: 59
diff changeset
48 def init_pos(self):
12ec95a2e8ea Bouncing.
Simon Cross <hodgestar@gmail.com>
parents: 59
diff changeset
49 self._float_pos = self.rect.topleft
39
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
50
117
b361d9e17c26 Angry fruit salad debug boxes.
Jeremy Thurgood <firxen@gmail.com>
parents: 116
diff changeset
51 def get_debug_color(self):
b361d9e17c26 Angry fruit salad debug boxes.
Jeremy Thurgood <firxen@gmail.com>
parents: 116
diff changeset
52 return self.debug_color
b361d9e17c26 Angry fruit salad debug boxes.
Jeremy Thurgood <firxen@gmail.com>
parents: 116
diff changeset
53
53
01cfef3a5acf Add debugging rectangles.
Simon Cross <hodgestar@gmail.com>
parents: 51
diff changeset
54 def draw_debug(self, surface):
122
51bcc909873d Saner, buggier collision rectangles
Neil Muller <drnlmuller@gmail.com>
parents: 121
diff changeset
55 pygame.draw.rect(surface, (240, 0, 0), self.collide_rect, 1)
51bcc909873d Saner, buggier collision rectangles
Neil Muller <drnlmuller@gmail.com>
parents: 121
diff changeset
56 pygame.draw.rect(surface, self.get_debug_color(), self.collide_rect, 1)
53
01cfef3a5acf Add debugging rectangles.
Simon Cross <hodgestar@gmail.com>
parents: 51
diff changeset
57
121
5f5e43391395 Ramming speed, Mr Sulu\!
Simon Cross <hodgestar@gmail.com>
parents: 117
diff changeset
58 def deltaf(self, df):
5f5e43391395 Ramming speed, Mr Sulu\!
Simon Cross <hodgestar@gmail.com>
parents: 117
diff changeset
59 dv = df[0] / self.mass, df[1] / self.mass
5f5e43391395 Ramming speed, Mr Sulu\!
Simon Cross <hodgestar@gmail.com>
parents: 117
diff changeset
60 self.deltav(dv)
5f5e43391395 Ramming speed, Mr Sulu\!
Simon Cross <hodgestar@gmail.com>
parents: 117
diff changeset
61
39
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
62 def deltav(self, dv):
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
63 v_x, v_y = self.velocity
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
64 v_x, v_y = v_x + dv[0], v_y + dv[1]
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
65
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
66 t_v = self.terminal_velocity
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
67 v_x = max(min(v_x, t_v[0]), -t_v[0])
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
68 v_y = max(min(v_y, t_v[1]), -t_v[1])
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
69
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
70 self.velocity = (v_x, v_y)
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
71
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
72 def deltap(self, dt):
122
51bcc909873d Saner, buggier collision rectangles
Neil Muller <drnlmuller@gmail.com>
parents: 121
diff changeset
73 old_pos = self.rect.topleft
39
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
74 v_x, v_y = self.velocity
66
12ec95a2e8ea Bouncing.
Simon Cross <hodgestar@gmail.com>
parents: 59
diff changeset
75 f_x, f_y = self._float_pos
39
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
76 d_x, d_y = v_x * dt, v_y * dt
66
12ec95a2e8ea Bouncing.
Simon Cross <hodgestar@gmail.com>
parents: 59
diff changeset
77 f_x, f_y = f_x + d_x, f_y + d_y
12ec95a2e8ea Bouncing.
Simon Cross <hodgestar@gmail.com>
parents: 59
diff changeset
78 self._float_pos = f_x, f_y
12ec95a2e8ea Bouncing.
Simon Cross <hodgestar@gmail.com>
parents: 59
diff changeset
79 self.rect.topleft = int(f_x), int(f_y)
122
51bcc909873d Saner, buggier collision rectangles
Neil Muller <drnlmuller@gmail.com>
parents: 121
diff changeset
80 delta_pos = self.rect.left - old_pos[0], self.rect.top - old_pos[1]
51bcc909873d Saner, buggier collision rectangles
Neil Muller <drnlmuller@gmail.com>
parents: 121
diff changeset
81 self.collide_rect.move_ip(delta_pos)
66
12ec95a2e8ea Bouncing.
Simon Cross <hodgestar@gmail.com>
parents: 59
diff changeset
82
97
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
83 def check_collides(self, other):
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
84 return True # default to relying purefly on collision_layer and collides_with
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
85
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
86 def collided(self, other):
98
449a9579ec7a Remove a debugging print.
Simon Cross <hodgestar@gmail.com>
parents: 97
diff changeset
87 pass
66
12ec95a2e8ea Bouncing.
Simon Cross <hodgestar@gmail.com>
parents: 59
diff changeset
88
128
36267deaccd8 Add friction. Remove old dirty sprite attributes.
Simon Cross <hodgestar@gmail.com>
parents: 122
diff changeset
89 def apply_friction(self):
36267deaccd8 Add friction. Remove old dirty sprite attributes.
Simon Cross <hodgestar@gmail.com>
parents: 122
diff changeset
90 v_x, v_y = self.velocity
36267deaccd8 Add friction. Remove old dirty sprite attributes.
Simon Cross <hodgestar@gmail.com>
parents: 122
diff changeset
91 self.velocity = self.friction_coeff[0] * v_x, self.friction_coeff[1] * v_y
36267deaccd8 Add friction. Remove old dirty sprite attributes.
Simon Cross <hodgestar@gmail.com>
parents: 122
diff changeset
92
97
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
93 def bounce(self, other, normal):
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
94 """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
95
97
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
96 other: sprite collided with
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
97 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
98 surface.
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
99 """
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
100 v_x, v_y = self.velocity
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
101 b_x = 1.0 + self.bounce_factor[0] * other.bounce_factor[0]
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
102 b_y = 1.0 + self.bounce_factor[1] * other.bounce_factor[1]
121
5f5e43391395 Ramming speed, Mr Sulu\!
Simon Cross <hodgestar@gmail.com>
parents: 117
diff changeset
103 dv_x = - normal[0] * b_x * v_x
5f5e43391395 Ramming speed, Mr Sulu\!
Simon Cross <hodgestar@gmail.com>
parents: 117
diff changeset
104 dv_y = - normal[1] * b_y * v_y
5f5e43391395 Ramming speed, Mr Sulu\!
Simon Cross <hodgestar@gmail.com>
parents: 117
diff changeset
105
146
5eb51736464c Use floor flag
Neil Muller <drnlmuller@gmail.com>
parents: 144
diff changeset
106 if normal == (0, 1) and other.floor and v_y > 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
107 # Colliding with the ground from above is special
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
108 self.on_ground = True
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
109 dv_y = -v_y
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
110
121
5f5e43391395 Ramming speed, Mr Sulu\!
Simon Cross <hodgestar@gmail.com>
parents: 117
diff changeset
111 if other.mobile:
5f5e43391395 Ramming speed, Mr Sulu\!
Simon Cross <hodgestar@gmail.com>
parents: 117
diff changeset
112 total_mass = self.mass + other.mass
5f5e43391395 Ramming speed, Mr Sulu\!
Simon Cross <hodgestar@gmail.com>
parents: 117
diff changeset
113 f_self = self.mass / total_mass
5f5e43391395 Ramming speed, Mr Sulu\!
Simon Cross <hodgestar@gmail.com>
parents: 117
diff changeset
114 f_other = other.mass / total_mass
5f5e43391395 Ramming speed, Mr Sulu\!
Simon Cross <hodgestar@gmail.com>
parents: 117
diff changeset
115
5f5e43391395 Ramming speed, Mr Sulu\!
Simon Cross <hodgestar@gmail.com>
parents: 117
diff changeset
116 self.deltav((dv_x * f_self, dv_y * f_self))
5f5e43391395 Ramming speed, Mr Sulu\!
Simon Cross <hodgestar@gmail.com>
parents: 117
diff changeset
117 other.deltav((- dv_x * f_other, - dv_y * f_other))
5f5e43391395 Ramming speed, Mr Sulu\!
Simon Cross <hodgestar@gmail.com>
parents: 117
diff changeset
118 else:
5f5e43391395 Ramming speed, Mr Sulu\!
Simon Cross <hodgestar@gmail.com>
parents: 117
diff changeset
119 self.deltav((dv_x, dv_y)) # oof
39
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
120
116
69a97094417a Hook up per-tick sprite animations.
Simon Cross <hodgestar@gmail.com>
parents: 112
diff changeset
121 def update(self):
69a97094417a Hook up per-tick sprite animations.
Simon Cross <hodgestar@gmail.com>
parents: 112
diff changeset
122 pass # only called in wants_update = True
69a97094417a Hook up per-tick sprite animations.
Simon Cross <hodgestar@gmail.com>
parents: 112
diff changeset
123
22
b815471d4b95 Move sprite base class into physics since they're tightly coupled.
Simon Cross <hodgestar@gmail.com>
parents: 18
diff changeset
124
b815471d4b95 Move sprite base class into physics since they're tightly coupled.
Simon Cross <hodgestar@gmail.com>
parents: 18
diff changeset
125 class World(object):
23
5c9f2eeeb629 Very start of world / physics engine.
Simon Cross <hodgestar@gmail.com>
parents: 22
diff changeset
126
103
aaef228b6358 Run kitsune, run! And by the running of the kitsune gravity is restored to normal.
Simon Cross <hodgestar@gmail.com>
parents: 98
diff changeset
127 GRAVITY = 0.0, 9.8 * 20.0 # pixels / s^2
39
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
128
23
5c9f2eeeb629 Very start of world / physics engine.
Simon Cross <hodgestar@gmail.com>
parents: 22
diff changeset
129 def __init__(self):
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
130 self._all = pygame.sprite.LayeredUpdates()
23
5c9f2eeeb629 Very start of world / physics engine.
Simon Cross <hodgestar@gmail.com>
parents: 22
diff changeset
131 self._mobiles = pygame.sprite.Group()
5c9f2eeeb629 Very start of world / physics engine.
Simon Cross <hodgestar@gmail.com>
parents: 22
diff changeset
132 self._gravitators = pygame.sprite.Group()
116
69a97094417a Hook up per-tick sprite animations.
Simon Cross <hodgestar@gmail.com>
parents: 112
diff changeset
133 self._updaters = pygame.sprite.Group()
97
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
134 self._collision_groups = { None: pygame.sprite.Group() }
39
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
135 self._last_time = None
23
5c9f2eeeb629 Very start of world / physics engine.
Simon Cross <hodgestar@gmail.com>
parents: 22
diff changeset
136
104
12ce1d131a72 Hack in resume game option
Neil Muller <drnlmuller@gmail.com>
parents: 103
diff changeset
137 def freeze(self):
12ce1d131a72 Hack in resume game option
Neil Muller <drnlmuller@gmail.com>
parents: 103
diff changeset
138 self._last_time = None
12ce1d131a72 Hack in resume game option
Neil Muller <drnlmuller@gmail.com>
parents: 103
diff changeset
139
12ce1d131a72 Hack in resume game option
Neil Muller <drnlmuller@gmail.com>
parents: 103
diff changeset
140 def thaw(self):
12ce1d131a72 Hack in resume game option
Neil Muller <drnlmuller@gmail.com>
parents: 103
diff changeset
141 self._last_time = time.time()
12ce1d131a72 Hack in resume game option
Neil Muller <drnlmuller@gmail.com>
parents: 103
diff changeset
142
23
5c9f2eeeb629 Very start of world / physics engine.
Simon Cross <hodgestar@gmail.com>
parents: 22
diff changeset
143 def add(self, sprite):
66
12ec95a2e8ea Bouncing.
Simon Cross <hodgestar@gmail.com>
parents: 59
diff changeset
144 sprite.init_pos()
23
5c9f2eeeb629 Very start of world / physics engine.
Simon Cross <hodgestar@gmail.com>
parents: 22
diff changeset
145 self._all.add(sprite)
5c9f2eeeb629 Very start of world / physics engine.
Simon Cross <hodgestar@gmail.com>
parents: 22
diff changeset
146 if sprite.mobile:
5c9f2eeeb629 Very start of world / physics engine.
Simon Cross <hodgestar@gmail.com>
parents: 22
diff changeset
147 self._mobiles.add(sprite)
5c9f2eeeb629 Very start of world / physics engine.
Simon Cross <hodgestar@gmail.com>
parents: 22
diff changeset
148 if sprite.gravitates:
5c9f2eeeb629 Very start of world / physics engine.
Simon Cross <hodgestar@gmail.com>
parents: 22
diff changeset
149 self._gravitators.add(sprite)
116
69a97094417a Hook up per-tick sprite animations.
Simon Cross <hodgestar@gmail.com>
parents: 112
diff changeset
150 if sprite.wants_updates:
69a97094417a Hook up per-tick sprite animations.
Simon Cross <hodgestar@gmail.com>
parents: 112
diff changeset
151 self._updaters.add(sprite)
97
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
152 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
153 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
154 self._add_collision_group(layer)
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
155 self._collision_groups[layer].add(sprite)
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
156
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
157 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
158 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
159 return
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
160 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
161
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
162 def _backout_collisions(self, sprite, others, dt):
122
51bcc909873d Saner, buggier collision rectangles
Neil Muller <drnlmuller@gmail.com>
parents: 121
diff changeset
163 frac, normal, idx = -1.0, None, None
97
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
164 v_x, v_y = sprite.velocity
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
165 abs_v_x, abs_v_y = abs(v_x), abs(v_y)
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
166
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
167 for i, other in enumerate(others):
122
51bcc909873d Saner, buggier collision rectangles
Neil Muller <drnlmuller@gmail.com>
parents: 121
diff changeset
168 clip = sprite.collide_rect.clip(other.collide_rect)
97
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
169 # TODO: avoid continual "if abs_v_? > EPSILON"
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
170 frac_x = clip.width / abs_v_x if abs_v_x > EPSILON else dt
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
171 frac_y = clip.height / abs_v_y if abs_v_y > EPSILON else dt
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
172 if frac_x > frac_y:
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
173 if frac_y > frac:
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
174 frac, normal, idx = frac_y, (0, 1), i
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
175 else:
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
176 if frac_x > frac:
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
177 frac, normal, idx = frac_x, (1, 0), i
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
178
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
179 sprite.deltap(max(-1.1 * frac, -dt))
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
180 sprite.bounce(others[idx], normal)
128
36267deaccd8 Add friction. Remove old dirty sprite attributes.
Simon Cross <hodgestar@gmail.com>
parents: 122
diff changeset
181
97
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
182 for other in others:
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
183 sprite.collided(other)
39
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
184
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
185 def update(self):
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
186 if self._last_time is None:
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
187 self._last_time = time.time()
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
188 return
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
189
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
190 # find dt
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
191 now = time.time()
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
192 self._last_time, dt = now, now - self._last_time
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
193
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
194 # gravity
103
aaef228b6358 Run kitsune, run! And by the running of the kitsune gravity is restored to normal.
Simon Cross <hodgestar@gmail.com>
parents: 98
diff changeset
195 dv = self.GRAVITY[0] * dt, self.GRAVITY[1] * dt
39
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
196 for sprite in self._gravitators:
144
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
197 if sprite.on_ground:
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
198 sprite.deltav((dv[0], 0.0))
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
199 else:
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
200 sprite.deltav(dv)
39
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
201
128
36267deaccd8 Add friction. Remove old dirty sprite attributes.
Simon Cross <hodgestar@gmail.com>
parents: 122
diff changeset
202 # friction
36267deaccd8 Add friction. Remove old dirty sprite attributes.
Simon Cross <hodgestar@gmail.com>
parents: 122
diff changeset
203 for sprite in self._mobiles:
36267deaccd8 Add friction. Remove old dirty sprite attributes.
Simon Cross <hodgestar@gmail.com>
parents: 122
diff changeset
204 sprite.apply_friction()
36267deaccd8 Add friction. Remove old dirty sprite attributes.
Simon Cross <hodgestar@gmail.com>
parents: 122
diff changeset
205
97
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
206 # position update and collision check (do last)
39
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
207 for sprite in self._mobiles:
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
208 sprite.deltap(dt)
122
51bcc909873d Saner, buggier collision rectangles
Neil Muller <drnlmuller@gmail.com>
parents: 121
diff changeset
209 sprite_collides = sprite.collide_rect.colliderect
97
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
210 collisions = []
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
211 for other in self._collision_groups[sprite.collision_layer]:
144
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
212 if sprite_collides(other.collide_rect) \
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
213 and sprite.check_collides(other):
97
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
214 collisions.append(other)
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
215 if collisions:
a1d95c6152a0 Shiny new collision detection. Read code for usage information.
Simon Cross <hodgestar@gmail.com>
parents: 85
diff changeset
216 self._backout_collisions(sprite, collisions, dt)
144
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
217 if sprite.on_ground:
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
218 # Check if we are still in contact with the ground
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
219 contact_rect = sprite.collide_rect.move((0, 1))
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
220 collides = contact_rect.colliderect
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
221 still_on_ground = False
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
222 for other in self._collision_groups[sprite.collision_layer]:
146
5eb51736464c Use floor flag
Neil Muller <drnlmuller@gmail.com>
parents: 144
diff changeset
223 if other.floor and collides(other.collide_rect):
144
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
224 still_on_ground = True
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
225 break
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
226 sprite.on_ground = still_on_ground
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
227 else:
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
228 # Are we currently in contact with the groun
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
229 contact_rect = pygame.Rect(
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
230 (sprite.collide_rect.left, sprite.collide_rect.bottom -1),
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
231 (sprite.collide_rect.width, 1))
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
232 collides = contact_rect.colliderect
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
233 for other in self._collision_groups[sprite.collision_layer]:
146
5eb51736464c Use floor flag
Neil Muller <drnlmuller@gmail.com>
parents: 144
diff changeset
234 if other.floor and collides(other.collide_rect):
144
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
235 sprite.on_ground = True
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
236 break
6b488e1351a5 Buggy ground implementation. Make the world less bouncy
Neil Muller <drnlmuller@gmail.com>
parents: 128
diff changeset
237
50
7d411ed02eac Initial stab at detecting collisions.
Simon Cross <hodgestar@gmail.com>
parents: 43
diff changeset
238
116
69a97094417a Hook up per-tick sprite animations.
Simon Cross <hodgestar@gmail.com>
parents: 112
diff changeset
239 # call update methods
69a97094417a Hook up per-tick sprite animations.
Simon Cross <hodgestar@gmail.com>
parents: 112
diff changeset
240 self._updaters.update()
69a97094417a Hook up per-tick sprite animations.
Simon Cross <hodgestar@gmail.com>
parents: 112
diff changeset
241
39
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
242 def draw(self, surface):
34038447be23 Very basic world physics.
Simon Cross <hodgestar@gmail.com>
parents: 23
diff changeset
243 self._all.draw(surface)
105
c455b7925212 Global options in skaapsteker.__init__
Stefano Rivera <stefano@rivera.za.net>
parents: 104
diff changeset
244 if options['debug_rects']:
53
01cfef3a5acf Add debugging rectangles.
Simon Cross <hodgestar@gmail.com>
parents: 51
diff changeset
245 for sprite in self._all:
01cfef3a5acf Add debugging rectangles.
Simon Cross <hodgestar@gmail.com>
parents: 51
diff changeset
246 sprite.draw_debug(surface)