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