Mercurial > touhou
comparison pytouhou/game/bullet.pyx @ 304:f3099ebf4f61
Update attribute names to reflect the actual interface.
author | Thibaut Girka <thib@sitedethib.com> |
---|---|
date | Tue, 13 Mar 2012 18:38:14 +0100 |
parents | 35644a67ba4c |
children | 0f88ae611d37 |
comparison
equal
deleted
inserted
replaced
303:647bde10353d | 304:f3099ebf4f61 |
---|---|
23 | 23 |
24 cdef class Bullet(object): | 24 cdef class Bullet(object): |
25 cdef public unsigned int _state, flags, frame, sprite_idx_offset | 25 cdef public unsigned int _state, flags, frame, sprite_idx_offset |
26 cdef public double dx, dy, angle, speed #TODO | 26 cdef public double dx, dy, angle, speed #TODO |
27 cdef public object player_bullet, target | 27 cdef public object player_bullet, target |
28 cdef public object _game, _sprite, _anmrunner, _removed, _bullet_type, _was_visible | 28 cdef public object _game, _bullet_type |
29 cdef public object sprite, anmrunner, removed, was_visible | |
29 cdef public object attributes, damage, hitbox_half_size, speed_interpolator, grazed | 30 cdef public object attributes, damage, hitbox_half_size, speed_interpolator, grazed |
30 cdef public object x, y #TODO | 31 cdef public object x, y #TODO |
31 | 32 |
32 def __init__(self, pos, bullet_type, sprite_idx_offset, | 33 def __init__(self, pos, bullet_type, sprite_idx_offset, |
33 angle, speed, attributes, flags, target, game, | 34 angle, speed, attributes, flags, target, game, |
34 player_bullet=False, damage=0, hitbox=None): | 35 player_bullet=False, damage=0, hitbox=None): |
35 self._game = game | 36 self._game = game |
36 self._sprite = None | |
37 self._anmrunner = None | |
38 self._removed = False | |
39 self._bullet_type = bullet_type | 37 self._bullet_type = bullet_type |
40 self._was_visible = True | |
41 self._state = LAUNCHING | 38 self._state = LAUNCHING |
39 self.sprite = None | |
40 self.anmrunner = None | |
41 self.removed = False | |
42 self.was_visible = True | |
42 | 43 |
43 if hitbox: | 44 if hitbox: |
44 self.hitbox_half_size = (hitbox[0] / 2., hitbox[1] / 2.) | 45 self.hitbox_half_size = (hitbox[0] / 2., hitbox[1] / 2.) |
45 else: | 46 else: |
46 self.hitbox_half_size = (bullet_type.hitbox_size / 2., bullet_type.hitbox_size / 2.) | 47 self.hitbox_half_size = (bullet_type.hitbox_size / 2., bullet_type.hitbox_size / 2.) |
74 launch_mult = bullet_type.launch_anim_penalties[1] | 75 launch_mult = bullet_type.launch_anim_penalties[1] |
75 else: | 76 else: |
76 index = bullet_type.launch_anim8_index | 77 index = bullet_type.launch_anim8_index |
77 launch_mult = bullet_type.launch_anim_penalties[2] | 78 launch_mult = bullet_type.launch_anim_penalties[2] |
78 self.dx, self.dy = self.dx * launch_mult, self.dy * launch_mult | 79 self.dx, self.dy = self.dx * launch_mult, self.dy * launch_mult |
79 self._sprite = Sprite() | 80 self.sprite = Sprite() |
80 self._anmrunner = ANMRunner(bullet_type.anm_wrapper, | 81 self.anmrunner = ANMRunner(bullet_type.anm_wrapper, |
81 index, self._sprite, | 82 index, self.sprite, |
82 bullet_type.launch_anim_offsets[sprite_idx_offset]) | 83 bullet_type.launch_anim_offsets[sprite_idx_offset]) |
83 self._anmrunner.run_frame() | 84 self.anmrunner.run_frame() |
84 else: | 85 else: |
85 self.launch() | 86 self.launch() |
86 | 87 |
87 if self.player_bullet: | 88 if self.player_bullet: |
88 self._sprite.angle = angle - pi | 89 self.sprite.angle = angle - pi |
89 else: | 90 else: |
90 self._sprite.angle = angle | 91 self.sprite.angle = angle |
91 | 92 |
92 | 93 |
93 cpdef is_visible(Bullet self, screen_width, screen_height): | 94 cpdef is_visible(Bullet self, screen_width, screen_height): |
94 tx, ty, tw, th = self._sprite.texcoords | 95 tx, ty, tw, th = self.sprite.texcoords |
95 x, y = self.x, self.y | 96 x, y = self.x, self.y |
96 | 97 |
97 max_x = tw / 2. | 98 max_x = tw / 2. |
98 max_y = th / 2. | 99 max_y = th / 2. |
99 | 100 |
108 def set_anim(Bullet self, sprite_idx_offset=None): | 109 def set_anim(Bullet self, sprite_idx_offset=None): |
109 if sprite_idx_offset is not None: | 110 if sprite_idx_offset is not None: |
110 self.sprite_idx_offset = sprite_idx_offset | 111 self.sprite_idx_offset = sprite_idx_offset |
111 | 112 |
112 bt = self._bullet_type | 113 bt = self._bullet_type |
113 self._sprite = Sprite() | 114 self.sprite = Sprite() |
114 if self.player_bullet: | 115 if self.player_bullet: |
115 self._sprite.angle = self.angle - pi | 116 self.sprite.angle = self.angle - pi |
116 else: | 117 else: |
117 self._sprite.angle = self.angle | 118 self.sprite.angle = self.angle |
118 self._anmrunner = ANMRunner(bt.anm_wrapper, bt.anim_index, | 119 self.anmrunner = ANMRunner(bt.anm_wrapper, bt.anim_index, |
119 self._sprite, self.sprite_idx_offset) | 120 self.sprite, self.sprite_idx_offset) |
120 self._anmrunner.run_frame() | 121 self.anmrunner.run_frame() |
121 | 122 |
122 | 123 |
123 def launch(Bullet self): | 124 def launch(Bullet self): |
124 self._state = LAUNCHED | 125 self._state = LAUNCHED |
125 self.frame = 0 | 126 self.frame = 0 |
135 | 136 |
136 | 137 |
137 def cancel(Bullet self): | 138 def cancel(Bullet self): |
138 # Cancel animation | 139 # Cancel animation |
139 bt = self._bullet_type | 140 bt = self._bullet_type |
140 self._sprite = Sprite() | 141 self.sprite = Sprite() |
141 if self.player_bullet: | 142 if self.player_bullet: |
142 self._sprite.angle = self.angle - pi | 143 self.sprite.angle = self.angle - pi |
143 else: | 144 else: |
144 self._sprite.angle = self.angle | 145 self.sprite.angle = self.angle |
145 self._anmrunner = ANMRunner(bt.anm_wrapper, bt.cancel_anim_index, | 146 self.anmrunner = ANMRunner(bt.anm_wrapper, bt.cancel_anim_index, |
146 self._sprite, bt.launch_anim_offsets[self.sprite_idx_offset]) | 147 self.sprite, bt.launch_anim_offsets[self.sprite_idx_offset]) |
147 self._anmrunner.run_frame() | 148 self.anmrunner.run_frame() |
148 self.dx, self.dy = self.dx / 2., self.dy / 2. | 149 self.dx, self.dy = self.dx / 2., self.dy / 2. |
149 | 150 |
150 # Change update method | 151 # Change update method |
151 self._state = CANCELLED | 152 self._state = CANCELLED |
152 | 153 |
157 self._game.bullets.remove(self) | 158 self._game.bullets.remove(self) |
158 self._game.cancelled_bullets.append(self) | 159 self._game.cancelled_bullets.append(self) |
159 | 160 |
160 | 161 |
161 def update(Bullet self): | 162 def update(Bullet self): |
162 if self._anmrunner is not None and not self._anmrunner.run_frame(): | 163 if self.anmrunner is not None and not self.anmrunner.run_frame(): |
163 if self._state == LAUNCHING: | 164 if self._state == LAUNCHING: |
164 #TODO: check if it doesn't skip a frame | 165 #TODO: check if it doesn't skip a frame |
165 self.launch() | 166 self.launch() |
166 elif self._state == CANCELLED: | 167 elif self._state == CANCELLED: |
167 self._removed = True | 168 self.removed = True |
168 else: | 169 else: |
169 self._anmrunner = None | 170 self.anmrunner = None |
170 | 171 |
171 if self._state == LAUNCHING: | 172 if self._state == LAUNCHING: |
172 pass | 173 pass |
173 elif self._state == CANCELLED: | 174 elif self._state == CANCELLED: |
174 pass | 175 pass |
182 length, angle = self.attributes[4:6] | 183 length, angle = self.attributes[4:6] |
183 angle = self.angle if angle < -900.0 else angle #TODO: is that right? | 184 angle = self.angle if angle < -900.0 else angle #TODO: is that right? |
184 self.dx += cos(angle) * length | 185 self.dx += cos(angle) * length |
185 self.dy += sin(angle) * length | 186 self.dy += sin(angle) * length |
186 self.speed = (self.dx ** 2 + self.dy ** 2) ** 0.5 | 187 self.speed = (self.dx ** 2 + self.dy ** 2) ** 0.5 |
187 self.angle = self._sprite.angle = atan2(self.dy, self.dx) | 188 self.angle = self.sprite.angle = atan2(self.dy, self.dx) |
188 if self._sprite.automatic_orientation: | 189 if self.sprite.automatic_orientation: |
189 self._sprite._changed = True | 190 self.sprite.changed = True |
190 if self.frame == self.attributes[0]: #TODO: include last frame, or not? | 191 if self.frame == self.attributes[0]: #TODO: include last frame, or not? |
191 self.flags &= ~16 | 192 self.flags &= ~16 |
192 elif self.flags & 32: | 193 elif self.flags & 32: |
193 # Each frame, accelerate and rotate | 194 # Each frame, accelerate and rotate |
194 #TODO: check | 195 #TODO: check |
195 acceleration, angular_speed = self.attributes[4:6] | 196 acceleration, angular_speed = self.attributes[4:6] |
196 self.speed += acceleration | 197 self.speed += acceleration |
197 self.angle += angular_speed | 198 self.angle += angular_speed |
198 self.dx = cos(self.angle) * self.speed | 199 self.dx = cos(self.angle) * self.speed |
199 self.dy = sin(self.angle) * self.speed | 200 self.dy = sin(self.angle) * self.speed |
200 self._sprite.angle = self.angle | 201 self.sprite.angle = self.angle |
201 if self._sprite.automatic_orientation: | 202 if self.sprite.automatic_orientation: |
202 self._sprite._changed = True | 203 self.sprite.changed = True |
203 if self.frame == self.attributes[0]: | 204 if self.frame == self.attributes[0]: |
204 self.flags &= ~32 | 205 self.flags &= ~32 |
205 elif self.flags & 448: | 206 elif self.flags & 448: |
206 #TODO: check | 207 #TODO: check |
207 frame, count = self.attributes[0:2] | 208 frame, count = self.attributes[0:2] |
220 elif self.flags & 256: | 221 elif self.flags & 256: |
221 self.angle = angle | 222 self.angle = angle |
222 | 223 |
223 self.dx = cos(self.angle) * self.speed | 224 self.dx = cos(self.angle) * self.speed |
224 self.dy = sin(self.angle) * self.speed | 225 self.dy = sin(self.angle) * self.speed |
225 self._sprite.angle = self.angle | 226 self.sprite.angle = self.angle |
226 if self._sprite.automatic_orientation: | 227 if self.sprite.automatic_orientation: |
227 self._sprite._changed = True | 228 self.sprite.changed = True |
228 | 229 |
229 if count >= 0: | 230 if count >= 0: |
230 self.speed_interpolator = Interpolator((self.speed,), self.frame, | 231 self.speed_interpolator = Interpolator((self.speed,), self.frame, |
231 (0.,), self.frame + frame - 1) | 232 (0.,), self.frame + frame - 1) |
232 else: | 233 else: |
247 | 248 |
248 self.frame += 1 | 249 self.frame += 1 |
249 | 250 |
250 # Filter out-of-screen bullets and handle special flags | 251 # Filter out-of-screen bullets and handle special flags |
251 if self.flags & 448: | 252 if self.flags & 448: |
252 self._was_visible = False | 253 self.was_visible = False |
253 elif self.is_visible(self._game.width, self._game.height): | 254 elif self.is_visible(self._game.width, self._game.height): |
254 self._was_visible = True | 255 self.was_visible = True |
255 elif self._was_visible: | 256 elif self.was_visible: |
256 self._removed = True | 257 self.removed = True |
257 if self.flags & (1024 | 2048) and self.attributes[0] > 0: | 258 if self.flags & (1024 | 2048) and self.attributes[0] > 0: |
258 # Bounce! | 259 # Bounce! |
259 if self.x < 0 or self.x > self._game.width: | 260 if self.x < 0 or self.x > self._game.width: |
260 self.angle = pi - self.angle | 261 self.angle = pi - self.angle |
261 self._removed = False | 262 self.removed = False |
262 if self.y < 0 or ((self.flags & 1024) and self.y > self._game.height): | 263 if self.y < 0 or ((self.flags & 1024) and self.y > self._game.height): |
263 self.angle = -self.angle | 264 self.angle = -self.angle |
264 self._removed = False | 265 self.removed = False |
265 self._sprite.angle = self.angle | 266 self.sprite.angle = self.angle |
266 if self._sprite.automatic_orientation: | 267 if self.sprite.automatic_orientation: |
267 self._sprite._changed = True | 268 self.sprite.changed = True |
268 self.dx = cos(self.angle) * self.speed | 269 self.dx = cos(self.angle) * self.speed |
269 self.dy = sin(self.angle) * self.speed | 270 self.dy = sin(self.angle) * self.speed |
270 self.attributes[0] -= 1 | 271 self.attributes[0] -= 1 |
271 | 272 |