Mercurial > touhou
comparison pytouhou/game/laser.py @ 274:f037bca24f2d
Partially implement lasers.
“Launch animations”/“energy circles” are missing, aswell as collision and grazing.
author | Thibaut Girka <thib@sitedethib.com> |
---|---|
date | Sun, 05 Feb 2012 23:41:55 +0100 |
parents | |
children | 615c0bb6064b |
comparison
equal
deleted
inserted
replaced
273:595b227886b1 | 274:f037bca24f2d |
---|---|
1 # -*- encoding: utf-8 -*- | |
2 ## | |
3 ## Copyright (C) 2012 Thibaut Girka <thib@sitedethib.com> | |
4 ## | |
5 ## This program is free software; you can redistribute it and/or modify | |
6 ## it under the terms of the GNU General Public License as published | |
7 ## by the Free Software Foundation; version 3 only. | |
8 ## | |
9 ## This program is distributed in the hope that it will be useful, | |
10 ## but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 ## GNU General Public License for more details. | |
13 ## | |
14 | |
15 from math import cos, sin, pi | |
16 | |
17 from pytouhou.vm.anmrunner import ANMRunner | |
18 from pytouhou.game.sprite import Sprite | |
19 | |
20 | |
21 STARTING, STARTED, STOPPING = range(3) | |
22 | |
23 | |
24 class Laser(object): | |
25 def __init__(self, pos, laser_type, sprite_idx_offset, | |
26 angle, speed, start_offset, end_offset, max_length, width, | |
27 start_duration, duration, stop_duration, | |
28 grazing_delay, grazing_extra_duration, | |
29 game): | |
30 self._game = game | |
31 #TODO: aux sprite | |
32 self._sprite = None | |
33 self._anmrunner = None | |
34 self._removed = False | |
35 self._laser_type = laser_type | |
36 self.state = STARTING | |
37 | |
38 #TODO: hitbox | |
39 | |
40 self.frame = 0 | |
41 self.start_duration = start_duration | |
42 self.duration = duration | |
43 self.stop_duration = stop_duration | |
44 self.grazing_delay = grazing_delay | |
45 self.grazing_extra_duration = grazing_extra_duration | |
46 | |
47 self.sprite_idx_offset = sprite_idx_offset | |
48 self.x, self.y = pos | |
49 self.angle = angle | |
50 self.speed = speed | |
51 self.start_offset = start_offset | |
52 self.end_offset = end_offset | |
53 self.max_length = max_length | |
54 self.width = width | |
55 | |
56 self.set_anim() | |
57 | |
58 | |
59 def set_anim(self, sprite_idx_offset=None): | |
60 if sprite_idx_offset is not None: | |
61 self.sprite_idx_offset = sprite_idx_offset | |
62 | |
63 lt = self._laser_type | |
64 self._sprite = Sprite() | |
65 self._sprite.angle = self.angle | |
66 self._anmrunner = ANMRunner(lt.anm_wrapper, lt.anim_index, | |
67 self._sprite, self.sprite_idx_offset) | |
68 self._anmrunner.run_frame() | |
69 | |
70 | |
71 def get_bullets_pos(self): | |
72 #TODO: check | |
73 offset = self.start_offset | |
74 length = min(self.end_offset - self.start_offset, self.max_length) | |
75 dx, dy = cos(self.angle), sin(self.angle) | |
76 while 0 <= offset - self.start_offset <= length: | |
77 yield (self.x + offset * dx, self.y + offset * dy) | |
78 offset += 48. | |
79 | |
80 | |
81 def cancel(self): | |
82 if self.state != STOPPING: | |
83 self.frame = 0 | |
84 self.state = STOPPING | |
85 | |
86 | |
87 def update(self): | |
88 if self._anmrunner is not None and not self._anmrunner.run_frame(): | |
89 self._anmrunner = None | |
90 | |
91 self.end_offset += self.speed | |
92 | |
93 length = min(self.end_offset - self.start_offset, self.max_length) # TODO | |
94 if self.state == STARTING: | |
95 if self.frame == self.start_duration: | |
96 self.frame = 0 | |
97 self.state = STARTED | |
98 else: | |
99 width = self.width * float(self.frame) / self.start_duration #TODO | |
100 if self.state == STARTED: | |
101 width = self.width #TODO | |
102 if self.frame == self.duration: | |
103 self.frame = 0 | |
104 self.state = STOPPING | |
105 if self.state == STOPPING: | |
106 if self.frame == self.stop_duration: | |
107 width = 0. | |
108 self._removed = True | |
109 else: | |
110 width = self.width * (1. - float(self.frame) / self.stop_duration) #TODO | |
111 | |
112 self._sprite.allow_dest_offset = True | |
113 self._sprite.dest_offset = (0., self.end_offset - length / 2., 0.) | |
114 self._sprite.width_override = width or 0.01 #TODO | |
115 self._sprite.height_override = length or 0.01 #TODO | |
116 | |
117 self._sprite.update_orientation(pi/2. - self.angle, True) | |
118 self._sprite._changed = True #TODO | |
119 | |
120 self.frame += 1 | |
121 |