comparison pytouhou/games/eosd.py @ 548:1e9ea6519f3c

Make EoSDInterface separate from EoSD game.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Wed, 21 May 2014 20:56:53 +0200
parents e35bef07290d
children
comparison
equal deleted inserted replaced
547:e35bef07290d 548:1e9ea6519f3c
18 from pytouhou.game.bullettype import BulletType 18 from pytouhou.game.bullettype import BulletType
19 from pytouhou.game.lasertype import LaserType 19 from pytouhou.game.lasertype import LaserType
20 from pytouhou.game.itemtype import ItemType 20 from pytouhou.game.itemtype import ItemType
21 from pytouhou.game.player import Player 21 from pytouhou.game.player import Player
22 from pytouhou.game.orb import Orb 22 from pytouhou.game.orb import Orb
23 from pytouhou.game.effect import Effect
24 from pytouhou.game.text import Text, Counter, Gauge, NativeText
25 from pytouhou.game.background import Background 23 from pytouhou.game.background import Background
26 24
27 from pytouhou.vm import ECLMainRunner 25 from pytouhou.vm import ECLMainRunner
28 26
29 27
94 92
95 self.players[i] = EoSDPlayer(i, self.player_anms[character][0], 93 self.players[i] = EoSDPlayer(i, self.player_anms[character][0],
96 eosd_characters[player_character], 94 eosd_characters[player_character],
97 character, default_power, continues) 95 character, default_power, continues)
98 96
99 self.interface = EoSDInterface(resource_loader, self.players[0]) #XXX
100
101 97
102 98
103 class EoSDGame(Game): 99 class EoSDGame(Game):
104 def __init__(self, resource_loader, stage, rank, difficulty, 100 def __init__(self, resource_loader, stage, rank, difficulty,
105 common, prng, hints=None, friendly_fire=True, 101 common, prng, hints=None, friendly_fire=True,
141 common.bullet_types, common.laser_types, 137 common.bullet_types, common.laser_types,
142 common.item_types, nb_bullets_max, common.width, 138 common.item_types, nb_bullets_max, common.width,
143 common.height, prng, common.interface, hints, 139 common.height, prng, common.interface, hints,
144 friendly_fire) 140 friendly_fire)
145 141
146 self.texts['stage_name'] = common.interface.stage_name 142 try:
147 self.texts['song_name'] = common.interface.song_name 143 self.texts['stage_name'] = common.interface.stage_name
148 144 except AttributeError:
149 145 pass
150 146
151 class EoSDInterface(object): 147 try:
152 def __init__(self, resource_loader, player_state): 148 self.texts['song_name'] = common.interface.song_name
153 self.game = None 149 except AttributeError:
154 self.player_state = player_state 150 pass
155 front = resource_loader.get_single_anm('front.anm')
156 self.ascii_anm = resource_loader.get_single_anm('ascii.anm')
157
158 self.width = 640
159 self.height = 480
160 self.game_pos = (32, 16)
161
162 self.highscore = 1000000 #TODO: read score.dat
163 self.items = ([Effect((0, 32 * i), 6, front) for i in range(15)] +
164 [Effect((416 + 32 * i, 32 * j), 6, front) for i in range(7) for j in range(15)] +
165 [Effect((32 + 32 * i, 0), 7, front) for i in range(12)] +
166 [Effect((32 + 32 * i, 464), 8, front) for i in range(12)] +
167 [Effect((0, 0), i, front) for i in reversed(range(6))] +
168 [Effect((0, 0), i, front) for i in range(9, 16)])
169 for item in self.items:
170 item.sprite.allow_dest_offset = True #XXX
171
172 self.level_start = []
173
174 self.labels = {
175 'highscore': Text((500, 58), self.ascii_anm, front, text='0'),
176 'score': Text((500, 82), self.ascii_anm, front, text='0'),
177 'player': Counter((500, 122), front, front, script=16, value=0),
178 'bombs': Counter((500, 146), front, front, script=17, value=0),
179 'power': Text((500, 186), self.ascii_anm, front, text='0'),
180 'graze': Text((500, 206), self.ascii_anm, front, text='0'),
181 'points': Text((500, 226), self.ascii_anm, front, text='0'),
182 'framerate': Text((512, 464), self.ascii_anm, front),
183 'debug?': Text((0, 464), self.ascii_anm, front),
184
185 # Only when there is a boss.
186 'boss_lives': Text((80, 16), self.ascii_anm),
187 'timeout': Text((384, 16), self.ascii_anm),
188 }
189 self.labels['boss_lives'].set_color('yellow')
190
191 self.boss_items = [
192 Effect((0, 0), 19, front), # Enemy
193 Gauge((100, 24), front), # Gauge
194 Gauge((100, 24), front), # Spellcard gauge
195 ]
196 for item in self.boss_items:
197 item.sprite.allow_dest_offset = True #XXX
198
199
200 def start_stage(self, game, stage):
201 self.game = game
202 if stage < 6:
203 text = 'STAGE %d' % stage
204 elif stage == 6:
205 text = 'FINAL STAGE'
206 elif stage == 7:
207 text = 'EXTRA STAGE'
208
209 self.stage_name = NativeText((192, 200), unicode(game.std.name), shadow=True, align='center')
210 self.stage_name.set_timeout(240, effect='fadeout', duration=60, start=120)
211
212 self.set_song_name(game.std.bgms[0][0])
213
214 self.level_start = [Text((16+384/2, 200), self.ascii_anm, text=text, align='center')] #TODO: find the exact location.
215 self.level_start[0].set_timeout(240, effect='fadeout', duration=60, start=120)
216 self.level_start[0].set_color('yellow')
217
218
219 def set_song_name(self, name):
220 #TODO: use the correct animation.
221 self.song_name = NativeText((384, 432), u'♪ ' + name, shadow=True, align='right')
222 self.song_name.set_timeout(240, effect='fadeout', duration=60, start=120)
223
224
225 def set_boss_life(self):
226 if not self.game.boss:
227 return
228 self.boss_items[1].maximum = self.game.boss.life or 1
229 self.boss_items[2].maximum = self.game.boss.life or 1
230
231
232 def set_spell_life(self):
233 self.boss_items[2].set_value(self.game.boss.low_life_trigger if self.game.boss else 0)
234
235
236 def update(self):
237 for elem in self.items:
238 elem.update()
239
240 for elem in self.level_start:
241 elem.update()
242 if elem.removed: #XXX
243 self.level_start = []
244
245 player_state = self.player_state
246
247 self.highscore = max(self.highscore, player_state.effective_score)
248 self.labels['highscore'].set_text('%09d' % self.highscore)
249 self.labels['score'].set_text('%09d' % player_state.effective_score)
250 self.labels['power'].set_text('%d' % player_state.power)
251 self.labels['graze'].set_text('%d' % player_state.graze)
252 self.labels['points'].set_text('%d' % player_state.points)
253 self.labels['player'].set_value(player_state.lives)
254 self.labels['bombs'].set_value(player_state.bombs)
255
256 if self.game.boss:
257 boss = self.game.boss
258
259 life_gauge = self.boss_items[1]
260 life_gauge.set_value(boss.life)
261
262 spell_gauge = self.boss_items[2]
263 spell_gauge.sprite.color = (255, 192, 192)
264 if boss.life < spell_gauge.value:
265 spell_gauge.set_value(boss.life)
266
267 for item in self.boss_items:
268 item.update()
269
270 self.labels['boss_lives'].set_text('%d' % boss.remaining_lives)
271 self.labels['boss_lives'].changed = True
272
273 timeout = min((boss.timeout - boss.frame) // 60, 99)
274 timeout_label = self.labels['timeout']
275 if timeout >= 20:
276 timeout_label.set_color('blue')
277 elif timeout >= 10:
278 timeout_label.set_color('darkblue')
279 else:
280 if timeout >= 5:
281 timeout_label.set_color('purple')
282 else:
283 timeout_label.set_color('red')
284 if (boss.timeout - boss.frame) % 60 == 0 and boss.timeout != 0:
285 self.game.sfx_player.set_volume('timeout.wav', 1.)
286 self.game.sfx_player.play('timeout.wav')
287 timeout_label.set_text('%02d' % (timeout if timeout >= 0 else 0))
288 timeout_label.changed = True
289 151
290 152
291 153
292 class EoSDPlayer(Player): 154 class EoSDPlayer(Player):
293 def __init__(self, number, anm, shts, character, power, continues): 155 def __init__(self, number, anm, shts, character, power, continues):