1 """
2 A collection of commonly used, global functions
3 """
4 import Text
5 import Movie
6 import pyzzle
7 import media
8 import pygame
9 import sys
10 from pygame.locals import *
11
18 """Finalizes drawing.
19 Useful for creating custom transitions."""
20 pygame.display.flip()
30 """Draws everything in pyzzle.panel. Does not run any highlight() methods."""
31 beginDraw()
32 endDraw()
33
35 """Pauses the game.
36 @param delay: The number of seconds to pause the game.
37 """
38 framecount=int(delay*pyzzle.framerate)
39 for i in range(framecount):
40 draw()
41
43 """Waits for user to drag the mouse.
44 Draws a rectangle that highlights the user's selection.
45 @type color: (int,int,int)
46 @param color: Color of the rectangle to be drawn.
47 @rtype: Rect
48 @return: The user's selection.
49 """
50 left,top=pygame.mouse.get_pos()
51 selected=Rect(left,top,0,0)
52 mouseDown=True
53 while mouseDown:
54 pyzzle.beginDraw()
55
56 right,bottom=pygame.mouse.get_pos()
57 selected=Rect(min(left,right),
58 min(top,bottom),
59 abs(right-left),
60 abs(bottom-top))
61 pygame.draw.rect(pyzzle.screen, color, selected, 2)
62 pyzzle.endDraw()
63
64 for event in pygame.event.get():
65 if event.type==MOUSEBUTTONUP:
66 mouseDown=False
67 return selected
80 -def drag(cursor='fist.png'):
81 """Waits for user to drag the mouse.
82 @param cursor: Name of the cursor file to display while dragging
83 @rtype: (int,int)
84 @return: coordinates of the cursor after the drag."""
85 mouseDown=True
86 while mouseDown:
87 pyzzle.beginDraw()
88 x,y=pygame.mouse.get_pos()
89 pyzzle.drawCursor(cursor)
90 pyzzle.endDraw()
91
92 for event in pygame.event.get():
93 if event.type==MOUSEBUTTONUP:
94 mouseDown=False
95 return x,y
96
97 -def prompt(text, color=None, fontSize=36):
98 """Prompts a message to the user.
99 The user may press any key so any mousebutton to continue.
100 @param text: The message to display.
101 @param color: The color of message text.
102 @param fontSize: The size of message text.
103 """
104 textSprite=Text.Text(text, fontSize=fontSize, color=color)
105 textSprite._getImage()
106 screenrect=pyzzle.screen.get_rect()
107 textSprite.rect.center=screenrect.center
108 done=False
109 while not done:
110 for event in pygame.event.get():
111 if event.type == QUIT:
112 sys.exit()
113 done=event.type == KEYDOWN or event.type == MOUSEBUTTONDOWN
114 beginDraw()
115 textSprite.draw(pyzzle.screen)
116 endDraw()
117 -def promptText(question='', answer='', numeric=False, allowExit=True, color=None, fontSize=36):
118 """Prompts the user to input text.
119 @param question: A question to display to the user.
120 @param answer: The default answer.
121 @param numeric: Whether only numeric characters are allowed.
122 @param allowExit: Whether the user may escape the prompt by hitting ESC
123 @param color: The color of question and answer text.
124 @param fontSize: The size of question and answer text.
125 @rtype: string
126 @return: The text the user has entered, or None if the user escaped the prompt.
127 """
128 questionSprite=Text.Text(question, fontSize=fontSize, color=color)
129 answerSprite=Text.Text(answer, fontSize=fontSize, color=color)
130 questionSprite._getImage()
131 answerSprite._getImage()
132 screenrect=pyzzle.screen.get_rect()
133 questionSprite.rect.center=screenrect.center
134 while True:
135 for event in pygame.event.get():
136 if event.type == QUIT:
137 sys.exit()
138 if event.type == KEYDOWN:
139 if event.key == K_ESCAPE and allowExit:
140 return None
141 elif event.key == K_BACKSPACE:
142 answer=answer[:-1]
143 elif event.key in (K_RETURN, K_KP_ENTER):
144 if len(answer)>0:
145 return answer
146 elif allowExit:
147 return None
148 else:
149 key=pygame.key.name(event.key)
150 key=' ' if key=='space' else key
151 key='' if len(key)>1 else key
152 key='' if key not in '0123456789.' and numeric else key
153 if pygame.key.get_mods() & KMOD_SHIFT:
154 key=key.upper()
155 upper={'-':'_'}
156 key=upper[key] if key in upper else key
157 answer+=key
158 answerSprite.rect.midtop=questionSprite.rect.midbottom
159 answerSprite.setText(answer)
160 beginDraw()
161 questionSprite.draw(pyzzle.screen)
162 answerSprite.draw(pyzzle.screen)
163 endDraw()
165 """Prompts the user to input a number.
166 @see: promptText
167 @param question: A question to display to the user.
168 @param **param: Arguments of the promptText function.
169 @rtype: float
170 @return: The number the user has entered, or None if the user escaped the prompt.
171 Returns a float or None if user escapes from prompt.
172 """
173 answer=promptText(question, numeric=True, **param)
174 try: answer=float(answer)
175 except: answer=None
176 return answer
177 -def promptChoice(question='', choices=[], allowExit=True, color=None, fontFile=None, fontSize=None, spacing=20, selectionColor=None):
178 """Prompts the user to answer a multiple choice question.
179 @param question: A question to display to the user.
180 @param choices: The choices the user may select.
181 @param allowExit: Whether the user may escape the prompt by hitting ESC
182 @param color: The color of question and choice text.
183 @param fontSize: The size of question and answer text.
184 @param spacing: The spacing between each choice, in pixels.
185 @param param: The color of choice text when highlighted by the user.
186 @rtype: string
187 @return: The text the user has selected, or None if the user escaped the prompt.
188 """
189 if not color: color=Text.Text.colorDefault
190 if not selectionColor: selectionColor=color
191 screenrect=pyzzle.screen.get_rect()
192 questionSprite=Text.Text(question, fontFile=fontFile, fontSize=fontSize, color=color)
193 questionSprite._getImage()
194 questionSprite.rect.center=screenrect.center
195 prevSprite=questionSprite
196 choiceSprites=pygame.sprite.Group()
197 for choice in choices:
198 choiceSprite=Text.Text(choice, fontFile=fontFile, fontSize=fontSize, color=color)
199 choiceSprite._getImage()
200 choiceSprite.rect.center=screenrect.center
201 choiceSprite.rect.top=prevSprite.rect.bottom+spacing
202 choiceSprites.add(choiceSprite)
203 prevSprite=choiceSprite
204 while True:
205 selection=None
206 beginDraw()
207 questionSprite.draw(pyzzle.screen)
208 for choiceSprite in choiceSprites:
209 choiceSprite.color=color
210 if choiceSprite.rect.collidepoint(pyzzle.cursor.rect.center):
211 choiceSprite.color=selectionColor
212 selection=choiceSprite
213 choiceSprite.draw(pyzzle.screen)
214 pyzzle.cursor.rect.topleft=pygame.mouse.get_pos()
215 drawCursor('fwd.png' if selection else 'default.png')
216 endDraw()
217
218 for event in pygame.event.get():
219 if event.type == QUIT:
220 sys.exit()
221 if event.type == KEYDOWN:
222 if event.key == K_ESCAPE and allowExit:
223 return None
224 if event.type == MOUSEBUTTONDOWN:
225 if selection: return selection.text
226
227
228 -def _pan(self, towards, aways):
229 screen=pyzzle.screen.get_rect()
230 mousex, mousey=pyzzle.cursor.rect.center
231 distance=getattr(self.rect,aways)-mousex
232 distance*=.1
233 if not (screen.left <= getattr(self.parent.rect, towards)+distance <= screen.right):
234 self.parent.rect.move_ip(distance,0)
235 else:
236 setattr(self.parent.rect, aways, getattr(screen, aways))
238 """Moves the slide right, and jumps back to the slide's left when it con go no further.
239 Used in panoramic slides."""
240 _pan(self, towards='right', aways='left')
242 """Moves the slide left, and jumps back to the slide's right when it con go no further.
243 Intended as a choice for Hotspot.onHighlight. Used in panoramic slides."""
244 _pan(self, towards='left', aways='right')
245
246
248 """Prepares slides for transition.
249 @attention: Must be used when creating custom transition functions.
250 @type oldslide: Panel
251 @param oldslide: The Panel to exit.
252 @type newslide: Panel
253 @param newslide: The Panel to enter.
254 @param delay: The time it should take to perform onStart and onStop
255 individually, in seconds.
256 @type panel: Panel
257 @param panel: The new parent panel of newslide. pyzzle.panel by default.
258 """
259 if not panel:
260 if hasattr(oldslide, 'parent'): panel=oldslide.parent
261 else: panel=pyzzle.panel
262 if newslide:
263 newslide.parent=panel
264 newslide._getRect()
265 panel.add(newslide)
266 if hasattr(oldslide, 'exit'):
267 oldslide.exit(newslide, delay)
268 if hasattr(newslide, 'enter'):
269 newslide.enter(oldslide, delay)
271 """Finalizes slide transition.
272 @attention: Must be used when creating custom transition functions.
273 @type oldslide: Panel
274 @param oldslide: The Panel to exit.
275 @type newslide: Panel
276 @param newslide: The Panel to enter.
277 @param delay: The time it should take to perform onStart and onStop
278 individually, in seconds.
279 @type panel: Panel
280 @param panel: The new parent panel of newslide. pyzzle.panel by default.
281 """
282 if not panel:
283 if hasattr(oldslide, 'parent'): panel=oldslide.parent
284 else: panel=pyzzle.panel
285 if oldslide:
286 panel.remove(oldslide)
287 pyzzle.history.append((oldslide, newslide))
290 -def transition(oldslide=None, newslide=None, delay=0, **param):
291 """Basic transition function.
292 Pauses the game for a given number of seconds, then flashes to newslide
293 @type oldslide: Panel
294 @param oldslide: The Panel to exit.
295 @type newslide: Panel
296 @param newslide: The Panel to enter.
297 @param delay: The time it should take to perform onStart and onStop
298 individually, in seconds.
299 @param **param: Additional arguments used in beginTransition() and endTransition()
300 """
301 beginTransition(oldslide, newslide, delay, **param)
302 pause(delay)
303 endTransition(oldslide, newslide, delay, **param)
327 return scroll
328 scrollRight =_scrollfn('right', 'left')
329 scrollLeft =_scrollfn('left', 'right')
330 scrollDown =_scrollfn('bottom', 'top')
331 scrollUp =_scrollfn('top', 'bottom')
332
333 -def fade(oldslide=None, newslide=None, delay=0, color=(0,0,0), alpha=255, **param):
334 """Transitions slides by fade in/out. Currently works best on full screen slides.
335 @type oldslide: Panel
336 @param oldslide: The Panel to fade out of.
337 @type newslide: Panel
338 @param newslide: The Panel to fade in to.
339 @param delay: The time it should take perform each fade in/fade out.
340 @type color: (int,int,int)
341 @param color: The color at maximum fade
342 @param alpha: The alpha transparency of the slide at maximum fade
343 @param **param: Additional arguments used in beginTransition() and endTransition()
344 """
345 if not (oldslide and newslide):
346 delay=delay*2
347 framecount=int(delay*pyzzle.framerate)
348 increment=1./(framecount) if framecount else 1.
349 filter=pyzzle.screen.copy()
350 filter.fill(color)
351 filter.set_alpha(alpha)
352 if oldslide:
353 for i in range(framecount):
354 beginDraw()
355 filter.set_alpha(int(alpha*increment*i))
356 pyzzle.screen.blit(filter, (0,0))
357 endDraw()
358 beginTransition(oldslide, newslide, delay, **param)
359 endTransition(oldslide, newslide, delay, **param)
360 if newslide:
361 for i in range(framecount):
362 beginDraw()
363 filter.set_alpha(int(alpha*(1-(increment*i))))
364 pyzzle.screen.blit(filter, (0,0))
365 endDraw()
366
367
368 -def cutscene(oldslide=None, newslide=None, delay=0,
369 onStart=fade, onStop=fade, allowExit=True,
370 moviefile=None, soundfile=None, movie=None, **param):
371 """Transitions from oldslide, plays a movie, and transitions back to newslide.
372 @type oldslide: Panel
373 @param oldslide: The Panel to exit.
374 @type newslide: Panel
375 @param newslide: The Panel to enter.
376 @param delay: The time it should take to perform onStart and onStop
377 individually, in seconds.
378 @param onStart: The transition function used to transition from oldslide to the movie
379 @param onStop: The transition function used to transition from the movie to newslide
380 @param allowExit: Whether the user can skip the movie by hitting ESC.
381 @param moviefile: The name of the movie file to play.
382 Pygame currently only supports the MPEG-1 video codec.
383 @param soundfile: The name of the sound file to play along with the movie.
384 Any sound from the movie will be replaced with this sound.
385 Use this if you are having trouble getting movie sound to play in Pygame.
386 @type movie: Movie
387 @param movie: An instance of the Movie class to play. If specified,
388 any file you specify with the moviefile parameter will be ignored.
389 @param **param: Additional arguments used in beginTransition() and endTransition()
390 """
391 if not movie:
392 movie=Movie.Movie(id=None, moviefile=moviefile, soundfile=soundfile)
393 stopped=False
394 onStart(oldslide, movie, delay)
395 clock = pygame.time.Clock()
396 while not (movie.played or stopped):
397 clock.tick(150)
398 pyzzle.framerate=clock.get_fps()
399 draw()
400 for event in pygame.event.get():
401 if event.type == QUIT:
402 sys.exit()
403 if event.type == KEYDOWN:
404 if event.key == K_ESCAPE and allowExit:
405 stopped=True
406 onStop(movie, newslide, delay)
407