Module GameResultsScene
[hide private]
[frames] | no frames]

Source Code for Module GameResultsScene

  1  #####################################################################
 
  2  # -*- coding: iso-8859-1 -*-                                        #
 
  3  #                                                                   #
 
  4  # Frets on Fire                                                     #
 
  5  # Copyright (C) 2006 Sami Kyöstilä                                  #
 
  6  #                                                                   #
 
  7  # This program is free software; you can redistribute it and/or     #
 
  8  # modify it under the terms of the GNU General Public License       #
 
  9  # as published by the Free Software Foundation; either version 2    #
 
 10  # of the License, or (at your option) any later version.            #
 
 11  #                                                                   #
 
 12  # This program is distributed in the hope that it will be useful,   #
 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of    #
 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     #
 
 15  # GNU General Public License for more details.                      #
 
 16  #                                                                   #
 
 17  # You should have received a copy of the GNU General Public License #
 
 18  # along with this program; if not, write to the Free Software       #
 
 19  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,        #
 
 20  # MA  02110-1301, USA.                                              #
 
 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  
 
38 -class GameResultsScene:
39 pass
40
41 -class GameResultsSceneServer(GameResultsScene, SceneServer):
42 pass
43
44 -class GameResultsSceneClient(GameResultsScene, SceneClient):
45 - def createClient(self, libraryName, songName):
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
68 - def keyPressed(self, key, unicode):
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
95 - def hidden(self):
96 SceneClient.hidden(self) 97 if self.nextScene: 98 self.nextScene()
99
100 - def quit(self):
101 self.engine.view.popLayer(self.menu) 102 self.session.world.finishGame()
103
104 - def replay(self):
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
109 - def changeSong(self):
110 self.engine.view.popLayer(self.menu) 111 self.session.world.deleteScene(self) 112 self.nextScene = lambda: self.session.world.createScene("SongChoosingScene")
113
114 - def songLoaded(self, song):
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 # 5 stars at 95%, 4 stars at 75% 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