Initial commit
8 files changed, 979 insertions(+), 0 deletions(-)

A => ogm/__init__.py
A => ogm/character.py
A => ogm/controler.py
A => ogm/engine.py
A => ogm/layer.py
A => ogm/level.py
A => ogm/physics.py
A => ogm/tileset.py
A => ogm/__init__.py +1 -0
@@ 0,0 1,1 @@ 
+__all__=["tileset","layer","level","character","engine","physics"]

          
A => ogm/character.py +102 -0
@@ 0,0 1,102 @@ 
+from ogm.tileset import Tileset_GL
+import xml.dom.minidom
+from OpenGL.GL import *
+from OpenGL.GLU import *
+import ogm.engine
+import ogm.physics
+class Character:
+	def __init__(self,xml_file):
+		engine = ogm.engine.get_engine()
+		dom_doc = xml.dom.minidom.parse(xml_file)
+		root = dom_doc.getElementsByTagName("character")[0]
+		self.name = root.getAttribute("name")
+		self.creator = root.getAttribute("creator")
+		self.date = root.getAttribute("date")
+		self.h = int(root.getAttribute("h"))
+		self.w = int(root.getAttribute("w"))
+		self.license = root.getAttribute("license")#need test
+		
+		tiles = dom_doc.getElementsByTagName("tileset")[0]
+		tileh = int(tiles.getAttribute("h"))
+		tilew = int(tiles.getAttribute("w"))
+		tilefile = tiles.getAttribute("file")
+		if tiles.hasAttribute("colorkey"):
+			colorkey = int(tiles.getAttribute("colorkey"))
+		else:
+			colorkey = None
+		self.tileset = tmptileset = engine.get_tileset(tilefile,tilew,tileh,colorkey)#Tileset_GL(tilefile,tilew,tileh)
+		
+		bbox = dom_doc.getElementsByTagName("boundingbox")[0]
+		xoff = int(bbox.getAttribute("xoffset"))
+		yoff = int(bbox.getAttribute("yoffset"))
+		w = int(bbox.getAttribute("width"))
+		h = int(bbox.getAttribute("height"))
+		self.bbox = ogm.physics.BoundingBox(xoff,yoff,w,h)
+		
+		self.x = 0
+		self.y = 0
+		self.actions = {}
+		for action in dom_doc.getElementsByTagName("action"):
+			key = action.getAttribute("key")
+			act = []
+			for step in action.getElementsByTagName("step"):
+				tile = int(step.getAttribute("tile"))
+				time = int(step.getAttribute("time"))
+				act.append((time,tile))
+			self.actions[key] = act 
+			
+		self.current_act = self.actions.keys()[0]
+		self.time = 0
+		self.texture = self.tileset[self.actions[self.current_act][0][1]]
+		print self.w, self.h
+		#self.tnext = self.actions["right"][1][0]
+	def get_action(self):
+		return self.current_act
+	def get_bounding_box(self):
+		return self.bbox		
+		
+	def render(self,xoff,yoff):
+		glBindTexture(GL_TEXTURE_2D, self.texture)
+
+		#print self.tileset[self.level[x][y]],xp,yp
+		#top 
+		glPushMatrix()
+		glLoadIdentity()
+		glTranslatef(xoff, -1*yoff-2,0.0)
+		
+		glTranslatef(0.0,0.0, -244.0)
+		glBegin(GL_QUADS)
+		# Top left corner
+		glTexCoord2f(0, 1)
+		glVertex(self.x, -1*self.y, 0)
+		# Top right corner
+		glTexCoord2f(1, 1)
+		glVertex(self.x+self.w, -1*self.y, 0)
+
+		# Bottom right corner
+		glTexCoord2f(1, 0)
+		glVertex(self.x+self.w, -1*self.y-self.h, 0)
+		# Bottom left corner
+		glTexCoord2f(0, 0)
+		glVertex(self.x, -1*self.y-self.h, 0)
+		glEnd()
+		glPopMatrix()
+		
+	def action(self, action):
+		if action == None:
+			self.time = 0
+			return
+		if not action == self.current_act:
+			self.current_act = action
+			self.time = 0
+	def update (self,time):
+		self.time = self.time + time
+		self.x += int(time * self.bbox.vect[0])
+		self.y += int(time * self.bbox.vect[1]) 
+		for tme,tile in self.actions[self.current_act]:
+			if self.time <= tme:
+				self.texture = self.tileset[tile]
+				return
+		self.time = 0
+		self.texture = self.tileset[self.actions[self.current_act][0][1]]
+		

          
A => ogm/controler.py +85 -0
@@ 0,0 1,85 @@ 
+import pygame
+import ogm.engine
+class Controler:
+	'''
+	Controler abstraction class
+	'''
+	def __init__( self ):
+		self.objects = []
+	def bind_object( self ,obj):
+		self.objects.append(obj)
+	def update( self ,time):
+		raise NotImplementedError( "Should have implemented this" )
+	def release_obj( self, obj):
+		self.objects.remove(obj)
+        
+class PlayerControler( Controler ):
+	'''
+	Controler that allows keyboard bindings (draft, will be configurable in future release)
+	'''
+
+	def update( self ,time):
+		key = pygame.key.get_pressed()
+		for car in self.objects:
+			if key[pygame.K_SPACE] :
+				if  car.bbox.contact['down']:
+					car.bbox.accel(0,-0.6)
+			if key[pygame.K_LEFT]:
+				car.bbox.vect[0] = -0.3
+				car.action("left")
+			elif key[pygame.K_RIGHT]:
+				car.bbox.vect[0] = 0.3
+				car.action("right")
+			elif key[pygame.K_DOWN]:
+				car.action("down")
+			elif key[pygame.K_UP]:
+				car.action("up")
+			else:
+				car.action(None)
+				car.bbox.vect[0] = 0.0
+
+class AIContactSeeker( Controler ):
+	'''
+	Naive "AI", seek contact with the player
+	'''
+	def __init__( self ):
+	#	self.objects = []
+		Controler.__init__(self)
+		self.dist = []
+		self.rate = 300
+		self.counter = 0
+	def update( self ,time):
+		self.counter += time
+		engine = ogm.engine.get_engine()
+		
+		th = engine.level.collide_tile_h
+		tw = engine.level.collide_tile_w
+		if self.counter > self.rate or len(self.dist) == 0:
+			self.counter = 0
+			car = engine.get_player()
+			array = engine.level.collide_array
+			bbox = car.get_bounding_box()
+			px = (car.x + bbox.xoff + bbox.width/2)/tw
+			py = (car.y + bbox.yoff + bbox.height/2)/th
+			self.dist = []
+			for x in range(len(array)):
+				self.dist.append([])
+				for y in range(len(array)):
+					if array[x][y] == 0:
+						self.dist[x].append(abs(px-x)+abs(py-y))
+					else:
+						self.dist[x].append(len(self.dist)+len(self.dist[x])+1)
+			
+			
+		for car in self.objects:
+			bbox = car.get_bounding_box()
+			px = (car.x + bbox.xoff + bbox.width/2)/tw
+			py = (car.y + bbox.yoff + bbox.height/2)/th
+	
+			if (px+1)<len(self.dist) and self.dist[px+1][py] < self.dist[px][py]:
+				car.bbox.vect[0] = 0.1
+				car.action("right")
+			elif (px-1)<len(self.dist) and self.dist[px-1][py] < self.dist[px][py]:
+				car.bbox.vect[0] = -0.1
+				car.action("left")
+

          
A => ogm/engine.py +127 -0
@@ 0,0 1,127 @@ 
+from ogm.physics import Physics
+import ogm.level
+from ogm.tileset import Tileset_GL
+import pygame
+import sys
+engine = None
+import thread
+class Engine:
+	'''
+	Engine Object, handle the whole game, responsible for traking and updating every assets
+	'''
+	def __init__(self):
+		self.physics = Physics()
+		self.level = None
+		self.tilesets = {}
+		self.controlers = {}
+		self.levels = {}
+		self.player = None
+
+		self.actors = {}
+	def set_player (self,name):
+		if self.actors.has_key(name):
+			self.player = name
+		else:
+			pass
+			#raise exception
+	def get_player (self):
+		return self.actors[self.player]
+	def add_actor (self, name, obj):
+
+		if self.actors.has_key(name):
+			self.remove_actor(name)
+		self.actors[name]= obj
+		self.physics.add_object(obj)
+		
+	def remove_actor (self, name):
+		self.physics.remove_object(self.actors[name])
+		del self.actors[name]
+
+	def remove_actor_by_instance (self, obj):
+		for key in self.actors.keys():
+			if self.actors[key] == obj:
+				self.physics.remove_object(self.actors[key])
+				del self.actors[key]
+				return
+	
+	def add_controler (self, name, obj):
+		self.controlers[name] = obj
+	def get_controler(self, name):
+		return self.controler[name]
+	def __del__(self):
+		pass
+	def unload_level(self,name):
+		del self.level
+		self.level = None
+	def load_level(self,name):
+		del self.level
+		self.level = ogm.level.Level(self.levels[name])
+		
+	def get_tileset(self,name,width,height,colorkey):
+		'''
+		Ensure unique instance of tilesets
+		'''
+		if not self.tilesets.has_key((name,width,height,colorkey)):
+			self.tilesets[(name,width,height,colorkey)] = [Tileset_GL(name,width,height,colorkey),1]
+		else:
+			self.tilesets[(name,width,height,colorkey)][1] += 1
+		return self.tilesets[(name,width,height,colorkey)][0]
+		
+	def release_tileset(self,name,width,height,colorkey):
+		'''
+			smart pointer proc, free tileset from memory when no longer required
+			Warning, get_tileset have to match release_tileset
+		'''
+		# nb: should use directly garbage collector in the future
+		if self.tilesets[(name,width,height,colorkey)][1] == 1: 
+			del  self.tilesets[(name,width,height,colorkey)]
+		else:
+			self.tilesets[(name,width,height,colorkey)][1] -= 1
+	def render(self,xoff,yoff):
+		if self.level != None:
+			self.level.render_callList(xoff,yoff)
+		for actor in self.actors.values():
+			actor.render(xoff,yoff)
+	def update(self,time):
+			for controler in self.controlers.values():
+				controler.update(time)
+			for actor in self.actors.values():
+				actor.update(time)
+			self.physics.update(time)
+	def start(self):
+		'''
+		start the main loop
+		'''
+		clock = pygame.time.Clock()
+		fps = 0
+		time_passed = 0.0
+		time_passed_seconds = 0.0
+		total_time = 0
+		
+		while True:
+			for event in pygame.event.get():
+				if event.type == pygame.QUIT:
+					return
+				
+			fps = fps +1
+			time_passed = clock.tick()
+			time_passed_seconds = time_passed / 1000.
+			total_time = total_time + time_passed_seconds
+			if int(total_time)>1:
+				print float(fps)/total_time
+				total_time = 0
+				fps= 0
+				
+			self.update(time_passed)
+			xoff = -1* self.actors[self.player].x
+			yoff = -1*self.actors[self.player].y +50
+			self.render(xoff,yoff)
+			pygame.display.flip()
+			
+def init():
+	global engine
+	engine = Engine()
+
+	
+def get_engine():
+	return engine

          
A => ogm/layer.py +149 -0
@@ 0,0 1,149 @@ 
+from ogm.tileset import Tileset
+import pygame
+from OpenGL.GL import *
+from OpenGL.GLU import *
+class Layer:
+
+	def __init__(self,tileset,array):
+		self.tileset = tileset
+		self.level = array
+		self.drawable = list()
+		for x in range (len (self.level)):
+			for y in range (len( self.level[x])):
+				if self.level[x][y] == -1:
+					continue
+				self.drawable.append((x,y))
+				
+		
+	def draw(self,surface,xoff,yoff):
+		for x in range (len (self.level)):
+			for y in range (len( self.level[x])):
+				rect = pygame.Rect(x*self.tileset.tile_width+xoff,\
+				y*self.tileset.tile_height+yoff,self.tileset.tile_width,\
+				self.tileset.tile_height)
+				surface.blit(self.tileset[self.level[x][y]],rect,None)
+	def __del__(self):
+		del self.tileset
+		
+	def draw_gl(self):
+
+		if len(self.drawable)>0:
+			for x,y in self.drawable:
+
+				xp= x*self.tileset.tile_width 
+				yp= -1*y*self.tileset.tile_height 
+				
+				glBindTexture(GL_TEXTURE_2D, self.tileset[self.level[x][y]])
+
+				glBegin(GL_QUADS)
+				# Top left corner
+				glTexCoord2f(0, 1)
+				glVertex(xp, yp, 0)
+				# Top right corner
+				glTexCoord2f(1, 1)
+				glVertex(xp+self.tileset.tile_width, yp, 0)
+
+				# Bottom right corner
+				glTexCoord2f(1, 0)
+				glVertex(xp+self.tileset.tile_width, yp-self.tileset.tile_height, 0)
+				# Bottom left corner
+				glTexCoord2f(0, 0)
+				glVertex(xp, yp-self.tileset.tile_height, 0)
+				glEnd()
+					
+	def draw_gl_cubes(self, size):
+
+		if len(self.drawable)>0:
+			for x,y in self.drawable:
+				xp= x*self.tileset.tile_width #-(len (self.level))*10
+				yp= -1*(y*self.tileset.tile_height) #-(len (self.level))*10
+
+				glBindTexture(GL_TEXTURE_2D, self.tileset[self.level[x][y]])
+
+				#top 
+				
+				glBegin(GL_QUADS)
+				# Top left corner
+				glTexCoord2f(0, 1)
+				glVertex(xp, yp, 0)
+				# Top right corner
+				glTexCoord2f(1, 1)
+				glVertex(xp+self.tileset.tile_width, yp, 0)
+				# Bottom right corner
+				glTexCoord2f(1, 0)
+				glVertex(xp+self.tileset.tile_width, yp-self.tileset.tile_height, 0)
+				# Bottom left corner
+				glTexCoord2f(0, 0)
+				glVertex(xp, yp-self.tileset.tile_height, 0)
+				glEnd()
+				#sides
+				#left
+				if (x-1 <=0) or (self.level[x - 1][y] == -1) :
+					glBegin(GL_QUADS)
+					# Top left corner
+					glTexCoord2f(0, 1)
+					glVertex(xp, yp, 0)
+					# Top right corner
+					glTexCoord2f(1, 1)
+					glVertex(xp, yp-self.tileset.tile_height, 0)
+					# Bottom right corner
+					glTexCoord2f(1, 0)
+					glVertex(xp, yp-self.tileset.tile_height, -32)
+					# Bottom left corner
+					glTexCoord2f(0, 0)
+					glVertex(xp, yp, -1*size)
+					glEnd()
+				#right
+				if (x + 1 >= len(self.level)) or (self.level[x + 1][y] == -1) :
+					glBegin(GL_QUADS)
+					# Top left corner
+					glTexCoord2f(0, 1)
+					glVertex(xp+self.tileset.tile_width, yp, 0)
+					# Top right corner
+					glTexCoord2f(1, 1)
+					glVertex(xp+self.tileset.tile_width, yp-self.tileset.tile_height, 0)
+					# Bottom right corner
+					glTexCoord2f(1, 0)
+					glVertex(xp+self.tileset.tile_width, yp-self.tileset.tile_height, -1*size)
+					# Bottom left corner
+					glTexCoord2f(0, 0)
+					glVertex(xp+self.tileset.tile_width, yp, -1*size)
+					glEnd()
+					
+				#top
+				if (y - 1 <= 0) or (self.level[x][y-1] == -1) :
+					glBegin(GL_QUADS)
+					# Top left corner
+					glTexCoord2f(0, 1)
+					glVertex(xp, yp, 0)
+					# Top right corner
+					glTexCoord2f(1, 1)
+					glVertex(xp+self.tileset.tile_width, yp, 0)
+					# Bottom right corner
+					glTexCoord2f(1, 0)
+					glVertex(xp+self.tileset.tile_width, yp, -1*size)
+					# Bottom left corner
+					glTexCoord2f(0, 0)
+					glVertex(xp, yp, -1*size)
+					glEnd()	
+				#bottom
+				if (y + 1 >= len(self.level[x])) or (self.level[x][y+1] == -1) :
+					glBegin(GL_QUADS)
+					# Top left corner
+					glTexCoord2f(0, 1)
+					glVertex(xp, yp-self.tileset.tile_height, 0)
+					# Top right corner
+					glTexCoord2f(1, 1)
+					glVertex(xp+self.tileset.tile_width, yp-self.tileset.tile_height, 0)
+					# Bottom right corner
+					glTexCoord2f(1, 0)
+					glVertex(xp+self.tileset.tile_width, yp-self.tileset.tile_height, -32)
+					# Bottom left corner
+					glTexCoord2f(0, 0)
+					glVertex(xp, yp-self.tileset.tile_height, -32)
+					glEnd()
+				
+				
+			
+				
+

          
A => ogm/level.py +227 -0
@@ 0,0 1,227 @@ 
+from ogm.layer import Layer
+from ogm.tileset import Tileset
+from ogm.tileset import Tileset_GL
+import xml.dom.minidom
+from OpenGL.GL import *
+from OpenGL.GLU import *
+import pygame
+import ogm.engine
+
+class Level:
+	def __init__(self,xml_file=None):
+		if xml_file==None:
+			pass
+		else:
+			
+			engine = ogm.engine.get_engine()
+			self.filename = xml_file
+			dom_doc = xml.dom.minidom.parse(xml_file)
+			root = dom_doc.getElementsByTagName("level")[0]
+			self.name = root.getAttribute("name")
+			self.creator = root.getAttribute("creator")
+			self.date = root.getAttribute("date")
+			self.h = int(root.getAttribute("h"))
+			self.w = int(root.getAttribute("w"))
+			self.background = None
+			self.license = root.getAttribute("license")#need test
+			
+			# building layers
+			layers = dom_doc.getElementsByTagName("layer")
+			self.layers = {}
+			self.layer_name = {}
+			self.elevations = {}
+			self.volumes = {}
+			for layer in layers:
+				tmplayr = []
+				tileset = layer.getAttribute("tileset")
+				tileh = int(layer.getAttribute("tile_h"))
+				tilew = int(layer.getAttribute("tile_w"))
+				if layer.hasAttribute("colorkey"):
+					colorkey = int(layer.getAttribute("colorkey"))
+				else:
+					colorkey = None
+				def_tile = int(layer.getAttribute("default_tile"))
+				lid = int(layer.getAttribute("id"))
+				if layer.hasAttribute("elevation"):
+					self.elevations[lid] = int(layer.getAttribute("elevation"))
+				else:
+					self.elevations[lid] = 0
+				if layer.hasAttribute("volume"):
+					self.volumes[lid] = int(layer.getAttribute("volume"))
+				else:
+					self.volumes[lid] = 0
+				self.layer_name[lid] = (layer.getAttribute("name"))
+				for x in range(self.w):
+					tmplayr.append([])
+					for y in range(self.h):
+						tmplayr[x].append(def_tile)
+				
+				cels = layer.getElementsByTagName("cell")
+				for cell in cels:
+					tmplayr[int(cell.getAttribute("x"))]\
+					[int(cell.getAttribute("y"))] = int(cell.getAttribute("tile"))
+				tmptileset = engine.get_tileset(tileset,tilew,tileh,colorkey)#Tileset_GL(tileset,tilew,tileh,colorkey)
+
+				self.layers[lid] = Layer(tmptileset,tmplayr)
+			self.layers_id = self.layers.keys()
+			self.layers_id.sort()
+			self.callList = {}
+			for id in self.layers_id:
+				self.callList[id] = None
+			self.compute_callList()
+			
+			clayer = dom_doc.getElementsByTagName("collision_layer")[0]
+			self.collide_tile_h = int(clayer.getAttribute("tile_h"))
+			self.collide_tile_w = int(clayer.getAttribute("tile_w"))
+			def_tile = int(clayer.getAttribute("default_tile"))
+			tmplayr = []
+			for x in range(self.w):
+				tmplayr.append([])
+				for y in range(self.h):
+					tmplayr[x].append(def_tile)
+			cels = clayer.getElementsByTagName("cell")
+			for cell in cels:
+				tmplayr[int(cell.getAttribute("x"))]\
+				[int(cell.getAttribute("y"))] = int(cell.getAttribute("tile"))
+			self.collide_array = tmplayr
+			# need clean up ---
+			bg = dom_doc.getElementsByTagName("bg")
+			if len(bg) == 1:
+			
+				surf = pygame.image.load(bg[0].getAttribute("image"))
+				surf.convert_alpha()
+				
+				texture_data = pygame.image.tostring(surf, 'RGBA', True)
+				texture_id = glGenTextures(1)
+				glBindTexture(GL_TEXTURE_2D, texture_id)
+				#for mip mapping
+				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
+				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR)
+				# Tell OpenGL that data is aligned to byte boundries
+				glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
+				#for mip mapping
+				gluBuild2DMipmaps( GL_TEXTURE_2D,4, surf.get_width(),surf.get_height(),\
+				GL_RGBA,GL_UNSIGNED_BYTE, texture_data)
+				self.background = texture_id
+			else:
+				self.background = None
+			
+	def draw(self,surface,xoff,yoff):
+		for lid in self.layers_id:
+			self.layers[lid].draw(surface,xoff,yoff)
+	
+	def __del__(self):
+		engine = ogm.engine.get_engine()
+		for lid in self.layers_id:
+			ts = self.layers[lid].tileset
+			engine.release_tileset(ts.filename,ts.tile_width,ts.tile_height,ts.colorkey)
+			glDeleteLists(self.callList[lid],1)
+			del self.layers[lid]
+		if self.background != None:
+			glDeleteTextures(self.background)
+	def compute_callList(self):
+		for lid in self.layers_id:
+			self.callList[lid] = glGenLists(1)
+			glNewList(self.callList[lid],GL_COMPILE)
+			if not self.volumes[lid] == 0:
+				glTranslatef(0.0, 0.0, self.volumes[lid])
+				self.layers[lid].draw_gl_cubes(self.volumes[lid])
+			else:
+				self.layers[lid].draw_gl()
+			glEndList()
+	def render_callList(self,xoff,yoff):
+		# Clear the screen (similar to fill)
+		glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
+		# Clear the modelview matrix
+
+		glPushMatrix()
+		glLoadIdentity()
+		glDisable(GL_DEPTH_TEST)
+		if self.background != None:
+
+			glBindTexture(GL_TEXTURE_2D, self.background)
+				#print self.tileset[self.level[x][y]],xp,yp
+			#top 
+			glTranslatef(0.0, 0.0, -250.0)
+			
+			glBegin(GL_QUADS)
+			# Top left corner
+			glTexCoord2f(0, 1)
+			glVertex(-200,200, 0)
+			# Top right corner
+			glTexCoord2f(1, 1)
+			glVertex(200, 200, 0)
+			# Bottom right corner
+			glTexCoord2f(1, 0)
+			glVertex(200, -200, 0)
+			# Bottom left corner
+			glTexCoord2f(0, 0)
+			glVertex(-200, -200, 0)
+			glEnd()
+		#glTranslatef(xoff, -1*yoff,0.0)
+		glEnable(GL_DEPTH_TEST)
+		glPopMatrix()
+		for lid in self.layers_id:
+			
+			glPushMatrix()
+			glLoadIdentity()
+			#glRotate(5, 1,0, 0)
+			glTranslatef(xoff, -1*yoff,0.0)
+			
+			
+			glTranslatef(0.0, 0.0, -250.0)
+			glTranslatef(0.0, 0.0, self.elevations[lid])
+			
+			glCallList(self.callList[lid])
+			glPopMatrix()
+		
+	def render(self,xoff,yoff):
+		# Clear the screen (similar to fill)
+		glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
+		# Clear the modelview matrix
+
+		glPushMatrix()
+		glLoadIdentity()
+		glDisable(GL_DEPTH_TEST)
+		if self.background != None:
+
+			glBindTexture(GL_TEXTURE_2D, self.background)
+				#print self.tileset[self.level[x][y]],xp,yp
+			#top 
+			glTranslatef(0.0, 0.0, -250.0)
+			
+			glBegin(GL_QUADS)
+			# Top left corner
+			glTexCoord2f(0, 1)
+			glVertex(-200,200, 0)
+			# Top right corner
+			glTexCoord2f(1, 1)
+			glVertex(200, 200, 0)
+			# Bottom right corner
+			glTexCoord2f(1, 0)
+			glVertex(200, -200, 0)
+			# Bottom left corner
+			glTexCoord2f(0, 0)
+			glVertex(-200, -200, 0)
+			glEnd()
+		#glTranslatef(xoff, -1*yoff,0.0)
+		glEnable(GL_DEPTH_TEST)
+		glPopMatrix()
+		for lid in self.layers_id:
+			
+			glPushMatrix()
+			glLoadIdentity()
+			#glRotate(5, 1,0, 0)
+			glTranslatef(xoff, -1*yoff,0.0)
+			
+			
+			glTranslatef(0.0, 0.0, -250.0)
+			glTranslatef(0.0, 0.0, self.elevations[lid])
+			
+			if not self.volumes[lid] == 0:
+				glTranslatef(0.0, 0.0, self.volumes[lid])
+				self.layers[lid].draw_gl_cubes(self.volumes[lid])
+			else:
+				self.layers[lid].draw_gl()
+			glPopMatrix()
+

          
A => ogm/physics.py +204 -0
@@ 0,0 1,204 @@ 
+import ogm.engine
+COLLIDE_WITH_EVERYTHING = 511
+COLLIDE_WITH_NOTHING = 0
+COLLIDE_WITH_LEVEL = 2
+AFFECTED_BY_GRAVITY = 4
+COLLIDE_WITH_ACTORS = 8
+COLLIDE_WITH_PARTICLES = 16
+COLLIDE_WITH_GROUP_3 = 32
+COLLIDE_WITH_GROUP_4 = 64
+COLLIDE_WITH_GROUP_5 = 128
+COLLIDE_WITH_GROUP_6 = 256
+
+class Physics:
+	def __init__(self):
+		self.objects = []
+	def __del__(self):
+		pass
+	def add_object(self,obj):
+		self.objects.append(obj)
+	def remove_object(self,obj):
+		self.objects.remove(obj)
+	def update(self,time):
+		engine = ogm.engine.get_engine()
+		array = engine.level.collide_array
+		th = engine.level.collide_tile_h
+		tw = engine.level.collide_tile_w
+		h = engine.level.h
+		w = engine.level.w
+		for obj1 in self.objects:
+			bbox1 = obj1.get_bounding_box()
+			u = obj1.y+bbox1.yoff
+			b = obj1.y+bbox1.yoff + bbox1.height
+			r = obj1.x+bbox1.xoff + bbox1.width
+			l = obj1.x+bbox1.xoff
+			if l <= 0 or r >= w*tw \
+			or b <= 0 or u >= h*th:
+				print "out of this silent planet"
+
+				engine.remove_actor_by_instance(obj1)
+				continue
+			if bbox1.state & AFFECTED_BY_GRAVITY:
+				bbox1.accel(0,(0.098/32.0)*time)
+			if bbox1.state & COLLIDE_WITH_NOTHING:
+				continue
+			elif bbox1.state & COLLIDE_WITH_LEVEL :
+				#check left
+				xdiff = 0
+				ydiff = 0
+				
+				#check up
+				if bbox1.vect[1]<0 and (array[(l+1)/tw][(u)/th] == 1\
+				or  array[(r-1)/tw][(u)/th] == 1):
+
+					obj1.y += (u)%th 
+					bbox1.vect[1]=0.0
+					bbox1.contact['up'] = True
+					u = obj1.y+bbox1.yoff
+					b = obj1.y+bbox1.yoff + bbox1.height
+				else:
+					bbox1.contact['up'] = False
+				#check down
+				if  bbox1.vect[1]>0 and (array[(l+1)/tw][(b)/th] == 1\
+				or array[(r-1)/tw][(b)/th] == 1):
+
+					obj1.y -= (b)%th 
+					bbox1.vect[1]=0.0
+					bbox1.contact['down'] = True
+					u = obj1.y+bbox1.yoff
+					b = obj1.y+bbox1.yoff + bbox1.height
+				else:
+					bbox1.contact['down'] = False
+				
+				if 	bbox1.vect[0]<0:
+					if (array[(l)/tw][(u+1)/th] == 1\
+					or array[(l)/tw][(b-1)/th] == 1):
+
+						obj1.x += tw-(l)%tw
+						bbox1.contact['left'] = True
+						r = obj1.x+bbox1.xoff + bbox1.width
+						l = obj1.x+bbox1.xoff
+
+					else:
+						bbox1.contact['left'] = False
+					
+					#check right
+					if  (array[(r)/tw][(u+1)/th] == 1\
+					or array[(r)/tw][(b-1)/th] == 1):
+						obj1.x -= (r)%tw
+					else:
+						bbox1.contact['right'] = False
+				else:
+					
+					#check right
+					if  (array[(r)/tw][(u+1)/th] == 1\
+					or array[(r)/tw][(b-1)/th] == 1):
+						obj1.x -= (r)%tw
+
+						bbox1.contact['right'] = True
+						r = obj1.x+bbox1.xoff + bbox1.width
+						l = obj1.x+bbox1.xoff
+
+					else:
+						bbox1.contact['right'] = False
+						
+					if (array[(l)/tw][(u+1)/th] == 1\
+					or array[(l)/tw][(b-1)/th] == 1):
+	
+						obj1.x += tw-(l)%tw
+						bbox1.contact['left'] = True
+					else:
+						bbox1.contact['left'] = False
+					
+				
+		for obj1 in self.objects:
+			bbox1 = obj1.get_bounding_box()	
+			if not bbox1.state & COLLIDE_WITH_ACTORS:
+				continue
+			for obj2 in self.objects:
+				
+				if obj1 == obj2:
+					continue
+				bbox2 = obj2.get_bounding_box()
+				if not bbox2.state & COLLIDE_WITH_ACTORS:
+					continue
+				contact =  bbox1.colide_with(obj1.x,obj1.y,bbox2,obj2.x, obj2.y)
+
+				if not bbox1.contact['left'] and not bbox2.contact['right']:
+					obj1.x -= contact['right']/2
+					obj2.x += contact['right']/2
+				elif not bbox1.contact['left']:
+					obj1.x -= contact['right']
+				elif not bbox2.contact['right']:
+					obj2.x += contact['right']
+				
+				
+					
+				if not bbox1.contact['right'] and not bbox2.contact['left']:
+					obj1.x += contact['left']/2
+					obj2.x -= contact['left']/2
+				elif not bbox1.contact['right']:
+					obj1.x += contact['left']
+				elif not bbox2.contact['left']:
+					obj2.x -= contact['left']
+					
+				if contact['right']!= 0:
+					bbox1.contact['right'] = True
+					bbox2.contact['left'] = True
+					print obj1.name ,obj2.name
+					if obj1.name == "disc":
+						print "kill"
+						engine.remove_actor_by_instance(obj2)
+						continue
+					elif  obj2.name == "disc":
+						print "kill"
+						engine.remove_actor_by_instance(obj1)
+						continue
+					
+					
+				if contact['left']!= 0:
+					bbox1.contact['left'] = True
+					bbox2.contact['right'] = True
+					print obj1.name ,obj2.name
+					if obj1.name == "disc":
+						print "kill"
+						engine.remove_actor_by_instance(obj2)
+						continue
+					elif  obj2.name == "disc":
+						print "kill"
+						engine.remove_actor_by_instance(obj1)
+						continue
+					
+
+class BoundingBox:
+	def __init__(self,xoff,yoff,w,h):
+		self.xoff = xoff
+		self.yoff = yoff
+		self.width = w
+		self.height = h
+		self.state = COLLIDE_WITH_EVERYTHING
+		self.counter = 0
+		self.vect = [0.0,0.0] #momentum
+		self.contact = {'left':False,'right':False,'up':False,'down':False}
+	def accel(self,x,y):
+		self.vect[0] += x
+		self.vect[1] += y
+		
+	def colide_with(self,x,y,bbox,x2,y2):
+		contact = {'left':0,'right':0,'up':0,'down':0}
+		if (((bbox.yoff+y2)-(self.yoff+y+self.height))*((bbox.yoff+y2+bbox.height)-(self.yoff+y)))<0:
+			
+			if ( (bbox.xoff+x2+bbox.width )> (self.xoff+x) and (bbox.xoff+x2 )< (self.xoff+x)):
+				contact['left'] = (bbox.xoff+x2+bbox.width) - (self.xoff+x)
+			if ( (bbox.xoff+x2 )< (self.xoff+x + self.width) and (bbox.xoff+x2 )> (self.xoff+x )):
+				contact['right'] = (self.xoff+x + self.width) - (bbox.xoff+x2 )
+
+		#not tested
+		if ( (bbox.yoff+y2+bbox.height )> (self.yoff+y) and (bbox.yoff+y2 )< (self.yoff+y+self.height)):
+			contact['down'] = (bbox.yoff+y2+bbox.height) - (self.yoff+y)
+		if ( (bbox.yoff+y2 )< (self.yoff+y + self.height) and (bbox.yoff+y2 )> (self.yoff+y )):
+			contact['up'] = (self.yoff+y + self.height) - (bbox.yoff+y2 )
+		return contact
+				
+		
+		

          
A => ogm/tileset.py +84 -0
@@ 0,0 1,84 @@ 
+import pygame
+from OpenGL.GL import *
+from OpenGL.GLU import *
+
+class Tileset:
+	'''
+	Tileset, legacy interface for tileset manipulation, non-OpenGL
+	'''
+	def __init__(self,filename,width,height):
+		self.filename = filename
+		self.tile_width = width
+		self.tile_height = height
+		self.surface = pygame.image.load(self.filename)
+		self.surface.convert_alpha()
+		self.len = (self.surface.get_width()/self.tile_width)*(self.surface.get_height()/self.tile_height)
+		
+		self.tiles = []
+		
+		# 
+		for y in range(self.surface.get_height()/self.tile_height):
+			for x in range((self.surface.get_width()/self.tile_width)):
+				rect = pygame.Rect(x*self.tile_width,y*self.tile_height,self.tile_width,self.tile_height)
+				self.tiles.append(self.surface.subsurface(rect))
+
+	def __getitem__(self, key):
+		return self.tiles[key]		
+	def __len__(self):
+		return self.len
+		
+class Tileset_GL:
+	'''
+	TilesetGL, OpenGL tileset class, load and manage tiles
+	'''
+	def __init__(self,filename,width,height,colorkey=None):
+		self.filename = filename
+		self.tile_width = width
+		self.tile_height = height
+		self.surface = pygame.image.load(self.filename)
+		self.colorkey = colorkey
+		if colorkey!= None:
+			self.surface.set_colorkey(colorkey)
+		self.surface.convert_alpha()
+		self.len = (self.surface.get_width()/self.tile_width)*(self.surface.get_height()/self.tile_height)
+		
+		self.tiles = list()
+		for y in range(self.surface.get_height()/self.tile_height):
+			for x in range((self.surface.get_width()/self.tile_width)):
+				rect = pygame.Rect(x*self.tile_width,y*self.tile_height,self.tile_width,self.tile_height)
+				texture_data = pygame.image.tostring(self.surface.subsurface(rect), 'RGBA', True)
+				texture_id = glGenTextures(1)
+				glBindTexture(GL_TEXTURE_2D, texture_id)
+				
+				# Tell OpenGL how to scale images
+				glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST )
+				glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST )
+				
+				#for mip mapping
+				#glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
+				#glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR)
+
+				
+				# Tell OpenGL that data is aligned to byte boundries
+				glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
+				glTexImage2D( GL_TEXTURE_2D, 0,4, self.tile_width,self.tile_height,0,\
+				GL_RGBA,GL_UNSIGNED_BYTE, texture_data)
+				
+				#for mip mapping
+				#gluBuild2DMipmaps( GL_TEXTURE_2D,4, self.tile_width,self.tile_height,\
+				#GL_RGBA,GL_UNSIGNED_BYTE, texture_data)
+
+				self.tiles.append(texture_id)
+
+
+
+	def __del__(self):
+		for texture_id in self.tiles:
+			glDeleteTextures(texture_id)
+			
+
+	def __getitem__(self, key):
+		return self.tiles[key]
+			
+	def __len__(self):
+		return self.len