Para ello primero crearemos el archivo mapa.py en la raiz del proyecto.
# -*- coding: utf-8 -*- from xml.dom import minidom import base64 import gzip import StringIO from utilidades.imagen import * from utilidades.archivo import * class Mapa: LAYER_PISABLE = 0 LAYER_SUELO = 1 LAYER_OBJETOS = 2 LAYER_OBJETOS_SUPERPUESTOS = 3 LAYER_CIELO = 4 def __init__(self, nombre): self.nombre = nombre self.capas = [] # Cargamos el mapa en self.capas. self._cargar_mapa() # Inicializa los valores desde el xml. # Obtenemos un array unidimensional con todos los tilesets del mapa. self.tileset = cortar_tileset("data/imagenes/" + self.tileset, self.tam_tiles, True) #self.crear_mapa() # Extrae valores mapa desde XML. def _cargar_mapa(self): xmlMap = minidom.parse("data/mapas/" + self.nombre) nPrincipal = xmlMap.childNodes[0] # Tamaño mapa self.width = int(nPrincipal.attributes.get("width").value) self.height = int(nPrincipal.attributes.get("height").value) for i in range(len(nPrincipal.childNodes)): if nPrincipal.childNodes[i].nodeType == 1: if nPrincipal.childNodes[i].nodeName == "tileset": if nPrincipal.childNodes[i].attributes.get("name").value != "config": width = nPrincipal.childNodes[i].attributes.get("tilewidth").value height = nPrincipal.childNodes[i].attributes.get("tileheight").value nombre = nPrincipal.childNodes[i].childNodes[1].attributes.get("source").value nombre = extraer_nombre(nombre) if nPrincipal.childNodes[i].attributes.get("name").value == "tileset": self.tileset = nombre self.tam_tiles = (int(width), int(height)) if nPrincipal.childNodes[i].nodeName == "layer": layer = nPrincipal.childNodes[i].childNodes[1].childNodes[0].data.replace("\n", "").replace(" ", "") layer = self._decodificar(layer) # Decodifica la lista layer = self.convertir(layer, self.width) # Convierta en array bidimensional self.capas.append(layer) def _decodificar(self, cadena): ''' Decodifica y descomprime los datos de un mapa creado con el TileMap Editor ''' # Decodificar. cadena = base64.decodestring(cadena) # Descomprimir. copmressed_stream = StringIO.StringIO(cadena) gzipper = gzip.GzipFile(fileobj=copmressed_stream) cadena = gzipper.read() # Convertir. salida = [] for idx in xrange(0, len(cadena), 4): val = ord(str(cadena[idx])) | (ord(str(cadena[idx + 1])) << 8) | \ (ord(str(cadena[idx + 2])) << 16) | (ord(str(cadena[idx + 3])) << 24) salida.append(val) return salida # Convierte un array unidimensional en uno bidimensional. def convertir(self, lista, col): nueva = [] for i in range(0, len(lista), col): nueva.append(lista[i:i + col]) return nueva def dibujar(self, capa, dest, x, y): ''' Dibuja una capa del mapa en una surface ''' x_aux = x y_aux = y for f in range(self.height): for c in range(self.width): if self.capas[capa][f][c]: dest.blit(self.tileset[self.capas[capa][f][c]],(x_aux,y_aux)) x_aux = x_aux + self.tam_tiles[0] y_aux = y_aux + self.tam_tiles[1] x_aux = x
Si observáis el código tendréis bastante claro lo que hace, pero os indico más o menos su funcionamiento.
En self.capas guardamos un array [capa][fila][columna] con los datos leídos del archivo que nos generó el Tiled Map Editor.
En self.tileset tendremos un array unidimensional de las imagenes del tileset que usamos para crear el mapa.
Y en self.height y self.width tendremos el tamaño del mapa. En nuestro caso de 10 filas x 10 columnas.
El método _cargar_mapa hace todo lo que he comentado anteriormente. Va leyendo el archivo XML del mapa y obtiene los datos del mismo. Si editáis con un editor de textos el archivo del mapa mapa1.tmx veréis la estructura del mismo.
Por último el metodo dibujar, imprime una capa del mapa en la surface que se le indique.
La capa que se desea dibujar se especifica mediante estas "constantes":
LAYER_SUELO = 1
LAYER_OBJETOS = 2
LAYER_OBJETOS_SUPERPUESTOS = 3
LAYER_CIELO = 4
Como veréis al principio del archivo está la instrucción "from utilidades.archivo import *", pues bien deberemos crear ese archivo (archivo.py) en la ruta indicada "utilidades/".
import StringIO def extraer_nombre(ruta): ''' Extra el nombre de un archivo de una ruta. ''' a = -1 for i in range(len(ruta)): if ruta[i] == "/" or ruta[i] == "\\": a = i if a == -1: return ruta return ruta[a + 1:]
Acordaros de pones la entrada de los archivos en los __init__.py.
Ahora solo queda añadir lo necesario para mostrar nuestro mapa en el estado de juego que creamos llamado pantallastate.py.
El archivo quedará de la siguiente forma:
import pygame from pygame.locals import * from gamemanager.states import gamestate from utilidades.imagen import * from mapa import * class PantallaState(gamestate.GameState): def __init__(self, parent): self.parent = parent self.background = pygame.Surface(self.parent.screen.get_size()) self.background = self.background.convert() self.background.fill((0, 0, 0)) self.mapa = Mapa('mapa1.tmx') def start(self): print "GameState Pantalla Started" def cleanUp(self): print "GameState Pantalla Cleaned" pass def pause(self): print "GameState Pantalla Paused" pass def resume(self): print "GameState Pantalla Resumed" pass def handleEvents(self, events): for event in events: if event.type == pygame.KEYDOWN : if event.key == pygame.K_ESCAPE : self.parent.popState() def update(self): pass def draw(self): self.parent.screen.blit(self.background, (0,0)) self.mapa.dibujar(Mapa.LAYER_SUELO, self.parent.screen,0,0) self.mapa.dibujar(Mapa.LAYER_OBJETOS, self.parent.screen,0,0) self.mapa.dibujar(Mapa.LAYER_OBJETOS_SUPERPUESTOS, self.parent.screen,0,0) self.mapa.dibujar(Mapa.LAYER_CIELO, self.parent.screen,0,0)
Hemos añadido en el __init__ la instrucción:
self.mapa = Mapa('mapa1.tmx')
y posteriromente en el draw:
self.mapa.dibujar(Mapa.LAYER_SUELO, self.parent.screen,0,0) self.mapa.dibujar(Mapa.LAYER_OBJETOS, self.parent.screen,0,0) self.mapa.dibujar(Mapa.LAYER_OBJETOS_SUPERPUESTOS, self.parent.screen,0,0) self.mapa.dibujar(Mapa.LAYER_CIELO, self.parent.screen,0,0)
Una vez ejecutado el programa debería darnos este resultado:
No hay comentarios:
Publicar un comentario