import sys
import os
import re
import new
import yaml
from Collage import Collage
from Surface import SurfaceSet
import pygame
from OpenGL.GL import *
classpath = ['classes']
sys.path += classpath
function_re = re.compile('^(\w+)\(([^)]*)\)$')
class Layer:
def __init__(self, collage=None, surfaces=None, scale=1.0, parallax=1.0):
self.collage = collage
self.surfaces = surfaces
self.scale = scale
self.parallax = parallax
self.position = (0, 0)
self.things = []
self.drawsurfaces = False
def add(self, thing):
self.things.append(thing)
def moveTo(self, x, y):
self.position = (x * self.parallax, y * self.parallax)
def update(self):
for t in self.things:
t.update()
t.collideCheck(self.things)
def drawSurfaces(self):
self.drawsurfaces = True
def hideSurfaces(self):
self.drawsurfaces = False
def toggleDrawSurfaces(self):
self.drawsurfaces = not self.drawsurfaces
def draw(self):
glPushMatrix()
if self.scale != 1.0:
glScalef(self.scale, self.scale, self.scale)
glTranslatef(-self.position[0], -self.position[1], 0)
self.collage.draw()
for t in self.things:
t.draw()
if self.drawsurfaces and self.surfaces:
self.surfaces.draw()
glPopMatrix()
class Level:
def __init__(self, dir):
self.layers = []
self.position = (0, 0)
self.env = {}
self.load(dir)
def load(self, dir):
f = open(os.path.join(dir, 'level.yaml'), 'r')
level = yaml.safe_load(f)
f.close()
layers = level['layers']
for layer in layers:
collage = None
surfaces = None
scale = 1.0
parallax = 1.0
if layer.has_key('collage'):
collage = Collage(os.path.join(dir, 'collages', layer['collage']))
if layer.has_key('surfaces'):
surfaces = SurfaceSet(os.path.join(dir, 'surfaces', layer['surfaces']))
if layer.has_key('scale'):
scale = layer['scale']
if layer.has_key('parallax'):
parallax = layer['parallax']
print 'Creating layer', layer['name'], 'with scale=%f, parallax=%f' % (scale, parallax)
new_layer = Layer(collage, surfaces, scale, parallax)
self.addLayerBack(new_layer)
if layer.has_key('things'):
self.compileThings(new_layer, layer['things'])
if level.has_key('bbox'):
self.bbox = pygame.Rect(level['bbox'])
else:
bboxes = filter(None, [c.bbox for c in filter(None, [l.collage for l in self.layers])])
if bboxes:
self.bbox = bboxes[0]
self.bbox.unionall_ip(bboxes[1:])
else:
self.bbox = None
print "Bounding box:", self.bbox
def compileThings(self, layer, things):
for (name, t) in things.iteritems():
print "Creating", t['class'], name
self.loadClass(t['class'])
properties = {}
if t.has_key('properties'):
properties = t['properties']
properties['surfaces'] = layer.surfaces
self.env[name] = eval('%s(**properties)' % t['class'], self.env, {'properties': properties})
if t.has_key('events'):
for (fdef, str) in t['events'].iteritems():
m = function_re.match(fdef)
if not m:
print "Malformed function definition:", fdef
continue
funcname = m.group(1)
code = "def %s:\n" % m.group(0)
for s in str.split("\n"):
if not s: continue
code += "\t" + s + "\n"
exec code in self.env
f = new.function(self.env[funcname].func_code, self.env)
self.env[name].__dict__[funcname] = new.instancemethod(f, self.env[name], self.env[name].__class__)
del self.env[funcname]
layer.add(self.env[name])
def loadClass(self, classname):
exec "from %s import %s" % (classname, classname) in self.env
def addLayerBack(self, layer):
self.layers.insert(0, layer)
def addLayerFront(self, layer):
self.layers.append(layer)
def moveTo(self, x, y):
self.position = [x,y]
for l in self.layers:
l.moveTo(x, y)
def update(self):
for l in self.layers:
l.update()
def drawSurfaces(self):
for l in self.layers:
l.drawSurfaces()
def hideSurfaces(self):
for l in self.layers:
l.hideSurfaces()
def toggleDrawSurfaces(self):
for l in self.layers:
l.toggleDrawSurfaces()
def draw(self):
for l in self.layers:
l.draw()