Package pyzzle :: Module Slide
[hide private]
[frames] | no frames]

Source Code for Module pyzzle.Slide

  1  """ 
  2  The basic building blocks of myst games.  
  3  Start here if you're not sure where to go 
  4  """ 
  5  import pygame, os 
  6  from pygame.sprite import Group 
  7  from pygame.rect import Rect 
  8  from pygame.surface import Surface 
  9  from RelativeRect import RelativeRect 
 10  from Hotspot import Hotspot 
 11  from Panel import Panel 
 12  from DB import Table,Row 
 13  import pyzzle 
 14  import standard 
 15  import Text 
 16  import media 
17 18 19 20 -class Slide(Panel):
21 """The basic building blocks of myst games. 22 23 A typical slide represents a location the player can visit in the game world. 24 Some slides may also represent items or switches that the player can interact with. 25 26 Every Slide has its own image file in the game world. 27 When the player encounters the Slide, he is presented with this image. 28 The player clicks on parts of the slide in order to perform certain actions. 29 These parts of the slide are called Hotspots. 30 31 As a subclass of Panel, the Slide class resembles both the Sprite and Group 32 classes of Pygame. As Sprites, they can blit an image to the screen, but as 33 Groups, they can manage the behavior of other Sprites that are nested within them. 34 Typically, Hotspots are the only Sprites nested within Slides, but it is possible 35 to store other types of Sprites, such as Text, Movies, and even other Slides.""" 36 37 __metaclass__=Table 38
39 - def panHotspots(self, direction):
40 panWidth=.2 41 rectRels=\ 42 {'left': Rect(0, rect.top, 43 screen.width*panWidth,rect.height), 44 'right': Rect(screen.width*(1-panWidth),rect.top, 45 screen.width*(panWidth),rect.height) } 46 highlighting={'left':standard.panLeft, 47 'right':standard.panRight} 48 hotspot=Hotspot(self, None, cursor=direction+'.png', 49 onHighlight=highlighting[direction], 50 layer=.1, _template=True) 51 hotspot.rect=highlighting[direction] 52 return hotspot
53 - def templateHotspots(self, link, direction):
54 width=.025 55 rectRels=\ 56 {'left': (0,0,width,1.), 57 'right': (1.-width,0,width,1.), 58 'forward': (width,width,1-width,1-width), 59 'up': (0,0,1.,width), 60 'down': (0,1.-width,1.,width) } 61 transitions=\ 62 {'left': standard.scrollLeft, 63 'right': standard.scrollRight, 64 'forward': standard.transition, 65 'up': standard.scrollUp, 66 'down': standard.scrollDown } 67 hotspot=Hotspot(self, link, None, 68 rectRel=RelativeRect(rectRels[direction]), 69 cursor=direction+'.png', onTransition=transitions[direction], 70 layer=-1., _template=True) 71 if direction=='forward': 72 hotspot.cursor='fwd.png' 73 hotspot.soundfile = self._movementSoundfile 74 if self._refs['left'] == self._refs['right'] and direction in ('left','right'): 75 hotspot.cursor=cursor=direction+'180.png' 76 return hotspot
77 @staticmethod
78 - def _load(cells):
79 row=Row(cells) 80 stage=pyzzle.stages[row.stage] 81 slide=Slide(row.id, row.image, stage, ambiencefile=row.ambientSound, 82 rectRel=RelativeRect((row.rectleft, row.recttop, 83 row.rectheight, row.rectwidth)), 84 layer=row.layer) 85 slide._movementSoundfile=row.movementSound 86 slide._refs={} 87 if stage and stage.movementSound and not row.movementSound: 88 slide._movementSoundfile=stage.movementSound 89 for ref in 'forward', 'up', 'down', 'right', 'left': 90 slide._refs[ref]=row[ref] 91 return slide
92 - def _loadRefs(self):
93 for direction in self._refs: 94 linkname=self._refs[direction] 95 link=Slide[linkname] if linkname else None 96 if pyzzle.design or linkname: 97 hotspot=self.templateHotspots(link, direction) 98 setattr(self,direction,hotspot) 99 self.add(hotspot)
100 - def _save(self):
101 cells= \ 102 {'id':self.id, 103 'stage':self.stage.id if self.stage else None, 104 'image':self.file, 105 'ambientSound' :self._ambiencefile, 106 'movementSound':self._movementSoundfile, 107 'layer' :self._layer} 108 if self.rectRel: 109 for attr in 'left','top','width','height': 110 cells['rect'+attr]=getattr(self.rectRel, attr) 111 for ref in 'forward', 'up', 'down', 'right', 'left': 112 hotspot=getattr(self,ref) 113 if hotspot and hotspot.link: 114 cells[ref]=hotspot.link.id 115 return cells
116 117 118 119 120
121 - def __init__(self, id, file, stage=None, parent=None, 122 ambiencefile=None, rectRel=None, layer=0, 123 cursor='', visible=True, enabled=True):
124 """Creates a slide. 125 Parameters: 126 @param id: A unique identifier for the Slide. Used to refer to the Slide 127 in scripts and the database 128 @param file: The name of the image file drawn by the slide. 129 @type stage: Stage 130 @param stage: An area of the game in which the slide occurs. Used to determine 131 folder paths and default ambience/movement sounds. 132 @type parent: Panel 133 @param parent: The panel that the slide is nested within. 134 The default is pyzzle.panel. 135 Note: This will not add the slide to the panel. You still need to add it 136 using Slide.enter() or one of the transition functions 137 @param ambiencefile: The name of the sound file that is played in a loop when 138 the player reaches the slide. 139 @type rectRel: RelativeRect 140 @param rectRel: The rectangle occupied by the Slide. 141 Currently, rect width and height do not resize the slide image. 142 @type layer: float 143 @param layer: The layer of the Slide. Larger numbers represent upper layers. 144 When the player clicks on an area of the Slide where two Sprites overlap, 145 the sprite with the topmost layer is the only one that's activated. 146 @param cursor: The name of the cursor file that is displayed when no hotspots are 147 highlighted. The default is defined by Panel.cursorDefault. None displays no cursor. 148 """ 149 if id: Slide.rows[id]=self 150 if not parent: parent=pyzzle.panel 151 Panel.__init__(self) 152 self.id = id 153 self._file = file 154 self.stage=stage 155 self.parent=parent 156 self._ambiencefile=ambiencefile 157 self.rectRel=rectRel 158 self._layer=layer 159 self.cursor=Panel.cursorDefault if cursor =='' else cursor 160 161 self._movementSoundfile=None 162 self._rect=None 163 self.loaded=False 164 """Whether the player has loaded the slide's image file 165 in the current game session.""" 166 self.links=Group() 167 """All Hotspots that link to this slide when clicked.""" 168 self.visited=False 169 """Whether the player has previously visited the slide.""" 170 171 for ref in 'forward', 'up', 'down', 'right', 'left': 172 setattr(self, ref, None)
173 174
175 - def _loadImage(self, image):
176 self.loaded=True 177 screen=pyzzle.screen.get_rect() 178 rect=image.get_rect() 179 rect.center=self.parent.rect.center 180 if self.rectRel: 181 rectAbs=self.rectRel.absolute(self.parent.rect) 182 for attr in 'left','top','width','height': 183 value=getattr(rectAbs, attr) 184 if value: setattr(rect,attr,value) 185 186 if rect.width > screen.width: 187 self.add(self.panHotspots('left')) 188 self.add(self.panHotspots('right')) 189 self._rect=rect
190 - def _getImage(self):
191 """The image displayed by the Slide.""" 192 file=self.file 193 if self.stage: 194 file=os.path.join(self.stage.folder, file) 195 image=media.images.load(file) 196 if not self.loaded: self._loadImage(image) 197 return image
198 image=property(_getImage) 199
200 - def _getRect(self):
201 """The portion of the screen occupied by the slide. 202 rect coordinates are determined by rectRel. 203 If a coordinate in rectRel is None, the coordinate is 204 determined by the slide's image size. 205 """ 206 self._getImage() 207 return self._rect
208 rect=property(_getRect) 209 210
211 - def _setFile(self, file):
212 self._file=file 213 self.loaded=False
214 - def _getFile(self):
215 """The name of the image file displayed by the Slide. 216 Resets self.loaded to False""" 217 return self._file
218 file=property(_getFile, _setFile) 219 220
221 - def _getAmbiencefile(self):
222 """The name of the sound file that is played in a loop when 223 the player reaches the slide. If none is specified, it returns 224 the default for the slide's stage.""" 225 if self._ambiencefile: 226 return self._ambiencefile 227 if self.stage: 228 return self.stage.ambientSound
229 - def _setAmbiencefile(self,value):
230 self._ambiencefile=value
231 ambiencefile=property(_getAmbiencefile, _setAmbiencefile) 232
233 - def draw(self, screen):
234 """Draws the slide's image to screen, 235 then draws any sprites within the Slide.""" 236 screen.blit(self.image, self._rect) 237 Panel.draw(self, screen) 238 239 if pyzzle.design: 240 Text.Text(self.id).draw(screen)
241 - def enter(self, oldslide=None, delay=.1):
242 """Called when the user enters the Slide. 243 @type oldslide: Panel 244 @param oldslide: The Panel that was previously presented to the user, 245 to be replaced by self 246 @param delay: The time it should take for oldslide to transition to self 247 """ 248 Panel.enter(self, oldslide, delay) 249 self.visited=True 250 if self.ambiencefile: 251 ambience=media.sounds.load(self.ambiencefile) 252 if ambience.get_num_channels() == 0: 253 ambience.play(-1, fade_ms=int(delay*1000))
254 - def exit(self, newslide=None, delay=.1):
255 """Called when the user exits the Slide. 256 @type newslide: Panel 257 @param newslide: The Panel that was previously presented to the user, 258 to be replaced by self 259 @param delay: The time it should take for oldslide to transition to self, 260 in seconds 261 """ 262 Panel.exit(self, newslide, delay) 263 if self.ambiencefile and \ 264 ((not hasattr(newslide, 'ambiencefile')) or self.ambiencefile!=newslide.ambiencefile): 265 ambience=media.sounds.load(self.ambiencefile) 266 ambience.fadeout(int(delay*1000))
267