16x16 Tileset lädt nicht korrekt

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
Source
User
Beiträge: 3
Registriert: Samstag 6. März 2010, 18:02

Hi, ich bin neu hier und auch relativ heut was Python und Pygame angeht.
Ich wollte zum üben ein kleines Spiel programmieren welches Pokemon ähnelt und habe mir dazu auch die entsprechenden Tiles geladen und daraus eine Map erstellt (mit diesem Map Editor).
Anfangs hatte ich, zwecks mangelnder Tiles, frei verfügbare geladen die 32x32 maßen.
Alles funktionierte reibungslos und nachdem ich die 16x16 Tiles hatte (andere fand ich von Pokemon nicht) baute ich eben auch daraus eine Map.
Nachdem laden war ich allerdings etwas verblüfft, denn scheinbar wird immer nur der oberste Layer geladen und Stücke der anderen, ich kanns mir nicht erklären, und hoffe das ihr das vllt könnt.

Zum auslesen der ersellten Map habe ich diesen Code gefunden und benutzt, ist eigentlich nur ein Parser für xml, da sämtliche Maps in XML Form abgespeichert werden:

Code: Alles auswählen

import sys, pygame
from pygame.locals import *

from pygame import Rect
from xml import sax

class Tileset:
    def __init__(self, file, tile_width, tile_height):
        image = pygame.image.load(file)
        
        if image.get_alpha() == None:
        	image.convert()
        else:
        	image.convert_alpha()
        
        if not image:
            print "Error creating new Tileset: file %s not found" % file
        
        self.tile_width  = tile_width
        self.tile_height = tile_height
        
        self.tiles = []
        for line in xrange(image.get_height() / self.tile_height):
            for column in xrange(image.get_width() / self.tile_width):
                rect = Rect(
                        column * self.tile_width,
                        line * self.tile_height,
                        self.tile_width,
                        self.tile_height 
                    )
                
            	tile = image.subsurface(rect)
            	
                self.tiles.append(tile)
    	
    def get_tile(self, gid):
        return self.tiles[gid]
	

class TMXHandler(sax.ContentHandler):
    def __init__(self):
        self.width  = 0
        self.height = 0
        
        self.tile_width  = 0
        self.tile_height = 0
        
        self.columns = 0
        self.lines   = 0
        
        self.properties = {}
        
        self.image   = None
        self.tileset = None
        
        self.tile_gids = {}

    def startElement(self, name, attrs):
        # get most general map informations and create a surface
        if name == 'map':
            self.columns 	= int(attrs.get('width', None))
            self.lines 		= int(attrs.get('height', None))
            
            self.tile_width  = int(attrs.get('tilewidth', None))
            self.tile_height = int(attrs.get('tileheight', None))
            
            self.width  = self.columns * self.tile_width
            self.height = self.lines * self.tile_height
            
            self.image = pygame.Surface((self.width, self.height))
            
            if self.image.get_alpha() == None:
            	self.image.convert()
            else:
            	self.image.convert_alpha()
        
        # create a tileset
        elif name == 'image':
            source = attrs.get('source', None)
            
            self.tileset = Tileset(source, self.tile_width, self.tile_height)
        
        # store additional properties.
        elif name == 'property':
            self.properties[attrs.get('name', None)] = attrs.get('value', None)
        
        # starting counting
        elif name == 'layer':
        	self._layer = attrs.get('name', None).strip()
        	
        	if self._layer not in self.tile_gids:
        		self.tile_gids[self._layer] = dict()
        	
        	self.line   = 0
        	self.column = 0
        
        # get information of each tile and put on the surface using the tileset
        elif name == 'tile':
            gid = int(attrs.get('gid', None)) - 1
            
            if gid < 0: 
            	gid = 0
            
            tile = self.tileset.get_tile(gid)
            pos  = (self.column * self.tile_width, self.line * self.tile_height)
            
            self.image.blit(tile, pos)
            
            self.tile_gids[self._layer][(self.column, self.line)] = int(gid)
            
            self.column += 1
            if(self.column >= self.columns):
                self.column = 0
                self.line  += 1

    # just for debugging
    def endDocument(self):
        print self.width, self.height, self.tile_width, self.tile_height
        print self.properties
        print self.image
        
und so wird er angewendet:

Code: Alles auswählen

    tmxhandler = TMXHandler()
    
    parser = sax.make_parser()
    parser.setContentHandler(tmxhandler)
    parser.parse("poke_map.tmx")
und so wird die Map auf den screen geblittet:

Code: Alles auswählen

screen.blit(tmxhandler.image, (0, 0))
Die Datei "poke_map.tmx" ist hier zu finden und das dazugehörige Tileset hier: http://img401.imageshack.us/img401/7315 ... dvance.png, die funktionierende Map (die auf 32x32 Tiles basiert) kann ich bei Fragen natürlich sofort nachreichen, sowie die dazugehörigen Tilesets.

Aber schonmal vorweg die Bilder:
So sollte es aussehen:
Bild
und so sieht es aus:
Bild
Source
User
Beiträge: 3
Registriert: Samstag 6. März 2010, 18:02

Keiner auch nur 'ne Idee? :o
Source
User
Beiträge: 3
Registriert: Samstag 6. März 2010, 18:02

Lösung war sehr simpel:
Beim Pokemon Tileset existiert anfangs kein leeres Tile wie bei meinem anderen (welches wohl transparent ist), somit musste man lediglich diesen Codeteil ändern

Code: Alles auswählen

self.image.blit(tile, pos)
in

Code: Alles auswählen

if gid > 0:
            	self.image.blit(tile, pos)
somit werden die unteren layer nicht immer wieder mit leeren tiles überschrieben.
Antworten