comparison pytouhou/interfaces/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
children e15672733c93
comparison
equal deleted inserted replaced
547:e35bef07290d 548:1e9ea6519f3c
1 # -*- encoding: utf-8 -*-
2 ##
3 ## Copyright (C) 2014 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
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 pytouhou.game.effect import Effect
16 from pytouhou.game.text import Text, Counter, Gauge, NativeText
17
18
19 class EoSDInterface(object):
20 def __init__(self, resource_loader, player_state):
21 self.game = None
22 self.player_state = player_state
23 front = resource_loader.get_single_anm('front.anm')
24 self.ascii_anm = resource_loader.get_single_anm('ascii.anm')
25
26 self.width = 640
27 self.height = 480
28 self.game_pos = (32, 16)
29
30 self.highscore = 1000000 #TODO: read score.dat
31 self.items = ([Effect((0, 32 * i), 6, front) for i in range(15)] +
32 [Effect((416 + 32 * i, 32 * j), 6, front) for i in range(7) for j in range(15)] +
33 [Effect((32 + 32 * i, 0), 7, front) for i in range(12)] +
34 [Effect((32 + 32 * i, 464), 8, front) for i in range(12)] +
35 [Effect((0, 0), i, front) for i in reversed(range(6))] +
36 [Effect((0, 0), i, front) for i in range(9, 16)])
37 for item in self.items:
38 item.sprite.allow_dest_offset = True #XXX
39
40 self.level_start = []
41
42 self.labels = {
43 'highscore': Text((500, 58), self.ascii_anm, front, text='0'),
44 'score': Text((500, 82), self.ascii_anm, front, text='0'),
45 'player': Counter((500, 122), front, front, script=16, value=0),
46 'bombs': Counter((500, 146), front, front, script=17, value=0),
47 'power': Text((500, 186), self.ascii_anm, front, text='0'),
48 'graze': Text((500, 206), self.ascii_anm, front, text='0'),
49 'points': Text((500, 226), self.ascii_anm, front, text='0'),
50 'framerate': Text((512, 464), self.ascii_anm, front),
51 'debug?': Text((0, 464), self.ascii_anm, front),
52
53 # Only when there is a boss.
54 'boss_lives': Text((80, 16), self.ascii_anm),
55 'timeout': Text((384, 16), self.ascii_anm),
56 }
57 self.labels['boss_lives'].set_color('yellow')
58
59 self.boss_items = [
60 Effect((0, 0), 19, front), # Enemy
61 Gauge((100, 24), front), # Gauge
62 Gauge((100, 24), front), # Spellcard gauge
63 ]
64 for item in self.boss_items:
65 item.sprite.allow_dest_offset = True #XXX
66
67
68 def start_stage(self, game, stage):
69 self.game = game
70 if stage < 6:
71 text = 'STAGE %d' % stage
72 elif stage == 6:
73 text = 'FINAL STAGE'
74 elif stage == 7:
75 text = 'EXTRA STAGE'
76
77 self.stage_name = NativeText((192, 200), unicode(game.std.name), shadow=True, align='center')
78 self.stage_name.set_timeout(240, effect='fadeout', duration=60, start=120)
79
80 self.set_song_name(game.std.bgms[0][0])
81
82 self.level_start = [Text((16+384/2, 200), self.ascii_anm, text=text, align='center')] #TODO: find the exact location.
83 self.level_start[0].set_timeout(240, effect='fadeout', duration=60, start=120)
84 self.level_start[0].set_color('yellow')
85
86
87 def set_song_name(self, name):
88 #TODO: use the correct animation.
89 self.song_name = NativeText((384, 432), u'♪ ' + name, shadow=True, align='right')
90 self.song_name.set_timeout(240, effect='fadeout', duration=60, start=120)
91
92
93 def set_boss_life(self):
94 if not self.game.boss:
95 return
96 self.boss_items[1].maximum = self.game.boss.life or 1
97 self.boss_items[2].maximum = self.game.boss.life or 1
98
99
100 def set_spell_life(self):
101 self.boss_items[2].set_value(self.game.boss.low_life_trigger if self.game.boss else 0)
102
103
104 def update(self):
105 for elem in self.items:
106 elem.update()
107
108 for elem in self.level_start:
109 elem.update()
110 if elem.removed: #XXX
111 self.level_start = []
112
113 player_state = self.player_state
114
115 self.highscore = max(self.highscore, player_state.effective_score)
116 self.labels['highscore'].set_text('%09d' % self.highscore)
117 self.labels['score'].set_text('%09d' % player_state.effective_score)
118 self.labels['power'].set_text('%d' % player_state.power)
119 self.labels['graze'].set_text('%d' % player_state.graze)
120 self.labels['points'].set_text('%d' % player_state.points)
121 self.labels['player'].set_value(player_state.lives)
122 self.labels['bombs'].set_value(player_state.bombs)
123
124 if self.game.boss:
125 boss = self.game.boss
126
127 life_gauge = self.boss_items[1]
128 life_gauge.set_value(boss.life)
129
130 spell_gauge = self.boss_items[2]
131 spell_gauge.sprite.color = (255, 192, 192)
132 if boss.life < spell_gauge.value:
133 spell_gauge.set_value(boss.life)
134
135 for item in self.boss_items:
136 item.update()
137
138 self.labels['boss_lives'].set_text('%d' % boss.remaining_lives)
139 self.labels['boss_lives'].changed = True
140
141 timeout = min((boss.timeout - boss.frame) // 60, 99)
142 timeout_label = self.labels['timeout']
143 if timeout >= 20:
144 timeout_label.set_color('blue')
145 elif timeout >= 10:
146 timeout_label.set_color('darkblue')
147 else:
148 if timeout >= 5:
149 timeout_label.set_color('purple')
150 else:
151 timeout_label.set_color('red')
152 if (boss.timeout - boss.frame) % 60 == 0 and boss.timeout != 0:
153 self.game.sfx_player.set_volume('timeout.wav', 1.)
154 self.game.sfx_player.play('timeout.wav')
155 timeout_label.set_text('%02d' % (timeout if timeout >= 0 else 0))
156 timeout_label.changed = True