all repos — Legends-RPG @ 9e643337e6380fdb1ab32813bf8848ad7e7219c8

A fantasy mini-RPG built with Python and Pygame.

upgrade to python3 and new pytmx
Marco Andronaco andronacomarco@gmail.com
Tue, 23 Aug 2022 17:08:44 +0200
commit

9e643337e6380fdb1ab32813bf8848ad7e7219c8

parent

91a9949cc8ed9a2054c3b1ab8efe46678be0fcf4

M .gitignore.gitignore

@@ -40,3 +40,5 @@ # Mr Developer

.mr.developer.cfg .project .pydevproject + +venv
A .vscode/launch.json

@@ -0,0 +1,16 @@

+{ + // Usare IntelliSense per informazioni sui possibili attributi. + // Al passaggio del mouse vengono visualizzate le descrizioni degli attributi esistenti. + // Per altre informazioni, visitare: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python: Run Game", + "type": "python", + "request": "launch", + "program": "The_Stolen_Crown.py", + "console": "integratedTerminal", + "justMyCode": true + } + ] +}
M data/battlegui.pydata/battlegui.py

@@ -270,7 +270,7 @@ Select what action the player should take.

""" self.pos_list = self.make_select_action_pos_list() if self.index > (len(self.pos_list) - 1): - print self.pos_list, self.index + print(self.pos_list, self.index) self.rect.topleft = self.pos_list[self.index] self.check_input(keys)
M data/components/person.pydata/components/person.py

@@ -1,5 +1,4 @@

from __future__ import division -from itertools import izip import math, random, copy, sys import pygame as pg from .. import setup, observer

@@ -64,7 +63,7 @@ for column in range(4):

image_list.append( self.get_image(column*32, row*32, 32, 32, sheet)) - for key, image in izip(image_keys, image_list): + for key, image in zip(image_keys, image_list): image_dict[key] = image return image_dict
M data/menugui.pydata/menugui.py

@@ -237,7 +237,7 @@ text = "{}{}: {}".format(stat[0].upper(),

stat[1:], self.player_stats[stat]) elif stat == 'Attack Power': - text = "{}: {}".format(stat, self.get_attack_power()) + text = "{}: {}".format(stat, self.get_attack_power()) elif stat == 'Defense Power': text = "{}: {}".format(stat, self.get_defense_power()) elif stat == 'gold':
D data/pytmx/__init__.py

@@ -1,8 +0,0 @@

-from data.pytmx.tmxloader import load_pygame, load_tmx -from data.pytmx.utils import buildDistributionRects -from data.pytmx.pytmx import * - -__version__ = '2.16.4' -__author__ = 'bitcraft' -__author_email__ = 'leif.theden@gmail.com' -__description__ = 'Map loader for TMX Files - Python 2.7'
D data/pytmx/constants.py

@@ -1,10 +0,0 @@

-# internal flags -TRANS_FLIPX = 1 -TRANS_FLIPY = 2 -TRANS_ROT = 4 - -# Tiled gid flags -GID_TRANS_FLIPX = 1<<31 -GID_TRANS_FLIPY = 1<<30 -GID_TRANS_ROT = 1<<29 -
D data/pytmx/pytmx.py

@@ -1,679 +0,0 @@

-from itertools import chain, product -from xml.etree import ElementTree - -from .utils import decode_gid, types, parse_properties, read_points - - -__all__ = ['TiledMap', 'TiledTileset', 'TiledLayer', 'TiledObject', 'TiledObjectGroup', 'TiledImageLayer'] - - -class TiledElement(object): - def set_properties(self, node): - """ - read the xml attributes and tiled "properties" from a xml node and fill - in the values into the object's dictionary. Names will be checked to - make sure that they do not conflict with reserved names. - """ - - # set the attributes reserved for tiled - [setattr(self, k, types[str(k)](v)) for (k, v) in node.items()] - - # set the attributes that are derived from tiled 'properties' - for k, v in parse_properties(node).items(): - if k in self.reserved: - msg = "{0} \"{1}\" has a property called \"{2}\"" - print msg.format(self.__class__.__name__, self.name, k, self.__class__.__name__) - msg = "This name is reserved for {0} objects and cannot be used." - print msg.format(self.__class__.__name__) - print "Please change the name in Tiled and try again." - raise ValueError - setattr(self, k, types[str(k)](v)) - - -class TiledMap(TiledElement): - """ - Contains the tile layers, tile images, object groups, and objects from a - Tiled TMX map. - """ - - reserved = "visible version orientation width height tilewidth tileheight properties tileset layer objectgroup".split() - - def __init__(self, filename=None): - from collections import defaultdict - - TiledElement.__init__(self) - self.tilesets = [] # list of TiledTileset objects - self.tilelayers = [] # list of TiledLayer objects - self.imagelayers = [] # list of TiledImageLayer objects - self.objectgroups = [] # list of TiledObjectGroup objects - self.all_layers = [] # list of all layers in proper order - self.tile_properties = {} # dict of tiles that have metadata - self.filename = filename - - self.layernames = {} - - # only used tiles are actually loaded, so there will be a difference - # between the GIDs in the Tile map data (tmx) and the data in this - # class and the layers. This dictionary keeps track of that difference. - self.gidmap = defaultdict(list) - - # should be filled in by a loader function - self.images = [] - - # defaults from the TMX specification - self.version = 0.0 - self.orientation = None - self.width = 0 # width of map in tiles - self.height = 0 # height of map in tiles - self.tilewidth = 0 # width of a tile in pixels - self.tileheight = 0 # height of a tile in pixels - self.background_color = None - - self.imagemap = {} # mapping of gid and trans flags to real gids - self.maxgid = 1 - - if filename: - self.load() - - def __repr__(self): - return "<{0}: \"{1}\">".format(self.__class__.__name__, self.filename) - - def getTileImage(self, x, y, layer): - """ - return the tile image for this location - x and y must be integers and are in tile coordinates, not pixel - - return value will be 0 if there is no tile with that location. - """ - - try: - x, y, layer = map(int, (x, y, layer)) - except TypeError: - msg = "Tile indexes/layers must be specified as integers." - print msg - raise TypeError - - try: - assert (x >= 0 and y >= 0) - except AssertionError: - raise ValueError - - try: - gid = self.tilelayers[layer].data[y][x] - except IndexError: - msg = "Coords: ({0},{1}) in layer {2} is not valid." - print msg.format(x, y, layer) - raise ValueError - - return self.getTileImageByGid(gid) - - def getTileImageByGid(self, gid): - try: - assert (gid >= 0) - return self.images[gid] - except (IndexError, ValueError, AssertionError): - msg = "Invalid GID specified: {}" - print msg.format(gid) - raise ValueError - except TypeError: - msg = "GID must be specified as integer: {}" - print msg.format(gid) - raise TypeError - - def getTileGID(self, x, y, layer): - """ - return GID of a tile in this location - x and y must be integers and are in tile coordinates, not pixel - """ - - try: - return self.tilelayers[int(layer)].data[int(y)][int(x)] - except (IndexError, ValueError): - msg = "Coords: ({0},{1}) in layer {2} is invalid" - raise Exception, msg.format(x, y, layer) - - def getDrawOrder(self): - """ - return a list of objects in the order that they should be drawn - this will also exclude any layers that are not set to visible - - may be useful if you have objects and want to control rendering - from tiled - """ - - raise NotImplementedError - - def getTileImages(self, r, layer): - """ - return a group of tiles in an area - expects a pygame rect or rect-like list/tuple - - useful if you don't want to repeatedly call getTileImage - """ - - raise NotImplementedError - - def getObjects(self): - """ - Return iterator of all the objects associated with this map - """ - - return chain(*(i for i in self.objectgroups)) - - def getTileProperties(self, (x, y, layer)): - """ - return the properties for the tile, if any - x and y must be integers and are in tile coordinates, not pixel - - returns a dict of there are properties, otherwise will be None - """ - - try: - gid = self.tilelayers[int(layer)].data[int(y)][int(x)] - except (IndexError, ValueError): - msg = "Coords: ({0},{1}) in layer {2} is invalid." - raise Exception, msg.format(x, y, layer) - - else: - try: - return self.tile_properties[gid] - except (IndexError, ValueError): - msg = "Coords: ({0},{1}) in layer {2} has invalid GID: {3}" - raise Exception, msg.format(x, y, layer, gid) - except KeyError: - return None - - def getLayerData(self, layer): - """ - Return the data for a layer. - - Data is an array of arrays. - - >>> pos = data[y][x] - """ - - try: - return self.tilelayers[layer].data - except IndexError: - msg = "Layer {0} does not exist." - raise ValueError, msg.format(layer) - - def getTileLocation(self, gid): - # experimental way to find locations of a tile by the GID - - p = product(xrange(self.width), - xrange(self.height), - xrange(len(self.tilelayers))) - - return [(x, y, l) for (x, y, l) in p - if self.tilelayers[l].data[y][x] == gid] - - def getTilePropertiesByGID(self, gid): - try: - return self.tile_properties[gid] - except KeyError: - return None - - def setTileProperties(self, gid, d): - """ - set the properties of a tile by GID. - must use a standard python dict as d - """ - - try: - self.tile_properties[gid] = d - except KeyError: - msg = "GID #{0} does not exist." - raise ValueError, msg.format(gid) - - def getTilePropertiesByLayer(self, layer): - """ - Return a list of tile properties (dict) in use in this tile layer. - """ - - try: - layer = int(layer) - except: - msg = "Layer must be an integer. Got {0} instead." - raise ValueError, msg.format(type(layer)) - - p = product(range(self.width), range(self.height)) - layergids = set(self.tilelayers[layer].data[y][x] for x, y in p) - - props = [] - for gid in layergids: - try: - props.append((gid, self.tile_properties[gid])) - except: - continue - - return props - - def register_gid(self, real_gid, flags=0): - """ - used to manage the mapping of GID between the tmx data and the internal - data. - - number returned is gid used internally - """ - - if real_gid: - try: - return self.imagemap[(real_gid, flags)][0] - except KeyError: - # this tile has not been encountered before, or it has been - # transformed in some way. make a new GID for it. - gid = self.maxgid - self.maxgid += 1 - self.imagemap[(real_gid, flags)] = (gid, flags) - self.gidmap[real_gid].append((gid, flags)) - return gid - else: - return 0 - - def map_gid(self, real_gid): - """ - used to lookup a GID read from a TMX file's data - """ - - try: - return self.gidmap[int(real_gid)] - except KeyError: - return None - except TypeError: - msg = "GIDs must be an integer" - raise TypeError, msg - - def loadTileImages(self, filename): - raise NotImplementedError - - def load(self): - """ - parse a map node from a tiled tmx file - """ - etree = ElementTree.parse(self.filename).getroot() - self.set_properties(etree) - - # initialize the gid mapping - self.imagemap[(0, 0)] = 0 - - self.background_color = etree.get('backgroundcolor', self.background_color) - - # *** do not change this load order! gid mapping errors will occur if changed *** - for node in etree.findall('layer'): - self.addTileLayer(TiledLayer(self, node)) - - for node in etree.findall('imagelayer'): - self.addImageLayer(TiledImageLayer(self, node)) - - for node in etree.findall('objectgroup'): - self.objectgroups.append(TiledObjectGroup(self, node)) - - for node in etree.findall('tileset'): - self.tilesets.append(TiledTileset(self, node)) - - # "tile objects", objects with a GID, have need to have their - # attributes set after the tileset is loaded, so this step must be performed last - for o in self.objects: - p = self.getTilePropertiesByGID(o.gid) - if p: - o.__dict__.update(p) - - def addTileLayer(self, layer): - """ - Add a TiledLayer layer object to the map. - """ - - if not isinstance(layer, TiledLayer): - msg = "Layer must be an TiledLayer object. Got {0} instead." - raise ValueError, msg.format(type(layer)) - - self.tilelayers.append(layer) - self.all_layers.append(layer) - self.layernames[layer.name] = layer - - def addImageLayer(self, layer): - """ - Add a TiledImageLayer layer object to the map. - """ - - if not isinstance(layer, TiledImageLayer): - msg = "Layer must be an TiledImageLayer object. Got {0} instead." - raise ValueError, msg.format(type(layer)) - - self.imagelayers.append(layer) - self.all_layers.append(layer) - self.layernames[layer.name] = layer - - def getTileLayerByName(self, name): - """ - Return a TiledLayer object with the name. - This is case-sensitive. - """ - - try: - return self.layernames[name] - except KeyError: - msg = "Layer \"{0}\" not found." - raise ValueError, msg.format(name) - - def getTileLayerOrder(self): - """ - Return a list of the map's layers in drawing order. - """ - - return list(self.tilelayers) - - @property - def visibleTileLayers(self): - """ - Returns a list of TileLayer objects that are set 'visible'. - - Layers have their visibility set in Tiled. Optionally, you can over- - ride the Tiled visibility by creating a property named 'visible'. - """ - - return [layer for layer in self.tilelayers if layer.visible] - - @property - def objects(self): - """ - Return iterator of all the objects associated with this map - """ - return chain(*self.objectgroups) - - @property - def visibleLayers(self): - """ - Returns a generator of [Image/Tile]Layer objects that are set 'visible'. - - Layers have their visibility set in Tiled. - """ - return (l for l in self.all_layers if l.visible) - - -class TiledTileset(TiledElement): - reserved = "visible firstgid source name tilewidth tileheight spacing margin image tile properties".split() - - def __init__(self, parent, node): - TiledElement.__init__(self) - self.parent = parent - - # defaults from the specification - self.firstgid = 0 - self.source = None - self.name = None - self.tilewidth = 0 - self.tileheight = 0 - self.spacing = 0 - self.margin = 0 - self.tiles = {} - self.trans = None - self.width = 0 - self.height = 0 - - self.parse(node) - - def __repr__(self): - return "<{0}: \"{1}\">".format(self.__class__.__name__, self.name) - - def parse(self, node): - """ - parse a tileset element and return a tileset object and properties for - tiles as a dict - - a bit of mangling is done here so that tilesets that have external - TSX files appear the same as those that don't - """ - import os - - # if true, then node references an external tileset - source = node.get('source', False) - if source: - if source[-4:].lower() == ".tsx": - - # external tilesets don't save this, store it for later - self.firstgid = int(node.get('firstgid')) - - # we need to mangle the path - tiled stores relative paths - dirname = os.path.dirname(self.parent.filename) - path = os.path.abspath(os.path.join(dirname, source)) - try: - node = ElementTree.parse(path).getroot() - except IOError: - msg = "Cannot load external tileset: {0}" - raise Exception, msg.format(path) - - else: - msg = "Found external tileset, but cannot handle type: {0}" - raise Exception, msg.format(self.source) - - self.set_properties(node) - - # since tile objects [probably] don't have a lot of metadata, - # we store it separately in the parent (a TiledMap instance) - for child in node.getiterator('tile'): - real_gid = int(child.get("id")) - p = parse_properties(child) - p['width'] = self.tilewidth - p['height'] = self.tileheight - for gid, flags in self.parent.map_gid(real_gid + self.firstgid): - self.parent.setTileProperties(gid, p) - - image_node = node.find('image') - self.source = image_node.get('source') - self.trans = image_node.get("trans", None) - - -class TiledLayer(TiledElement): - reserved = "visible name x y width height opacity properties data".split() - - def __init__(self, parent, node): - TiledElement.__init__(self) - self.parent = parent - self.data = [] - - # defaults from the specification - self.name = None - self.opacity = 1.0 - self.visible = True - - self.parse(node) - - def __iter__(self): - return self.iter_tiles() - - def iter_tiles(self): - for y, x in product(range(self.height), range(self.width)): - yield x, y, self.data[y][x] - - def __repr__(self): - return "<{0}: \"{1}\">".format(self.__class__.__name__, self.name) - - def parse(self, node): - """ - parse a layer element - """ - from data.pytmx.utils import group - from itertools import product, imap - from struct import unpack - import array - - self.set_properties(node) - - data = None - next_gid = None - - data_node = node.find('data') - - encoding = data_node.get("encoding", None) - if encoding == "base64": - from base64 import decodestring - - data = decodestring(data_node.text.strip()) - - elif encoding == "csv": - next_gid = imap(int, "".join( - line.strip() for line in data_node.text.strip() - ).split(",")) - - elif encoding: - msg = "TMX encoding type: {0} is not supported." - raise Exception, msg.format(encoding) - - compression = data_node.get("compression", None) - if compression == "gzip": - from StringIO import StringIO - import gzip - - fh = gzip.GzipFile(fileobj=StringIO(data)) - data = fh.read() - fh.close() - - elif compression == "zlib": - import zlib - - data = zlib.decompress(data) - - elif compression: - msg = "TMX compression type: {0} is not supported." - raise Exception, msg.format(str(attr["compression"])) - - # if data is None, then it was not decoded or decompressed, so - # we assume here that it is going to be a bunch of tile elements - # TODO: this will probably raise an exception if there are no tiles - if encoding == next_gid is None: - def get_children(parent): - for child in parent.findall('tile'): - yield int(child.get('gid')) - - next_gid = get_children(data_node) - - elif data: - # data is a list of gids. cast as 32-bit ints to format properly - # create iterator to efficiently parse data - next_gid = imap(lambda i: unpack("<L", "".join(i))[0], group(data, 4)) - - # using bytes here limits the layer to 256 unique tiles - # may be a limitation for very detailed maps, but most maps are not - # so detailed. - [self.data.append(array.array("H")) for i in xrange(self.height)] - - for (y, x) in product(xrange(self.height), xrange(self.width)): - self.data[y].append(self.parent.register_gid(*decode_gid(next(next_gid)))) - - -class TiledObjectGroup(TiledElement, list): - """ - Stores TiledObjects. Supports any operation of a normal list. - """ - reserved = "visible name color x y width height opacity object properties".split() - - def __init__(self, parent, node): - TiledElement.__init__(self) - self.parent = parent - - # defaults from the specification - self.name = None - self.color = None - self.opacity = 1 - self.visible = 1 - self.parse(node) - - def __repr__(self): - return "<{0}: \"{1}\">".format(self.__class__.__name__, self.name) - - def parse(self, node): - """ - parse a objectgroup element and return a object group - """ - - self.set_properties(node) - - for child in node.findall('object'): - o = TiledObject(self.parent, child) - self.append(o) - - -class TiledObject(TiledElement): - reserved = "visible name type x y width height gid properties polygon polyline image".split() - - def __init__(self, parent, node): - TiledElement.__init__(self) - self.parent = parent - - # defaults from the specification - self.name = None - self.type = None - self.x = 0 - self.y = 0 - self.width = 0 - self.height = 0 - self.rotation = 0 - self.gid = 0 - self.visible = 1 - - self.parse(node) - - def __repr__(self): - return "<{0}: \"{1}\">".format(self.__class__.__name__, self.name) - - def parse(self, node): - self.set_properties(node) - - # correctly handle "tile objects" (object with gid set) - if self.gid: - self.gid = self.parent.register_gid(self.gid) - - points = None - - polygon = node.find('polygon') - if polygon is not None: - points = read_points(polygon.get('points')) - self.closed = True - - polyline = node.find('polyline') - if polyline is not None: - points = read_points(polyline.get('points')) - self.closed = False - - if points: - x1 = x2 = y1 = y2 = 0 - for x, y in points: - if x < x1: x1 = x - if x > x2: x2 = x - if y < y1: y1 = y - if y > y2: y2 = y - self.width = abs(x1) + abs(x2) - self.height = abs(y1) + abs(y2) - self.points = tuple([(i[0] + self.x, i[1] + self.y) for i in points]) - -class TiledImageLayer(TiledElement): - reserved = "visible source name width height opacity visible".split() - - def __init__(self, parent, node): - TiledElement.__init__(self) - self.parent = parent - self.source = None - self.trans = None - - # unify the structure of layers - self.gid = 0 - - # defaults from the specification - self.name = None - self.opacity = 1 - self.visible = 1 - - self.parse(node) - - def parse(self, node): - self.set_properties(node) - - self.name = node.get('name', None) - self.opacity = node.get('opacity', self.opacity) - self.visible = node.get('visible', self.visible) - - image_node = node.find('image') - self.source = image_node.get('source') - self.trans = image_node.get('trans', None)
D data/pytmx/tmxloader.py

@@ -1,196 +0,0 @@

-import itertools -import os - -import pygame - -from data.pytmx import pytmx -from .constants import * - - -__all__ = ['load_pygame', 'load_tmx'] - - -def handle_transformation(tile, flags): - if flags: - fx = flags & TRANS_FLIPX == TRANS_FLIPX - fy = flags & TRANS_FLIPY == TRANS_FLIPY - r = flags & TRANS_ROT == TRANS_ROT - - if r: - # not sure why the flip is required...but it is. - newtile = pygame.transform.rotate(tile, 270) - newtile = pygame.transform.flip(newtile, 1, 0) - - if fx or fy: - newtile = pygame.transform.flip(newtile, fx, fy) - - elif fx or fy: - newtile = pygame.transform.flip(tile, fx, fy) - - return newtile - - else: - return tile - - -def smart_convert(original, colorkey, force_colorkey, pixelalpha): - """ - this method does several tests on a surface to determine the optimal - flags and pixel format for each tile surface. - - this is done for the best rendering speeds and removes the need to - convert() the images on your own - """ - tile_size = original.get_size() - - # count the number of pixels in the tile that are not transparent - px = pygame.mask.from_surface(original).count() - - # there are no transparent pixels in the image - if px == tile_size[0] * tile_size[1]: - tile = original.convert() - - # there are transparent pixels, and set to force a colorkey - elif force_colorkey: - tile = pygame.Surface(tile_size) - tile.fill(force_colorkey) - tile.blit(original, (0, 0)) - tile.set_colorkey(force_colorkey, pygame.RLEACCEL) - - # there are transparent pixels, and tiled set a colorkey - elif colorkey: - tile = original.convert() - tile.set_colorkey(colorkey, pygame.RLEACCEL) - - # there are transparent pixels, and set for perpixel alpha - elif pixelalpha: - tile = original.convert_alpha() - - # there are transparent pixels, and we won't handle them - else: - tile = original.convert() - - return tile - - -def _load_images_pygame(tmxdata, mapping, *args, **kwargs): - """ - Utility function to load images. - - - due to the way the tiles are loaded, they will be in the same pixel format - as the display when it is loaded. take this into consideration if you - intend to support different screen pixel formats. - - by default, the images will not have per-pixel alphas. this can be - changed by including "pixelalpha=True" in the keywords. this will result - in much slower blitting speeds. - - if the tileset's image has colorkey transparency set in Tiled, the loader - will return images that have their transparency already set. using a - tileset with colorkey transparency will greatly increase the speed of - rendering the map. - - optionally, you can force the loader to strip the alpha channel of the - tileset image and to fill in the missing areas with a color, then use that - new color as a colorkey. the resulting tiles will render much faster, but - will not preserve the transparency of the tile if it uses partial - transparency (which you shouldn't be doing anyway, this is SDL). - - TL;DR: - Don't attempt to convert() or convert_alpha() the individual tiles. It is - already done for you. - """ - - pixelalpha = kwargs.get("pixelalpha", False) - force_colorkey = kwargs.get("force_colorkey", False) - - if force_colorkey: - pixelalpha = True - - if force_colorkey: - try: - force_colorkey = pygame.Color(*force_colorkey) - except: - msg = 'Cannot understand color: {0}' - print msg.format(force_colorkey) - raise ValueError - - # change background color into something nice - if tmxdata.background_color: - tmxdata.background_color = pygame.Color(tmxdata.background_color) - - # initialize the array of images - tmxdata.images = [0] * tmxdata.maxgid - - for ts in tmxdata.tilesets: - path = os.path.join(os.path.dirname(tmxdata.filename), ts.source) - image = pygame.image.load(path) - w, h = image.get_size() - - # margins and spacing - tilewidth = ts.tilewidth + ts.spacing - tileheight = ts.tileheight + ts.spacing - tile_size = ts.tilewidth, ts.tileheight - - # some tileset images may be slightly larger than the tile area - # ie: may include a banner, copyright, ect. this compensates for that - width = int((((w - ts.margin * 2 + ts.spacing) / tilewidth) * tilewidth) - ts.spacing) - height = int((((h - ts.margin * 2 + ts.spacing) / tileheight) * tileheight) - ts.spacing) - - # trim off any pixels on the right side that isn't a tile - # this happens if extra graphics are included on the left, but they are not actually part of the tileset - width -= (w - ts.margin) % tilewidth - - # using product avoids the overhead of nested loops - p = itertools.product(xrange(ts.margin, height + ts.margin, tileheight), - xrange(ts.margin, width + ts.margin, tilewidth)) - - colorkey = getattr(ts, 'trans', None) - if colorkey: - colorkey = pygame.Color('#{0}'.format(colorkey)) - - for real_gid, (y, x) in enumerate(p, ts.firstgid): - if x + ts.tilewidth-ts.spacing > width: - continue - - gids = tmxdata.map_gid(real_gid) - - if gids: - original = image.subsurface(((x, y), tile_size)) - - for gid, flags in gids: - tile = handle_transformation(original, flags) - tile = smart_convert(tile, colorkey, force_colorkey, pixelalpha) - tmxdata.images[gid] = tile - - # load image layer images - for layer in tmxdata.all_layers: - if isinstance(layer, pytmx.TiledImageLayer): - colorkey = getattr(layer, 'trans', None) - if colorkey: - colorkey = pygame.Color("#{0}".format(colorkey)) - - source = getattr(layer, 'source', None) - if source: - real_gid = len(tmxdata.images) - gid = tmxdata.register_gid(real_gid) - layer.gid = gid - path = os.path.join(os.path.dirname(tmxdata.filename), source) - image = pygame.image.load(path) - image = smart_convert(image, colorkey, force_colorkey, pixelalpha) - tmxdata.images.append(image) - - -def load_pygame(filename, *args, **kwargs): - """ - PYGAME USERS: Use me. - - Load a TMX file, load the images, and return a TiledMap class that is ready to use. - """ - tmxdata = pytmx.TiledMap(filename) - _load_images_pygame(tmxdata, None, *args, **kwargs) - return tmxdata - - -load_tmx = pytmx.TiledMap
D data/pytmx/utils.py

@@ -1,244 +0,0 @@

-from itertools import tee, islice, izip, product -from collections import defaultdict - -from pygame import Rect - -from .constants import * - - -def read_points(text): - return [ tuple(map(lambda x: int(x), i.split(','))) - for i in text.split() ] - - -def parse_properties(node): - """ - parse a node and return a dict that represents a tiled "property" - """ - - # the "properties" from tiled's tmx have an annoying quality that "name" - # and "value" is included. here we mangle it to get that junk out. - - d = {} - - for child in node.findall('properties'): - for subnode in child.findall('property'): - d[subnode.get('name')] = subnode.get('value') - - return d - - -def decode_gid(raw_gid): - # gids are encoded with extra information - # as of 0.7.0 it determines if the tile should be flipped when rendered - # as of 0.8.0 bit 30 determines if GID is rotated - - flags = 0 - if raw_gid & GID_TRANS_FLIPX == GID_TRANS_FLIPX: flags += TRANS_FLIPX - if raw_gid & GID_TRANS_FLIPY == GID_TRANS_FLIPY: flags += TRANS_FLIPY - if raw_gid & GID_TRANS_ROT == GID_TRANS_ROT: flags += TRANS_ROT - gid = raw_gid & ~(GID_TRANS_FLIPX | GID_TRANS_FLIPY | GID_TRANS_ROT) - - return gid, flags - - -def handle_bool(text): - # properly convert strings to a bool - try: - return bool(int(text)) - except: - pass - - try: - text = str(text).lower() - if text == "true": return True - if text == "yes": return True - if text == "false": return False - if text == "no": return False - except: - pass - - raise ValueError - - -# used to change the unicode string returned from xml to proper python -# variable types. -types = defaultdict(lambda: str) -types.update({ - "version": float, - "orientation": str, - "width": int, - "height": int, - "tilewidth": int, - "tileheight": int, - "firstgid": int, - "source": str, - "name": str, - "spacing": int, - "margin": int, - "trans": str, - "id": int, - "opacity": float, - "visible": handle_bool, - "encoding": str, - "compression": str, - "gid": int, - "type": str, - "x": int, - "y": int, - "value": str, -}) - - -def pairwise(iterable): - # return a list as a sequence of pairs - a, b = tee(iterable) - next(b, None) - return izip(a, b) - - -def group(l, n): - # return a list as a sequence of n tuples - return izip(*(islice(l, i, None, n) for i in xrange(n))) - - -def buildDistributionRects(tmxmap, layer, tileset=None, real_gid=None): - """ - generate a set of non-overlapping rects that represents the distribution - of the specified gid. - - useful for generating rects for use in collision detection - """ - - if isinstance(tileset, int): - try: - tileset = tmxmap.tilesets[tileset] - except IndexError: - msg = "Tileset #{0} not found in map {1}." - raise IndexError, msg.format(tileset, tmxmap) - - elif isinstance(tileset, str): - try: - tileset = [ t for t in tmxmap.tilesets if t.name == tileset ].pop() - except IndexError: - msg = "Tileset \"{0}\" not found in map {1}." - raise ValueError, msg.format(tileset, tmxmap) - - elif tileset: - msg = "Tileset must be either a int or string. got: {0}" - raise ValueError, msg.format(type(tileset)) - - gid = None - if real_gid: - try: - gid, flags = tmxmap.map_gid(real_gid)[0] - except IndexError: - msg = "GID #{0} not found" - raise ValueError, msg.format(real_gid) - - if isinstance(layer, int): - layer_data = tmxmap.getLayerData(layer).data - elif isinstance(layer, str): - try: - layer = [ l for l in tmxmap.tilelayers if l.name == layer ].pop() - layer_data = layer.data - except IndexError: - msg = "Layer \"{0}\" not found in map {1}." - raise ValueError, msg.format(layer, tmxmap) - - p = product(xrange(tmxmap.width), xrange(tmxmap.height)) - if gid: - points = [ (x,y) for (x,y) in p if layer_data[y][x] == gid ] - else: - points = [ (x,y) for (x,y) in p if layer_data[y][x] ] - - rects = simplify(points, tmxmap.tilewidth, tmxmap.tileheight) - return rects - - -def simplify(all_points, tilewidth, tileheight): - """ - kludge: - - "A kludge (or kluge) is a workaround, a quick-and-dirty solution, - a clumsy or inelegant, yet effective, solution to a problem, typically - using parts that are cobbled together." - - -- wikipedia - - turn a list of points into a rects - adjacent rects will be combined. - - plain english: - the input list must be a list of tuples that represent - the areas to be combined into rects - the rects will be blended together over solid groups - - so if data is something like: - - 0 1 1 1 0 0 0 - 0 1 1 0 0 0 0 - 0 0 0 0 0 4 0 - 0 0 0 0 0 4 0 - 0 0 0 0 0 0 0 - 0 0 1 1 1 1 1 - - you'll have the 4 rects that mask the area like this: - - ..######...... - ..####........ - ..........##.. - ..........##.. - .............. - ....########## - - pretty cool, right? - - there may be cases where the number of rectangles is not as low as possible, - but I haven't found that it is excessively bad. certainly much better than - making a list of rects, one for each tile on the map! - - """ - - def pick_rect(points, rects): - ox, oy = sorted([ (sum(p), p) for p in points ])[0][1] - x = ox - y = oy - ex = None - - while 1: - x += 1 - if not (x, y) in points: - if ex is None: - ex = x - 1 - - if ((ox, y+1) in points): - if x == ex + 1 : - y += 1 - x = ox - - else: - y -= 1 - break - else: - if x <= ex: y-= 1 - break - - c_rect = Rect(ox*tilewidth,oy*tileheight,\ - (ex-ox+1)*tilewidth,(y-oy+1)*tileheight) - - rects.append(c_rect) - - rect = Rect(ox,oy,ex-ox+1,y-oy+1) - kill = [ p for p in points if rect.collidepoint(p) ] - [ points.remove(i) for i in kill ] - - if points: - pick_rect(points, rects) - - rect_list = [] - while all_points: - pick_rect(all_points, rect_list) - - return rect_list -
M data/states/battle.pydata/states/battle.py

@@ -1,7 +1,6 @@

"""This is the state that handles battles against monsters""" import random, sys -from itertools import izip import pygame as pg from .. import tools, battlegui, observer, setup from .. components import person, attack, attackitems

@@ -188,7 +187,7 @@ """

pos_list = self.arrow.make_select_action_pos_list() state_list = [self.enter_select_enemy_state, self.enter_select_item_state, self.enter_select_magic_state, self.try_to_run_away] - return dict(izip(pos_list, state_list)) + return dict(zip(pos_list, state_list)) def update(self, surface, keys, current_time): """
M data/states/levels.pydata/states/levels.py

@@ -126,13 +126,13 @@ player.rect.x = self.game_data['last location'][0] * 32

player.rect.y = self.game_data['last location'][1] * 32 else: - for object in self.renderer.tmx_data.getObjects(): + for object in self.renderer.tmx_data.objects: properties = object.__dict__ if properties['name'] == 'start point': - if last_state == properties['state']: + if last_state == properties['properties']['state']: posx = properties['x'] * 2 posy = (properties['y'] * 2) - 32 - player = person.Player(properties['direction'], + player = person.Player(properties['properties']['direction'], self.game_data) player.rect.x = posx player.rect.y = posy

@@ -145,7 +145,7 @@ Make the blockers for the level.

""" blockers = [] - for object in self.renderer.tmx_data.getObjects(): + for object in self.renderer.tmx_data.objects: properties = object.__dict__ if properties['name'] == 'blocker': left = properties['x'] * 2

@@ -161,7 +161,7 @@ Make any sprites for the level as needed.

""" sprites = pg.sprite.Group() - for object in self.renderer.tmx_data.getObjects(): + for object in self.renderer.tmx_data.objects: properties = object.__dict__ if properties['name'] == 'sprite': if 'direction' in properties:

@@ -246,8 +246,8 @@ """

Assign dialogue from object property dictionaries in tmx maps to sprites. """ dialogue_list = [] - for i in range(int(property_dict['dialogue length'])): - dialogue_list.append(property_dict['dialogue'+str(i)]) + for i in range(int(property_dict['properties']['dialogue length'])): + dialogue_list.append(property_dict['properties']['dialogue'+str(i)]) sprite.dialogue = dialogue_list if sprite.name == 'oldman':

@@ -323,7 +323,7 @@ Make the portals to switch state.

""" portal_group = pg.sprite.Group() - for object in self.renderer.tmx_data.getObjects(): + for object in self.renderer.tmx_data.objects: properties = object.__dict__ if properties['name'] == 'portal': posx = properties['x'] * 2
M data/states/main_menu.pydata/states/main_menu.py

@@ -3,7 +3,7 @@ import pygame as pg

from .. import setup, tools, tilerender from .. import observer from .. import constants as c -import death +from . import death #Python 2/3 compatibility.
M data/tilerender.pydata/tilerender.py

@@ -3,7 +3,7 @@ This is a test of using the pytmx library with Tiled.

""" import pygame as pg -from . import pytmx +import pytmx class Renderer(object):

@@ -19,13 +19,13 @@ def render(self, surface):

tw = self.tmx_data.tilewidth th = self.tmx_data.tileheight - gt = self.tmx_data.getTileImageByGid + gt = self.tmx_data.get_tile_image_by_gid if self.tmx_data.background_color: surface.fill(self.tmx_data.background_color) - for layer in self.tmx_data.visibleLayers: - if isinstance(layer, pytmx.TiledLayer): + for layer in self.tmx_data.visible_layers: + if isinstance(layer, pytmx.TiledTileLayer): for x, y, gid in layer: tile = gt(gid) if tile:

@@ -34,7 +34,7 @@

elif isinstance(layer, pytmx.TiledObjectGroup): pass - elif isinstance(layer, pytmx.TiledImageLayer): + elif isinstance(layer, pytmx.tiled_image_layer): image = gt(layer.gid) if image: surface.blit(image, (0, 0))