Package pilas :: Package actores :: Module mapatiled
[hide private]
[frames] | no frames]

Source Code for Module pilas.actores.mapatiled

  1  # -*- encoding: utf-8 -*- 
  2  # Pilas engine - A video game framework. 
  3  # 
  4  # Copyright 2010 - Hugo Ruscitti 
  5  # License: LGPLv3 (see http://www.gnu.org/licenses/lgpl.html) 
  6  # 
  7  # Website - http://www.pilas-engine.com.ar 
  8   
  9  import pilas 
 10  from pilas.actores import Mapa 
 11  from xml.dom import minidom 
 12   
13 -class MapaTiled(Mapa):
14 """Representa mapas creados a partir de imagenes mas pequeñas. 15 16 Este actor te permite crear escenarios tipo ``tiles``, a partir 17 de archivos .tmx, creados con el programa **tiled** (ver http://www.mapeditor.org). 18 19 Por ejemplo, para crear un mapa desde un archivo del programa 20 **tiled** puedes escribir: 21 22 >>> mapa = pilas.actores.MapaTiled('untitled2.tmx') 23 24 Tiled trabaja con capas, así que cuando pilas carga las capas las interpreta 25 de la siguiente manera: 26 27 - La capa 0 define los bloques no sólidos, generalmente fondos o decoración. 28 - La capa 1 define bloques sólidos, útiles para hacer suelos o paredes. 29 - Las siguientes capas solo se almacenan, pero no se dibujan. Se pueden acceder con ``mapa.capas``. 30 """ 31
32 - def __init__(self, ruta_mapa, x=0, y=0, restitucion=0.56):
33 ruta_mapa = pilas.utils.obtener_ruta_al_recurso(ruta_mapa) 34 self._cargar_datos_basicos_del_mapa(ruta_mapa) 35 Mapa.__init__(self, self.grilla, x=x, y=y, filas=self.filas, columnas=self.columnas) 36 self._dibujar_mapa(ruta_mapa)
37
38 - def cuadro_ancho(self):
39 """Retorna el ancho de un bloque del mapa""" 40 return self.ancho_cuadro
41
42 - def cuadro_alto(self):
43 """Retorna el alto de un bloque del mapa""" 44 return self.alto_cuadro
45
46 - def _cargar_datos_basicos_del_mapa(self, archivo):
47 nodo = makeRootNode(archivo) 48 nodo_mapa = nodo.getChild('map') 49 nodo_tileset = nodo_mapa.getChild('tileset') 50 51 self.columnas = int(nodo_mapa.getAttributeValue('width')) 52 self.filas = int(nodo_mapa.getAttributeValue('height')) 53 54 self.ancho_imagen = int(nodo_tileset.getChild('image').getAttributeValue('width')) 55 self.alto_imagen = int(nodo_tileset.getChild('image').getAttributeValue('height')) 56 57 self.ancho_cuadro = int(nodo_tileset.getAttributeValue('tilewidth')) 58 self.alto_cuadro = int(nodo_tileset.getAttributeValue('tileheight')) 59 60 self._ruta = nodo_tileset.getChild('image').getAttributeValue('source') 61 self._ruta = pilas.utils.obtener_ruta_al_recurso(self._ruta) 62 63 self.grilla = pilas.imagenes.cargar_grilla(self._ruta, 64 self.ancho_imagen / self.ancho_cuadro, 65 self.alto_imagen / self.alto_cuadro)
66
67 - def _dibujar_mapa(self, archivo):
68 nodo = makeRootNode(archivo) 69 layers = nodo.getChild('map').getChildren('layer') 70 71 if len(layers) == 0: 72 raise Exception("Debe tener al menos una capa (layer).") 73 74 self.capas = {} 75 76 # La capa 0 (inferior) define los bloques no-solidos. 77 bloques = self._pintar_bloques(layers[0], solidos=False) 78 self.capas[0] = bloques 79 80 # La capa 1 define bloques solidos. 81 if len(layers) > 1: 82 bloques = self._pintar_bloques(layers[1], solidos=True) 83 self.capas[1] = bloques 84 85 # El resto de las capas solo definen matrices para acceder mediante 86 # el atributo 'capas', no se imprimen automaticamente. 87 for (indice, layer) in enumerate(layers[2:]): 88 self.capas[indice + 2] = self._convertir_capa_en_bloques_enteros(layer)
89
90 - def _pintar_bloques(self, capa, solidos):
91 """Genera actores que representan los bloques del escenario. 92 93 Retorna una lista de los bloques convertidos a numeros. 94 """ 95 96 # Convierte todo el mapa en una matriz de numeros. 97 bloques = self._convertir_capa_en_bloques_enteros(capa) 98 99 for (y, fila) in enumerate(bloques): 100 for (x, bloque) in enumerate(fila): 101 if bloque: 102 self.pintar_bloque(y, x, bloque -1, solidos) 103 104 return bloques
105
107 datos = capa.getChild('data').getData() 108 return [[int(x) for x in x.split(',') if x] for x in datos.split()]
109 110 111
112 -class XmlNode:
113 """Representa un nodo XML.""" 114
115 - def __init__(self, domElement):
116 """Construstor del nodo desde un elemento dom. 117 118 :param domElement: Elemento de DOM a convertir. 119 """ 120 self.elem = domElement
121
122 - def getData(self):
123 """Extrae datos desde un nodo del DOM.""" 124 for child in self.elem.childNodes: 125 if child.nodeType == child.TEXT_NODE: 126 return str(child.data) 127 return None
128
129 - def getAttributeValue(self, name):
130 """Returns the value of the attribute having the specified name.""" 131 return str(self.elem.attributes[name].value)
132
133 - def getChild(self, tag):
134 """Retorna el primer nodo hijo que contenga el tag especificado.""" 135 return XmlNode(self.elem.getElementsByTagName(tag)[0])
136
137 - def getChildren(self, tag):
138 """Retorna una lista de todos los nodos hijos que tienen el tag especificado.""" 139 return [XmlNode(x) for x in self.elem.getElementsByTagName(tag)]
140
141 -def makeRootNode(xmlFileName):
142 """Genera un nodo XML dado un archivo. 143 144 :param xmlFileName: El nombre del archivo .xml""" 145 return XmlNode(minidom.parse(xmlFileName))
146