1 from __future__
import division
2 from xml
.sax
import ContentHandler
3 from pyglet
.gl
.gl
import *
4 from tracker
import tracker
5 from geom
import vector
, rect
14 VIEW_ACCELERATION
= 1000
20 class handler (ContentHandler
):
22 def __init__ (self
, lvl
):
23 ContentHandler
.__init
__ (self
)
32 def startElement (self
, name
, attrs
):
33 if name
in ('level', ):
35 raise SAXParseException ('<level> unexpected')
37 elif name
in ('area', 'view', 'bg', 'gravity', 'walls', 'actors'):
38 if self
.trace
!= ['level']:
39 raise SAXParseException ('<%s> unexpected' % name
)
41 elif name
in ('wall', ):
42 if self
.trace
!= ['level', 'walls']:
43 raise SAXParseException ('<%s> unexpected' % name
)
45 self
.lvl
.walls
.append (wall ())
47 elif name
in ('top', 'left', 'right', 'bottom'):
48 if self
.trace
!= ['level', 'area']:
49 raise SAXParseException ('<%s> unexpected' % name
)
51 elif name
in ('x', 'y'):
52 if self
.trace
!= ['level', 'view']:
53 raise SAXParseException ('<%s> unexpected' % name
)
55 elif name
in ('width', 'height'):
56 if not self
.trace
or self
.trace
[-1] not in ('bg', ):
57 raise SAXParseException ('<%s> unexpected' % name
)
59 elif name
in ('x1', 'y1', 'x2', 'y2'):
60 if self
.trace
!= ['level', 'walls', 'wall']:
61 raise SAXParseException ('<%s> unexpected' % name
)
63 elif name
in ('img', ):
64 if not self
.trace
or self
.trace
[-1] not in ('bg', 'wall'):
65 raise SAXParseException ('<%s> unexpected' % name
)
67 elif name
in ('bounce', 'friction', 'stiction'):
68 if self
.trace
!= ['level', 'walls', 'wall']:
69 raise SAXParseException ('<%s> unexpected' % name
)
72 raise SAXParseException ('<%s> tag unknown' % name
)
74 self
.trace
.append (name
)
76 def endElement (self
, name
):
77 if name
!= self
.trace
.pop ():
78 raise SAXParseException ('</%s> unexpected' % name
)
81 self
.lvl
.area
.pos
.x
= (self
.__left
+ self
.__right
) / 2
82 self
.lvl
.area
.pos
.y
= (self
.__bottom
+ self
.__top
) / 2
83 self
.lvl
.area
.set_width (self
.__right
- self
.__left
)
84 self
.lvl
.area
.set_height (self
.__top
- self
.__bottom
)
86 w
= wall (self
.lvl
.walls
[-1].seg
,
87 self
.lvl
.walls
[-1].img
)
88 w
.bounce
= self
.lvl
.walls
[-1].bounce
89 w
.friction
= self
.lvl
.walls
[-1].friction
90 w
.stiction
= self
.lvl
.walls
[-1].stiction
91 self
.lvl
.walls
[-1] = w
93 def characters (self
, content
):
95 raise SAXParseException ('tag missing')
97 if self
.trace
[-1] == 'top':
98 if self
.trace
[-2] == 'area':
99 self
.__top
= float (content
)
101 elif self
.trace
[-1] == 'left':
102 if self
.trace
[-2] == 'area':
103 self
.__left
= float (content
)
105 elif self
.trace
[-1] == 'right':
106 if self
.trace
[-2] == 'area':
107 self
.__right
= float (content
)
109 elif self
.trace
[-1] == 'bottom':
110 if self
.trace
[-2] == 'area':
111 self
.__bottom
= float (content
)
113 elif self
.trace
[-1] == 'x':
114 if self
.trace
[-2] == 'view':
115 self
.lvl
.view
.pos
.x
= tracker (VIEW_ACCELERATION
,
119 self
.lvl
.view
.pos
.x
.x
= float (content
)
120 self
.lvl
.view
.pos
.x
.y
= float (content
)
122 elif self
.trace
[-1] == 'y':
123 if self
.trace
[-2] == 'view':
124 self
.lvl
.view
.pos
.y
= tracker (VIEW_ACCELERATION
,
128 self
.lvl
.view
.pos
.y
.x
= float (content
)
129 self
.lvl
.view
.pos
.y
.y
= float (content
)
131 elif self
.trace
[-1] == 'width':
132 if self
.trace
[-2] == 'bg':
133 self
.lvl
.bg_size
.x
= float (content
)
135 elif self
.trace
[-1] == 'height':
136 if self
.trace
[-2] == 'bg':
137 self
.lvl
.bg_size
.y
= float (content
)
139 elif self
.trace
[-1] == 'gravity':
140 self
.lvl
.gravity
= float (content
)
142 elif self
.trace
[-1] == 'x1':
143 if self
.trace
[-2] == 'wall':
144 self
.lvl
.walls
[-1].seg
.p1
.x
= float (content
)
146 elif self
.trace
[-1] == 'y1':
147 if self
.trace
[-2] == 'wall':
148 self
.lvl
.walls
[-1].seg
.p1
.y
= float (content
)
150 elif self
.trace
[-1] == 'x2':
151 if self
.trace
[-2] == 'wall':
152 self
.lvl
.walls
[-1].seg
.p2
.x
= float (content
)
154 elif self
.trace
[-1] == 'y2':
155 if self
.trace
[-2] == 'wall':
156 self
.lvl
.walls
[-1].seg
.p2
.y
= float (content
)
158 elif self
.trace
[-1] == 'img':
159 if self
.trace
[-2] == 'bg':
160 self
.lvl
.bg
= self
.lvl
.res
.image (content
)
161 elif self
.trace
[-2] == 'wall':
162 self
.lvl
.walls
[-1].img
= self
.lvl
.res
.texture (content
)
164 elif self
.trace
[-1] == 'bounce':
165 if self
.trace
[-2] == 'wall':
166 self
.lvl
.walls
[-1].bounce
= float (content
)
168 elif self
.trace
[-1] == 'friction':
169 if self
.trace
[-2] == 'wall':
170 self
.lvl
.walls
[-1].friction
= float (content
)
172 elif self
.trace
[-1] == 'stiction':
173 if self
.trace
[-2] == 'wall':
174 self
.lvl
.walls
[-1].stiction
= float (content
)
178 class level (object):
180 def __init__ (self
, cfg
, path
= None):
181 self
.res
= pyglet
.resource
186 self
.bg_size
= vector (1, 1)
192 from pyglet
.window
.key
import KeyStateHandler
193 self
.keys
= KeyStateHandler ()
196 def load (self
, path
):
198 from os
.path
import dirname
199 self
.res
= pyglet
.resource
.Loader (script_home
= dirname (path
))
201 from xml
.sax
import parse
202 parse (path
, handler (self
))
204 def pressed (self
, action
):
205 '''Check by action if a key is pressed.'''
207 from pyglet
.window
import key
208 return self
.keys
[getattr (key
, self
.cfg
[action
])]
210 def update (self
, dt
):
211 for actor
in self
.actors
:
212 actor
.vel
.y
-= dt
* self
.gravity
215 self
.view
.pos
.x
.x
= self
.player
.oval
.pos
.x
216 self
.view
.pos
.y
.x
= self
.player
.oval
.pos
.y
218 self
.view
.pos
.x
.update (dt
)
219 self
.view
.pos
.y
.update (dt
)
222 if self
.view
.top () > self
.area
.top ():
223 self
.view
.pos
.y
.x
= self
.area
.top () - self
.view
.size
.y
224 self
.view
.pos
.y
.y
= self
.area
.top () - self
.view
.size
.y
225 self
.view
.pos
.y
.v
= 0
227 if self
.view
.left () < self
.area
.left ():
228 self
.view
.pos
.x
.x
= self
.area
.left () + self
.view
.size
.x
229 self
.view
.pos
.x
.y
= self
.area
.left () + self
.view
.size
.x
230 self
.view
.pos
.x
.v
= 0
232 if self
.view
.right () > self
.area
.right ():
233 self
.view
.pos
.x
.x
= self
.area
.right () - self
.view
.size
.x
234 self
.view
.pos
.x
.y
= self
.area
.right () - self
.view
.size
.x
235 self
.view
.pos
.x
.v
= 0
237 if self
.view
.bottom () < self
.area
.bottom ():
238 self
.view
.pos
.y
.x
= self
.area
.bottom () + self
.view
.size
.y
239 self
.view
.pos
.y
.y
= self
.area
.bottom () + self
.view
.size
.y
240 self
.view
.pos
.y
.v
= 0
242 glMatrixMode (GL_PROJECTION
)
244 glOrtho (self
.view
.left (),
247 self
.view
.top (), -1, 1)
250 bg_width
= self
.bg_size
.x
* self
.view
.width ()
251 bg_height
= self
.bg_size
.y
* self
.view
.height ()
254 y
= self
.view
.bottom () - self
.area
.bottom ()
255 y
/= self
.area
.height () - self
.view
.height ()
256 y
= (self
.area
.bottom () + y
* (self
.area
.height () - bg_height
))
257 except ZeroDivisionError:
258 y
= self
.area
.bottom ()
261 x
= self
.view
.left () - self
.area
.left ()
262 x
/= self
.area
.width () - self
.view
.width ()
263 x
= (self
.area
.left () + x
* (self
.area
.width () - bg_width
))
264 except ZeroDivisionError:
265 x
= self
.area
.left ()
267 glBindTexture (GL_TEXTURE_2D
, self
.bg
.id)
268 glBegin (GL_TRIANGLE_STRIP
)
269 glColor4d (1, 1, 1, 1)
271 glTexCoord2d (self
.bg
.tex_coords
[0],
272 self
.bg
.tex_coords
[1])
275 glTexCoord2d (self
.bg
.tex_coords
[3],
276 self
.bg
.tex_coords
[4])
277 glVertex2d (x
+ bg_width
, y
)
279 glTexCoord2d (self
.bg
.tex_coords
[9],
280 self
.bg
.tex_coords
[10])
281 glVertex2d (x
, y
+ bg_height
)
283 glTexCoord2d (self
.bg
.tex_coords
[6],
284 self
.bg
.tex_coords
[7])
285 glVertex2d (x
+ bg_width
, y
+ bg_height
)
289 glClear (GL_COLOR_BUFFER_BIT
)
291 for actor
in self
.actors
:
294 for wall
in self
.walls
: