Commits

Richard Jones  committed f1dc8ad

more tmx goodness

  • Participants
  • Parent commits f08c45d

Comments (0)

Files changed (1)

         self.tile_height = tileset.tile_height
         self.properties = {}
 
+    @classmethod
+    def fromSurface(cls, surface):
+        '''Create a new Tile object straight from a pygame Surface.
+
+        Its tile_width and tile_height will be set using the Surface dimensions.
+        Its gid will be 0.
+        '''
+        class ts:
+            tile_width, tile_height = surface.get_size()
+        return cls(0, surface, ts)
+
     def loadxml(self, tag):
         props = tag.find('properties')
         if props is None:
         self.x, self.y = x, y
         self.px, self.py = px, py
         self.tile = tile
+        self.topleft = (px, py)
         self.left = px
         self.right = px + tile.tile_width
         self.top = py
         self.bottom = py + tile.tile_height
+        self.center = (px + tile.tile_width//2, py + tile.tile_height//2)
         self._added_properties = {}
         self._deleted_properties = set()
     def __repr__(self):
         if other.y + other.height < self.py: return False
         return True
 
+class LayerIterator(object):
+    '''Iterates over all the cells in a layer in column,row order.
+    '''
+    def __init__(self, layer):
+        self.layer = layer
+        self.i, self.j = 0, 0
+    def next(self):
+        if self.i == self.layer.width - 1:
+            self.j += 1
+            self.i = 0
+        if self.j == self.layer.height - 1:
+            raise StopIteration()
+        value = self.layer[self.i, self.j]
+        self.i += 1
+        return value
+
+
 class Layer(object):
     '''A 2d grid of Cells.
 
     def __init__(self, name, visible, map):
         self.name = name
         self.visible = visible
+        self.position = (0, 0)
         # TODO get from TMX?
         self.px_width = map.px_width
         self.px_height = map.px_height
         self.tilesets = map.tilesets
         self.group = pygame.sprite.Group()
         self.properties = {}
-        self.cells = collections.defaultdict(lambda: None)
+        self.cells = {}
+
+    def __repr__(self):
+        return '<Layer "%s" at 0x%x>' % (self.name, id(self))
 
     def __getitem__(self, pos):
         return self.cells.get(pos)
 
+    def __setitem__(self, pos, tile):
+        x, y = pos
+        px = x * self.tile_width
+        py = y * self.tile_width
+        self.cells[pos] = Cell(x, y, px, py, tile)
+
+    def __iter__(self):
+        return LayerIterator(self)
+
     @classmethod
     def fromxml(cls, tag, map):
         layer = cls(tag.attrib['name'], int(tag.attrib.get('visible', 1)), map)
         r = []
         for propname in properties:
             for cell in self.cells.values():
-                if propname in cell:
+                if cell and propname in cell:
                     r.append(cell)
         return r
 
                 for j in range(int(j1), int(j2))
                     if (i, j) in self.cells]
 
+    def get_at(self, x, y):
+        '''Return the cell at the nominated (x, y) coordinate.
+
+        Return a Cell instance or None.
+        '''
+        i = x // self.tile_width
+        j = y // self.tile_height
+        return self.cells.get((i, j))
+
+    def neighbors(self, index):
+        '''Return the indexes of the valid (ie. within the map) cardinal (ie.
+        North, South, East, West) neighbors of the nominated cell index.
+
+        Returns a list of 2-tuple indexes.
+        '''
+        i, j = index
+        n = []
+        if i < self.width-1:
+            n.append((i+1, j))
+        if i > 0:
+            n.append((i-1, j))
+        if j < self.height-1:
+            n.append((i, j+1))
+        if j > 0:
+            n.append((i, j-1))
+        return n
+
 class SpriteLayer(pygame.sprite.AbstractGroup):
     def __init__(self):
         super(SpriteLayer, self).__init__()
         screen_y = y-self.childs_oy
         return int(screen_x), int(screen_y)
 
+    def index_at(self, x, y):
+        '''Return the map index at the (screen-space) pixel position.
+        '''
+        sx, sy = self.pixel_from_screen(x, y)
+        return int(sx//self.tile_width), int(sy//self.tile_height)
+
 def load(filename, viewport):
     return TileMap.load(filename, viewport)