Disabled actor rotation for speed
[flail.git] / level.py
blobb457cc9eff467e46dcc7ec21fadc54475a975fe3
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
6 from wall import wall
10 import pyglet
14 VIEW_ACCELERATION = 1000
15 VIEW_X_TOLERANCE = 5
16 VIEW_V_TOLERANCE = 50
20 class handler (ContentHandler):
22 def __init__ (self, lvl):
23 ContentHandler.__init__ (self)
25 self.lvl = lvl
26 self.trace = []
27 self.__top = 0
28 self.__left = 0
29 self.__right = 0
30 self.__bottom = 0
32 def startElement (self, name, attrs):
33 if name in ('level', ):
34 if self.trace:
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)
71 else:
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)
80 if name == 'area':
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)
85 elif name == 'wall':
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):
94 if not self.trace:
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,
116 VIEW_X_TOLERANCE,
117 VIEW_V_TOLERANCE)
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,
125 VIEW_X_TOLERANCE,
126 VIEW_V_TOLERANCE)
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
182 self.cfg = cfg
183 self.area = rect ()
184 self.view = rect ()
185 self.bg = None
186 self.bg_size = vector (1, 1)
187 self.gravity = 0
188 self.walls = []
189 self.actors = []
190 self.player = None
192 from pyglet.window.key import KeyStateHandler
193 self.keys = KeyStateHandler ()
194 self.load (path)
196 def load (self, path):
197 if 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
213 actor.update (dt)
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)
221 def render (self):
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)
243 glLoadIdentity ()
244 glOrtho (self.view.left (),
245 self.view.right (),
246 self.view.bottom (),
247 self.view.top (), -1, 1)
249 if self.bg:
250 bg_width = self.bg_size.x * self.view.width ()
251 bg_height = self.bg_size.y * self.view.height ()
253 try:
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 ()
260 try:
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])
273 glVertex2d (x, y)
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)
287 glEnd ()
288 else:
289 glClear (GL_COLOR_BUFFER_BIT)
291 for actor in self.actors:
292 actor.render ()
294 for wall in self.walls:
295 wall.render ()