Mercurial > touhou
comparison pytouhou/game/item.pyx @ 446:3a33ed7f3b85
Make pytouhou.game.item an extension type.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Sat, 17 Aug 2013 06:01:45 +0200 |
parents | pytouhou/game/item.py@b0abb05811f7 |
children | 78e1c3864e73 |
comparison
equal
deleted
inserted
replaced
445:b0abb05811f7 | 446:3a33ed7f3b85 |
---|---|
1 # -*- encoding: utf-8 -*- | |
2 ## | |
3 ## Copyright (C) 2011 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 libc.math cimport cos, sin, atan2, M_PI as pi | |
16 | |
17 | |
18 cdef class Indicator(Element): | |
19 def __init__(self, Item item): | |
20 Element.__init__(self) | |
21 | |
22 self._item = item | |
23 self.sprite = item._item_type.indicator_sprite.copy() | |
24 | |
25 self.x = self._item.x | |
26 self.y = self.sprite.texcoords[2] / 2. | |
27 | |
28 | |
29 cpdef update(self): | |
30 #TODO: alpha | |
31 self.x = self._item.x | |
32 | |
33 | |
34 | |
35 cdef class Item(Element): | |
36 def __init__(self, start_pos, long _type, item_type, game, double angle=pi/2, Player player=None, end_pos=None): | |
37 Element.__init__(self, start_pos) | |
38 | |
39 self._game = game | |
40 self._type = _type | |
41 self._item_type = item_type | |
42 self.sprite = item_type.sprite | |
43 | |
44 self.frame = 0 | |
45 self.angle = angle | |
46 self.indicator = None | |
47 | |
48 if player is not None: | |
49 self.autocollect(player) | |
50 else: | |
51 self.player = None | |
52 | |
53 #TODO: find the formulae in the binary. | |
54 self.speed_interpolator = None | |
55 if end_pos: | |
56 self.pos_interpolator = Interpolator(start_pos, 0, | |
57 end_pos, 60) | |
58 else: | |
59 self.speed_interpolator = Interpolator((-2.,), 0, | |
60 (0.,), 60) | |
61 | |
62 self.sprite.angle = angle | |
63 | |
64 | |
65 property objects: | |
66 def __get__(self): | |
67 if self.indicator is not None: | |
68 return [self.indicator] | |
69 return [self] | |
70 | |
71 | |
72 cpdef autocollect(self, Player player): | |
73 if self.player is None: | |
74 self.player = player | |
75 self.speed = player.sht.autocollection_speed | |
76 | |
77 | |
78 cpdef on_collect(self, Player player): | |
79 cdef long level, poc | |
80 | |
81 player_state = player.state | |
82 old_power = player_state.power | |
83 score = 0 | |
84 label = None | |
85 color = 'white' | |
86 player.play_sound('item00') | |
87 | |
88 if self._type == 0 or self._type == 2: # power or big power | |
89 if old_power < 128: | |
90 player_state.power_bonus = 0 | |
91 score = 10 | |
92 player_state.power += (1 if self._type == 0 else 8) | |
93 if player_state.power > 128: | |
94 player_state.power = 128 | |
95 for level in (8, 16, 32, 48, 64, 96): | |
96 if old_power < level and player_state.power >= level: | |
97 label = self._game.new_label((self.x, self.y), ':') # Actually a “PowerUp” character. | |
98 color = 'blue' | |
99 label.set_color(color) | |
100 labeled = True | |
101 else: | |
102 bonus = player_state.power_bonus + (1 if self._type == 0 else 8) | |
103 if bonus > 30: | |
104 bonus = 30 | |
105 if bonus < 9: | |
106 score = (bonus + 1) * 10 | |
107 elif bonus < 18: | |
108 score = (bonus - 8) * 100 | |
109 elif bonus < 30: | |
110 score = (bonus - 17) * 1000 | |
111 elif bonus == 30: | |
112 score = 51200 | |
113 color = 'yellow' | |
114 player_state.power_bonus = bonus | |
115 self._game.modify_difficulty(+1) | |
116 | |
117 elif self._type == 1: # point | |
118 player_state.points += 1 | |
119 poc = player.sht.point_of_collection | |
120 if player_state.y < poc: | |
121 score = 100000 | |
122 self._game.modify_difficulty(+30) | |
123 color = 'yellow' | |
124 else: | |
125 #score = #TODO: find the formula. | |
126 self._game.modify_difficulty(+3) | |
127 | |
128 elif self._type == 3: # bomb | |
129 if player_state.bombs < 8: | |
130 player_state.bombs += 1 | |
131 self._game.modify_difficulty(+5) | |
132 | |
133 elif self._type == 4: # full power | |
134 score = 1000 | |
135 player_state.power = 128 | |
136 | |
137 elif self._type == 5: # 1up | |
138 if player_state.lives < 8: | |
139 player_state.lives += 1 | |
140 self._game.modify_difficulty(+200) | |
141 player.play_sound('extend') | |
142 | |
143 elif self._type == 6: # star | |
144 score = 500 | |
145 | |
146 if old_power < 128 and player_state.power == 128: | |
147 #TODO: display “full power”. | |
148 self._game.change_bullets_into_star_items() | |
149 | |
150 if score > 0: | |
151 player_state.score += score | |
152 if label is None: | |
153 label = self._game.new_label((self.x, self.y), str(score)) | |
154 if color != 'white': | |
155 label.set_color(color) | |
156 | |
157 self.removed = True | |
158 | |
159 | |
160 cpdef update(self): | |
161 cdef bint offscreen | |
162 | |
163 if self.frame == 60: | |
164 self.speed_interpolator = Interpolator((0.,), 60, | |
165 (3.,), 180) | |
166 | |
167 if self.player is not None: | |
168 player_state = self.player.state | |
169 self.angle = atan2(player_state.y - self.y, player_state.x - self.x) | |
170 self.x += cos(self.angle) * self.speed | |
171 self.y += sin(self.angle) * self.speed | |
172 elif self.speed_interpolator is None: | |
173 self.pos_interpolator.update(self.frame) | |
174 self.x, self.y = self.pos_interpolator.values | |
175 else: | |
176 self.speed_interpolator.update(self.frame) | |
177 self.speed, = self.speed_interpolator.values | |
178 dx, dy = cos(self.angle) * self.speed, sin(self.angle) * self.speed | |
179 self.x += dx | |
180 self.y += dy | |
181 | |
182 offscreen = self.y < -(<double>self.sprite.texcoords[2] / 2.) | |
183 if offscreen: | |
184 if self.indicator is None: | |
185 self.indicator = Indicator(self) | |
186 self.indicator.update() | |
187 else: | |
188 self.indicator = None | |
189 | |
190 self.frame += 1 |