1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 from Scene import SceneServer, SceneClient
24 from Menu import Menu
25 import Player
26 import Dialogs
27 import Song
28 import Data
29 import Theme
30 from Audio import Sound
31 from Language import _
32
33 import pygame
34 import math
35 import random
36 from OpenGL.GL import *
37
40
43
46 self.libraryName = libraryName
47 self.songName = songName
48 self.stars = 0
49 self.accuracy = 0
50 self.counter = 0
51 self.showHighscores = False
52 self.highscoreIndex = None
53 self.taunt = None
54 self.uploadingScores = False
55 self.nextScene = None
56
57 items = [
58 (_("Replay"), self.replay),
59 (_("Change Song"), self.changeSong),
60 (_("Quit to Main Menu"), self.quit),
61 ]
62 self.menu = Menu(self.engine, items, onCancel = self.quit, pos = (.2, .5))
63
64 self.engine.resource.load(self, "song", lambda: Song.loadSong(self.engine, songName, library = self.libraryName, notesOnly = True), onLoad = self.songLoaded)
65 self.engine.loadSvgDrawing(self, "background", "keyboard.svg")
66 Dialogs.showLoadingScreen(self.engine, lambda: self.song, text = _("Chilling..."))
67
69 ret = SceneClient.keyPressed(self, key, unicode)
70
71 c = self.controls.keyPressed(key)
72 if self.song and (c in [Player.KEY1, Player.KEY2, Player.CANCEL, Player.ACTION1, Player.ACTION2] or key == pygame.K_RETURN):
73 scores = self.song.info.getHighscores(self.player.difficulty)
74 if not scores or self.player.score > scores[-1][0] or len(scores) < 5:
75 if self.player.cheating:
76 Dialogs.showMessage(self.engine, _("No highscores for cheaters!"))
77 else:
78 name = Dialogs.getText(self.engine, _("%d points is a new high score! Please enter your name:") % self.player.score, self.player.name)
79 if name:
80 self.player.name = name
81 self.highscoreIndex = self.song.info.addHighscore(self.player.difficulty, self.player.score, self.stars, self.player.name)
82 self.song.info.save()
83
84 if self.engine.config.get("game", "uploadscores"):
85 self.uploadingScores = True
86 fn = lambda: self.song.info.uploadHighscores(self.engine.config.get("game", "uploadurl"), self.song.getHash())
87 self.engine.resource.load(self, "uploadResult", fn)
88
89 self.showHighscores = True
90 self.engine.view.pushLayer(self.menu)
91 return True
92
93 return ret
94
99
103
105 self.engine.view.popLayer(self.menu)
106 self.session.world.deleteScene(self)
107 self.nextScene = lambda: self.session.world.createScene("GuitarScene", libraryName = self.libraryName, songName = self.songName)
108
110 self.engine.view.popLayer(self.menu)
111 self.session.world.deleteScene(self)
112 self.nextScene = lambda: self.session.world.createScene("SongChoosingScene")
113
115 song.difficulty = self.player.difficulty
116 notes = len([1 for time, event in song.track.getAllEvents() if isinstance(event, Song.Note)])
117
118 if notes:
119
120 f = float(self.player.notesHit) / notes
121 self.stars = int(5.0 * (f + .05))
122 self.accuracy = int(100.0 * f)
123
124 taunt = None
125 if self.player.score == 0:
126 taunt = "jurgen1.ogg"
127 elif self.accuracy >= 99.0:
128 taunt = "myhero.ogg"
129 elif self.stars in [0, 1]:
130 taunt = random.choice(["jurgen2.ogg", "jurgen3.ogg", "jurgen4.ogg", "jurgen5.ogg"])
131 elif self.stars == 5:
132 taunt = random.choice(["perfect1.ogg", "perfect2.ogg", "perfect3.ogg"])
133
134 if taunt:
135 self.engine.resource.load(self, "taunt", lambda: Sound(self.engine.resource.fileName(taunt)))
136
137 - def run(self, ticks):
138 SceneClient.run(self, ticks)
139 self.time += ticks / 50.0
140 self.counter += ticks
141
142 if self.counter > 5000 and self.taunt:
143 self.taunt.setVolume(self.engine.config.get("audio", "guitarvol"))
144 self.taunt.play()
145 self.taunt = None
146
147 - def anim(self, start, ticks):
148 return min(1.0, float(max(start, self.counter)) / ticks)
149
150 - def render(self, visibility, topMost):
151 SceneClient.render(self, visibility, topMost)
152
153 bigFont = self.engine.data.bigFont
154 font = self.engine.data.font
155
156 v = ((1 - visibility) ** 2)
157
158 glEnable(GL_BLEND)
159 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
160 glEnable(GL_COLOR_MATERIAL)
161
162 self.engine.view.setOrthogonalProjection(normalize = True)
163 try:
164 t = self.time / 100
165 w, h, = self.engine.view.geometry[2:4]
166 r = .5
167 self.background.transform.reset()
168 self.background.transform.translate(v * 2 * w + w / 2 + math.cos(t / 2) * w / 2 * r, h / 2 + math.sin(t) * h / 2 * r)
169 self.background.transform.rotate(-t)
170 self.background.transform.scale(math.sin(t / 8) + 2, math.sin(t / 8) + 2)
171 self.background.draw()
172
173 if self.showHighscores:
174 scale = 0.0017
175 d = self.player.difficulty
176
177 text = _("Highest Scores (%s)") % d
178 w, h = font.getStringSize(text)
179 Theme.setBaseColor(1 - v)
180 font.render(text, (.5 - w / 2, .05 - v))
181
182 x = .1
183 y = .15 + v
184 for i, scores in enumerate(self.song.info.getHighscores(d)):
185 score, stars, name = scores
186 if i == self.highscoreIndex and (self.time % 10.0) < 5.0:
187 Theme.setSelectedColor(1 - v)
188 else:
189 Theme.setBaseColor(1 - v)
190 font.render("%d." % (i + 1), (x, y), scale = scale)
191 font.render(unicode(score), (x + .05, y), scale = scale)
192 font.render(unicode(Data.STAR2 * stars + Data.STAR1 * (5 - stars)), (x + .25, y), scale = scale * .9)
193 font.render(name, (x + .5, y), scale = scale)
194 y += h
195
196 if self.uploadingScores:
197 Theme.setBaseColor(1 - v)
198 if self.uploadResult is None:
199 text = _("Uploading Scores...")
200 else:
201 success, ordinal = self.uploadResult
202 if success:
203 if ordinal > 0:
204 text = _("You're #%d on the world charts!") % ordinal
205 else:
206 text = ""
207 else:
208 text = _("Score upload failed")
209 font.render(text, (.05, .7 + v), scale = 0.001)
210 return
211
212 Theme.setBaseColor(1 - v)
213 text = _("Song Finished!")
214 w, h = font.getStringSize(text)
215 font.render(text, (.5 - w / 2, .05 - v))
216
217 text = "%d" % (self.player.score * self.anim(1000, 2000))
218 w, h = bigFont.getStringSize(text)
219 bigFont.render(text, (.5 - w / 2, .11 + v + (1.0 - self.anim(0, 1000) ** 3)), scale = 0.0025)
220
221 if self.counter > 1000:
222 scale = 0.0017
223 text = (Data.STAR2 * self.stars + Data.STAR1 * (5 - self.stars))
224 w, h = bigFont.getStringSize(Data.STAR1, scale = scale)
225 x = .5 - w * len(text) / 2
226 for i, ch in enumerate(text):
227 bigFont.render(ch, (x + 100 * (1.0 - self.anim(1000 + i * 200, 1000 + (i + 1) * 200)) ** 2, .35 + v), scale = scale)
228 x += w
229
230 if self.counter > 2500:
231 text = _("Accuracy: %d%%") % self.accuracy
232 w, h = font.getStringSize(text)
233 font.render(text, (.5 - w / 2, .55 + v))
234 text = _("Longest note streak: %d") % self.player.longestStreak
235 w, h = font.getStringSize(text)
236 font.render(text, (.5 - w / 2, .55 + h + v))
237 finally:
238 self.engine.view.resetProjection()
239