示例#1
0
    def copySelection(self, mapDocument):
        currentLayer = mapDocument.currentLayer()
        if (not currentLayer):
            return
        map = mapDocument.map()
        selectedArea = mapDocument.selectedArea()
        selectedObjects = mapDocument.selectedObjects()
        tileLayer = currentLayer
        copyLayer = None
        if (not selectedArea.isEmpty() and type(tileLayer)==TileLayer):
            # Copy the selected part of the layer
            copyLayer = tileLayer.copy(selectedArea.translated(-tileLayer.x(), -tileLayer.y()))
        elif (not selectedObjects.isEmpty()):
            # Create a new object group with clones of the selected objects
            objectGroup = ObjectGroup()
            for mapObject in selectedObjects:
                objectGroup.addObject(mapObject.clone())
            copyLayer = objectGroup
        else:
            return

        # Create a temporary map to write to the clipboard
        copyMap = Map(map.orientation(),
                    copyLayer.width(), copyLayer.height(),
                    map.tileWidth(), map.tileHeight())
        copyMap.setRenderOrder(map.renderOrder())
        # Resolve the set of tilesets used by this layer
        for tileset in copyLayer.usedTilesets():
            copyMap.addTileset(tileset)
        copyMap.addLayer(copyLayer)
        self.setMap(copyMap)
示例#2
0
    def setCurrentTiles(self, tiles):
        if (self.mCurrentTiles == tiles):
            return
        del self.mCurrentTiles
        self.mCurrentTiles = tiles
        # Set the selected tiles on the map document
        if (tiles):
            selectedTiles = QList()
            for y in range(tiles.height()):
                for x in range(tiles.width()):
                    cell = tiles.cellAt(x, y)
                    if (not cell.isEmpty()):
                        selectedTiles.append(cell.tile)

            self.mMapDocument.setSelectedTiles(selectedTiles)

            # Create a tile stamp with these tiles
            map = self.mMapDocument.map()
            stamp = Map(map.orientation(), tiles.width(), tiles.height(),
                        map.tileWidth(), map.tileHeight())
            stamp.addLayer(tiles.clone())
            stamp.addTilesets(tiles.usedTilesets())

            self.mEmittingStampCaptured = True
            self.stampCaptured.emit(TileStamp(stamp))
            self.mEmittingStampCaptured = False
示例#3
0
    def read(self, fileName):
        uncompressed = QByteArray()
        # Read data
        f = QFile(fileName)
        if (f.open(QIODevice.ReadOnly)):
            compressed = f.readAll()
            f.close()
            uncompressed, length = decompress(compressed, 48 * 48)

        # Check the data
        if (uncompressed.count() != 48 * 48):
            self.mError = self.tr("This is not a valid Droidcraft map file!")
            return None

        uncompressed = uncompressed.data()
        # Build 48 x 48 map
        # Create a Map -> Create a Tileset -> Add Tileset to map
        # -> Create a TileLayer -> Fill layer -> Add TileLayer to Map
        map = Map(Map.Orientation.Orthogonal, 48, 48, 32, 32)
        mapTileset = Tileset.create("tileset", 32, 32)
        mapTileset.loadFromImage(QImage(":/tileset.png"), "tileset.png")
        map.addTileset(mapTileset)
        # Fill layer
        mapLayer = TileLayer("map", 0, 0, 48, 48)
        # Load
        for i in range(0, 48 * 48):
            tileFile = int(uncompressed[i]) & 0xff
            y = int(i / 48)
            x = i - (48 * y)
            tile = mapTileset.tileAt(tileFile)
            mapLayer.setCell(x, y, Cell(tile))

        map.addLayer(mapLayer)
        return map
示例#4
0
 def read(self, fileName):
     uncompressed = QByteArray()
     # Read data
     f = QFile(fileName)
     if (f.open(QIODevice.ReadOnly)) :
         compressed = f.readAll()
         f.close()
         uncompressed, length = decompress(compressed, 48 * 48)
     
     # Check the data
     if (uncompressed.count() != 48 * 48) :
         self.mError = self.tr("This is not a valid Droidcraft map file!")
         return None
     
     uncompressed = uncompressed.data()
     # Build 48 x 48 map
     # Create a Map -> Create a Tileset -> Add Tileset to map
     # -> Create a TileLayer -> Fill layer -> Add TileLayer to Map
     map = Map(Map.Orientation.Orthogonal, 48, 48, 32, 32)
     mapTileset = Tileset.create("tileset", 32, 32)
     mapTileset.loadFromImage(QImage(":/tileset.png"), "tileset.png")
     map.addTileset(mapTileset)
     # Fill layer
     mapLayer =  TileLayer("map", 0, 0, 48, 48)
     # Load
     for i in range(0, 48 * 48):
         tileFile = int(uncompressed[i])&0xff
         y = int(i / 48)
         x = i - (48 * y)
         tile = mapTileset.tileAt(tileFile)
         mapLayer.setCell(x, y, Cell(tile))
     
     map.addLayer(mapLayer)
     return map
示例#5
0
    def endCapture(self):
        if (self.mBrushBehavior != BrushBehavior.Capture):
            return
        self.mBrushBehavior = BrushBehavior.Free
        tileLayer = self.currentTileLayer()
        # Intersect with the layer and translate to layer coordinates
        captured = self.capturedArea()
        captured &= QRect(tileLayer.x(), tileLayer.y(), tileLayer.width(),
                          tileLayer.height())
        if (captured.isValid()):
            captured.translate(-tileLayer.x(), -tileLayer.y())
            map = tileLayer.map()
            capture = tileLayer.copy(captured)

            stamp = Map(map.orientation(), capture.width(), capture.height(),
                        map.tileWidth(), map.tileHeight())
            # Add tileset references to map
            for tileset in capture.usedTilesets():
                stamp.addTileset(tileset)

            stamp.addLayer(capture)

            self.stampCaptured.emit(TileStamp(stamp))
        else:
            self.updatePreview()
示例#6
0
    def copySelection(self, mapDocument):
        currentLayer = mapDocument.currentLayer()
        if (not currentLayer):
            return
        map = mapDocument.map()
        selectedArea = mapDocument.selectedArea()
        selectedObjects = mapDocument.selectedObjects()
        tileLayer = currentLayer
        copyLayer = None
        if (not selectedArea.isEmpty() and type(tileLayer) == TileLayer):
            # Copy the selected part of the layer
            copyLayer = tileLayer.copy(
                selectedArea.translated(-tileLayer.x(), -tileLayer.y()))
        elif (not selectedObjects.isEmpty()):
            # Create a new object group with clones of the selected objects
            objectGroup = ObjectGroup()
            for mapObject in selectedObjects:
                objectGroup.addObject(mapObject.clone())
            copyLayer = objectGroup
        else:
            return

        # Create a temporary map to write to the clipboard
        copyMap = Map(map.orientation(), copyLayer.width(), copyLayer.height(),
                      map.tileWidth(), map.tileHeight())
        copyMap.setRenderOrder(map.renderOrder())
        # Resolve the set of tilesets used by this layer
        for tileset in copyLayer.usedTilesets():
            copyMap.addTileset(tileset)
        copyMap.addLayer(copyLayer)
        self.setMap(copyMap)
示例#7
0
    def endCapture(self):
        if (self.mBrushBehavior != BrushBehavior.Capture):
            return
        self.mBrushBehavior = BrushBehavior.Free
        tileLayer = self.currentTileLayer()
        # Intersect with the layer and translate to layer coordinates
        captured = self.capturedArea()
        captured &= QRect(tileLayer.x(), tileLayer.y(),
                          tileLayer.width(), tileLayer.height())
        if (captured.isValid()):
            captured.translate(-tileLayer.x(), -tileLayer.y())
            map = tileLayer.map()
            capture = tileLayer.copy(captured)
            
            stamp = Map(map.orientation(),
                             capture.width(),
                             capture.height(),
                             map.tileWidth(),
                             map.tileHeight())
            # Add tileset references to map
            for tileset in capture.usedTilesets():
                stamp.addTileset(tileset)

            stamp.addLayer(capture)

            self.stampCaptured.emit(TileStamp(stamp))
        else:
            self.updatePreview()
 def toMap(self, variant, mapDir):
     self.mGidMapper.clear()
     self.mMapDir = mapDir
     variantMap = variant
     orientationString = variantMap.get("orientation", '')
     orientation = orientationFromString(orientationString)
     if (orientation == Map.Orientation.Unknown):
         self.mError = self.tr("Unsupported map orientation: \"%s\""%orientationString)
         return None
     
     staggerAxisString = variantMap.get("staggeraxis", '')
     staggerAxis = staggerAxisFromString(staggerAxisString)
     staggerIndexString = variantMap.get("staggerindex", '')
     staggerIndex = staggerIndexFromString(staggerIndexString)
     renderOrderString = variantMap.get("renderorder", '')
     renderOrder = renderOrderFromString(renderOrderString)
     nextObjectId = variantMap.get("nextobjectid", 0)
     map = Map(orientation,
                        variantMap.get("width",0),
                        variantMap.get("height",0),
                        variantMap.get("tilewidth",0),
                        variantMap.get("tileheight",0))
     map.setHexSideLength(variantMap.get("hexsidelength", 0))
     map.setStaggerAxis(staggerAxis)
     map.setStaggerIndex(staggerIndex)
     map.setRenderOrder(renderOrder)
     if (nextObjectId):
         map.setNextObjectId(nextObjectId)
     self.mMap = map
     map.setProperties(self.toProperties(variantMap.get("properties", {})))
     bgColor = variantMap.get("backgroundcolor", '')
     if (bgColor!='' and QColor.isValidColor(bgColor)):
         map.setBackgroundColor(QColor(bgColor))
     for tilesetVariant in variantMap.get("tilesets", []):
         tileset = self.__toTileset(tilesetVariant)
         if not tileset:
             return None
         
         map.addTileset(tileset)
     
     for layerVariant in variantMap.get("layers", []):
         layer = self.toLayer(layerVariant)
         if not layer:
             return None
         
         map.addLayer(layer)
     
     return map
    def toMap(self, variant, mapDir):
        self.mGidMapper.clear()
        self.mMapDir = mapDir
        variantMap = variant
        orientationString = variantMap.get("orientation", '')
        orientation = orientationFromString(orientationString)
        if (orientation == Map.Orientation.Unknown):
            self.mError = self.tr("Unsupported map orientation: \"%s\"" %
                                  orientationString)
            return None

        staggerAxisString = variantMap.get("staggeraxis", '')
        staggerAxis = staggerAxisFromString(staggerAxisString)
        staggerIndexString = variantMap.get("staggerindex", '')
        staggerIndex = staggerIndexFromString(staggerIndexString)
        renderOrderString = variantMap.get("renderorder", '')
        renderOrder = renderOrderFromString(renderOrderString)
        nextObjectId = variantMap.get("nextobjectid", 0)
        map = Map(orientation, variantMap.get("width", 0),
                  variantMap.get("height", 0), variantMap.get("tilewidth", 0),
                  variantMap.get("tileheight", 0))
        map.setHexSideLength(variantMap.get("hexsidelength", 0))
        map.setStaggerAxis(staggerAxis)
        map.setStaggerIndex(staggerIndex)
        map.setRenderOrder(renderOrder)
        if (nextObjectId):
            map.setNextObjectId(nextObjectId)
        self.mMap = map
        map.setProperties(self.toProperties(variantMap.get("properties", {})))
        bgColor = variantMap.get("backgroundcolor", '')
        if (bgColor != '' and QColor.isValidColor(bgColor)):
            map.setBackgroundColor(QColor(bgColor))
        for tilesetVariant in variantMap.get("tilesets", []):
            tileset = self.__toTileset(tilesetVariant)
            if not tileset:
                return None

            map.addTileset(tileset)

        for layerVariant in variantMap.get("layers", []):
            layer = self.toLayer(layerVariant)
            if not layer:
                return None

            map.addLayer(layer)

        return map
示例#10
0
    def createMap(self):
        if (self.exec() != QDialog.Accepted):
            return None
        mapWidth = self.mUi.mapWidth.value()
        mapHeight = self.mUi.mapHeight.value()
        tileWidth = self.mUi.tileWidth.value()
        tileHeight = self.mUi.tileHeight.value()
        orientationIndex = self.mUi.orientation.currentIndex()
        orientationData = self.mUi.orientation.itemData(orientationIndex)
        orientation = orientationData
        layerFormat = Map.LayerDataFormat(self.mUi.layerFormat.currentIndex())
        renderOrder = Map.RenderOrder(self.mUi.renderOrder.currentIndex())
        map = Map(orientation,
                           mapWidth, mapHeight,
                           tileWidth, tileHeight)
        map.setLayerDataFormat(layerFormat)
        map.setRenderOrder(renderOrder)
        gigabyte = 1073741824
        memory = mapWidth * mapHeight * 8#sizeof(Cell)
        # Add a tile layer to new maps of reasonable size
        if (memory < gigabyte):
            map.addLayer(TileLayer(self.tr("Tile Layer 1"), 0, 0,
                                        mapWidth, mapHeight))
        else:
            gigabytes = memory / gigabyte
            QMessageBox.warning(self, self.tr("Memory Usage Warning"),
                                 self.tr("Tile layers for this map will consume %.2f GB "
                                    "of memory each. Not creating one by default."%gigabytes))

        # Store settings for next time
        prefs = preferences.Preferences.instance()
        prefs.setLayerDataFormat(layerFormat)
        prefs.setMapRenderOrder(renderOrder)
        s = preferences.Preferences.instance().settings()
        s.setValue(ORIENTATION_KEY, orientationIndex)
        s.setValue(MAP_WIDTH_KEY, mapWidth)
        s.setValue(MAP_HEIGHT_KEY, mapHeight)
        s.setValue(TILE_WIDTH_KEY, tileWidth)
        s.setValue(TILE_HEIGHT_KEY, tileHeight)
        return MapDocument(map)
示例#11
0
def stampFromContext(selectedTool):
    stamp = TileStamp()
    stampBrush = dynamic_cast(selectedTool, StampBrush)
    if stampBrush:
        # take the stamp from the stamp brush
        stamp = stampBrush.stamp()
    else:
        fillTool = dynamic_cast(selectedTool, BucketFillTool)
        if fillTool:
            # take the stamp from the fill tool
            stamp = fillTool.stamp()
        else:
            mapDocument = DocumentManager.instance().currentDocument()
            if mapDocument:
                # try making a stamp from the current tile selection
                tileLayer = dynamic_cast(mapDocument.currentLayer(), TileLayer)
                if (not tileLayer):
                    return stamp
                selection = mapDocument.selectedArea()
                if (selection.isEmpty()):
                    return stamp
                selection.translate(-tileLayer.position())
                copy = tileLayer.copy(selection)
                if (copy.size().isEmpty()):
                    return stamp
                map = mapDocument.map()
                copyMap = Map(map.orientation(),
                                       copy.width(), copy.height(),
                                       map.tileWidth(), map.tileHeight())
                # Add tileset references to map
                for tileset in copy.usedTilesets():
                    copyMap.addTileset(tileset)
                copyMap.setRenderOrder(map.renderOrder())
                copyMap.addLayer(copy.take())
                stamp.addVariation(copyMap)
    
    return stamp
示例#12
0
    def setTile(self, tile):
        if type(tile) == list:
            tile = tile[0]
        if (self.mTile == tile):
            return
        self.mTile = tile
        self.mMapScene.disableSelectedTool()
        previousDocument = self.mMapScene.mapDocument()
        if (tile):
            self.mMapView.setEnabled(not self.mTile.tileset().isExternal())
            map = Map(Map.Orientation.Orthogonal, 1, 1, tile.width(),
                      tile.height())
            map.addTileset(tile.sharedTileset())
            tileLayer = TileLayer(QString(), 0, 0, 1, 1)
            tileLayer.setCell(0, 0, Cell(tile))
            map.addLayer(tileLayer)
            objectGroup = None
            if (tile.objectGroup()):
                objectGroup = tile.objectGroup().clone()
            else:
                objectGroup = ObjectGroup()
            objectGroup.setDrawOrder(ObjectGroup.DrawOrder.IndexOrder)
            map.addLayer(objectGroup)
            mapDocument = MapDocument(map)
            self.mMapScene.setMapDocument(mapDocument)
            self.mToolManager.setMapDocument(mapDocument)
            mapDocument.setCurrentLayerIndex(1)
            self.mMapScene.enableSelectedTool()
            mapDocument.undoStack().indexChanged.connect(self.applyChanges)
        else:
            self.mMapView.setEnabled(False)
            self.mMapScene.setMapDocument(None)
            self.mToolManager.setMapDocument(None)

        if (previousDocument):
            previousDocument.undoStack().disconnect()
            del previousDocument
示例#13
0
def stampFromContext(selectedTool):
    stamp = TileStamp()
    stampBrush = dynamic_cast(selectedTool, StampBrush)
    if stampBrush:
        # take the stamp from the stamp brush
        stamp = stampBrush.stamp()
    else:
        fillTool = dynamic_cast(selectedTool, BucketFillTool)
        if fillTool:
            # take the stamp from the fill tool
            stamp = fillTool.stamp()
        else:
            mapDocument = DocumentManager.instance().currentDocument()
            if mapDocument:
                # try making a stamp from the current tile selection
                tileLayer = dynamic_cast(mapDocument.currentLayer(), TileLayer)
                if (not tileLayer):
                    return stamp
                selection = mapDocument.selectedArea()
                if (selection.isEmpty()):
                    return stamp
                selection.translate(-tileLayer.position())
                copy = tileLayer.copy(selection)
                if (copy.size().isEmpty()):
                    return stamp
                map = mapDocument.map()
                copyMap = Map(map.orientation(), copy.width(), copy.height(),
                              map.tileWidth(), map.tileHeight())
                # Add tileset references to map
                for tileset in copy.usedTilesets():
                    copyMap.addTileset(tileset)
                copyMap.setRenderOrder(map.renderOrder())
                copyMap.addLayer(copy.take())
                stamp.addVariation(copyMap)

    return stamp
示例#14
0
    def setTile(self, tile):
        if type(tile)==list:
            tile = tile[0]
        if (self.mTile == tile):
            return
        self.mTile = tile
        self.mMapScene.disableSelectedTool()
        previousDocument = self.mMapScene.mapDocument()
        if (tile):
            self.mMapView.setEnabled(not self.mTile.tileset().isExternal())
            map = Map(Map.Orientation.Orthogonal, 1, 1, tile.width(), tile.height())
            map.addTileset(tile.sharedTileset())
            tileLayer = TileLayer(QString(), 0, 0, 1, 1)
            tileLayer.setCell(0, 0, Cell(tile))
            map.addLayer(tileLayer)
            objectGroup = None
            if (tile.objectGroup()):
                objectGroup = tile.objectGroup().clone()
            else:
                objectGroup = ObjectGroup()
            objectGroup.setDrawOrder(ObjectGroup.DrawOrder.IndexOrder)
            map.addLayer(objectGroup)
            mapDocument = MapDocument(map)
            self.mMapScene.setMapDocument(mapDocument)
            self.mToolManager.setMapDocument(mapDocument)
            mapDocument.setCurrentLayerIndex(1)
            self.mMapScene.enableSelectedTool()
            mapDocument.undoStack().indexChanged.connect(self.applyChanges)
        else:
            self.mMapView.setEnabled(False)
            self.mMapScene.setMapDocument(None)
            self.mToolManager.setMapDocument(None)

        if (previousDocument):
            previousDocument.undoStack().disconnect()
            del previousDocument
示例#15
0
class Scene(engine.Module):
    """Główny ekran gry."""

    def __init__(self, _engine):
        super(Scene, self).__init__(_engine)
        self._background = pygame.Surface((self._resx, self._resy))
        self.surface = self._background.copy()
        self._actual = []
        self._client = _engine.options['client'] = sock.BomberFactory(self._process, self._connectionError)
        from twisted.internet import reactor
        from twisted.internet.task import LoopingCall
        self._gameloop = LoopingCall(self._render)
        self._network = reactor.connectTCP(_engine.options['host'], _engine.options['port'], self._client)
        self._play = True
        self._refresh = True
        self._submodules = ()
        self._map = None
        self._playerID = None

    def __del__(self):
        self._network.disconnect()

    def _loadMap(self, _width, _height):
        self._map = Map(self._engine, self, (_width, _height))
        self._heroLayer = ObjectsLayer(self._map) # Warstwa graczy
        self._mineLayer = ObjectsLayer(self._map) # Warstwa min
        self._map.addLayer('Hero', 3, self._heroLayer)
        self._map.addLayer('Mine', 2, self._mineLayer)
        self._submodules = (self._map,)

    def isPlaying(self):
        """Czy gracz nadal gra?"""

        return self._play

    def screenUpdated(self):
        """Aktualizuje obrazy tła i submoduły."""

        super(Scene, self).screenUpdated()
        self._refresh = True
        self._background = pygame.Surface((self._resx, self._resy))
        self.surface = pygame.transform.smoothscale(self.surface, (self._resx, self._resy))
        for submodule in self._submodules:
            submodule.screenUpdated()

    def show(self):
        if not self._play:
            self._engine.previousModule()
            return

        self._last = time.time()
        from twisted.internet import reactor
        self._gameloop.start(self._engine.getFPS() and 1.0 / self._engine.getFPS() or 0.0)
        reactor.run()
        self._gameloop.stop()

    def _render(self):
        self._engine.tick()
        for event in self._engine.events():
            if event.type == QUIT:
                self._play = False

            elif event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    self._engine.runLoop = False
                    from twisted.internet import reactor
                    reactor.stop()
                    return

                if self._map:
                    if event.key in (K_w, K_UP):
                        self._client.sendAction('u')
                        self._last = time.time()

                    elif event.key in (K_s, K_DOWN):
                        self._client.sendAction('d')
                        self._last = time.time()

                    elif event.key in (K_a, K_LEFT):
                        self._client.sendAction('l')
                        self._last = time.time()

                    elif event.key in (K_d, K_RIGHT):
                        self._client.sendAction('r')
                        self._last = time.time()

                    elif event.key in (K_RETURN, K_RCTRL, K_LCTRL):
                        self._client.sendAction('c')
                        self._last = time.time()

                    elif event.key == K_q:
                        self._client.sendAction('e')
                        self._last = time.time()

        if self._map and self._last + 1./self._engine.options['fps'] < time.time():
            self._client.sendAction('m')
            self._last = time.time()

        if not self._map and self._playerID == None:
            self.surface = self._background.copy()
            utils.drawText(self.surface, 'Oczekiwanie na graczy!', 20, (255, 255, 255), (self._resx / 2, self._resy / 2))

        updated = []
        if self._play:
            for submodule in self._submodules:
                updated.extend(submodule.update())
                submodule.draw(self.surface)

        if self._refresh:
            self._engine.show(self.surface)
            self._refresh = False

        else:
            self._engine.show(self.surface, updated)

        if not self._play:
            time.sleep(5)
            self._engine.runLoop = False
            from twisted.internet import reactor
            reactor.stop()
            return

    def _process(self, obj):
        if isinstance(obj, protocolObjects.Countdown):
            return self._countdown(obj)

        if isinstance(obj, protocolObjects.Result):
            return self._finish(obj)

        if isinstance(obj, protocolObjects.Map):
            return self._update(obj)

        return self._connectionError(obj)

    def _connectionError(self, msg):
        self._play = False
        utils.drawText(self.surface, str(msg), 10, (255, 255, 255), (self._resx / 2, self._resy - 10))

    def _countdown(self, countdown):
        if not self._map and countdown.number == 1:
            self._loadMap(countdown.mapSize.x, countdown.mapSize.y)

        if self._playerID == None:
            self._playerID = countdown.playerId

        self.surface = self._background.copy()
        utils.drawText(self.surface, 'Gracz %d. >%d<' % (countdown.playerId, countdown.number), 30, (255, 255, 255), (self._resx / 2, self._resy / 2))

    def _finish(self, result):
        self.surface = self._background.copy()
        utils.drawText(self.surface, 'Gra zakonczona!', 40, (255, 255, 255), (self._resx / 2, self._resy / 2))
        if len(result.winners) == 1:
            utils.drawText(self.surface, 'Wygral gracz %d!' % result.winners[0], 40, (255, 255, 255), (self._resx / 2, self._resy / 2 + 40))

        elif len(result.winners):
            utils.drawText(self.surface, 'Wygrali gracze %s!' % (', '.join([str(i) for i in result.winners])), 40, (255, 255, 255), (self._resx / 2, self._resy / 2 + 40))

        self._play = False
        self._engine.show(self.surface)

    def _update(self, map):
        if not self._map:
            self._play = False
            return

        for mine in map.mines:
            _id = mine.position.x, mine.position.y
            if not self._mineLayer.get(_id):
                _mine = ObjectsLayer.Sprite(utils.loadImage('gfx/bomb.png', alpha = True))
                self._mineLayer.add(_id, _mine)
                self._mineLayer.move(_id, _id)

        for _id, player in enumerate(map.playersPositions):
            if not self._heroLayer.get(_id):
                self._heroLayer.add(_id, ObjectsLayer.Sprite(utils.loadImage('gfx/hero/n.png', alpha = True)))

            _hero = self._heroLayer.get(_id)
            _pos = _hero.getPos()
            self._heroLayer.move(_id, (player.x, player.y))
            _newpos = _hero.getPos()
            if _pos[0] > _newpos[0]:
                _hero.changeImage(utils.loadImage('gfx/hero/w.png', alpha = True))

            if _pos[0] < _newpos[0]:
                _hero.changeImage(utils.loadImage('gfx/hero/e.png', alpha = True))

            if _pos[1] > _newpos[1]:
                _hero.changeImage(utils.loadImage('gfx/hero/n.png', alpha = True))

            if _pos[1] < _newpos[1]:
                _hero.changeImage(utils.loadImage('gfx/hero/s.png', alpha = True))

            if _id == self._playerID:
                _, _, w, h = self._map.getRectangle()
                self._map.setShift((w / 2 - _newpos[0], h / 2 - _newpos[1]))
示例#16
0
class Scene(engine.Module):
    """Główny ekran gry."""
    def __init__(self, _engine):
        super(Scene, self).__init__(_engine)
        self._background = pygame.Surface((self._resx, self._resy))
        self.surface = self._background.copy()
        self._actual = []
        self._client = _engine.options['client'] = sock.Client(
            _engine.options['host'], _engine.options['port'])
        self._play = True
        self._refresh = True
        self._submodules = ()
        self._map = None
        self._playerID = None

    def _loadMap(self, _width, _height):
        self._map = Map(self._engine, self, (_width, _height))
        self._heroLayer = ObjectsLayer(self._map)  # Warstwa graczy
        self._mineLayer = ObjectsLayer(self._map)  # Warstwa min
        self._map.addLayer('Hero', 3, self._heroLayer)
        self._map.addLayer('Mine', 2, self._mineLayer)
        self._submodules = (self._map, )

    def isPlaying(self):
        """Czy gracz nadal gra?"""

        return self._play

    def screenUpdated(self):
        """Aktualizuje obrazy tła i submoduły."""

        super(Scene, self).screenUpdated()
        self._refresh = True
        self._background = pygame.Surface((self._resx, self._resy))
        self.surface = pygame.transform.smoothscale(self.surface,
                                                    (self._resx, self._resy))
        for submodule in self._submodules:
            submodule.screenUpdated()

    def show(self):
        if not self._play:
            self._engine.previousModule()
            return

        try:
            self._last = time.time()
            while self._engine.tick():
                _upd = self._client.update(.5 / self._engine.options['fps'])
                if self._play and _upd != True:
                    utils.drawText(self.surface, _upd, 20, (255, 255, 255),
                                   (self._resx / 2, self._resy / 2))
                    self._play = False
                    self._engine.show(self.surface)
                    time.sleep(5)
                    self._engine.previousModule()
                    raise SceneQuit()

                if self._client.countdown:
                    if not self._map:
                        self._loadMap(self._client.countdown.mapSize.x,
                                      self._client.countdown.mapSize.y)

                    if self._playerID == None:
                        self._playerID = self._client.countdown.playerId

                    self.surface = self._background.copy()
                    utils.drawText(
                        self.surface,
                        'Gracz %d. >%d<' % (self._client.countdown.playerId,
                                            self._client.countdown.number), 30,
                        (255, 255, 255), (self._resx / 2, self._resy / 2))
                    self._engine.show(self.surface)
                    continue

                if self._client.result:
                    utils.drawText(self.surface, 'Gra zakonczona!', 40,
                                   (255, 255, 255),
                                   (self._resx / 2, self._resy / 2))
                    if len(self._client.result.winners) == 1:
                        utils.drawText(
                            self.surface, 'Wygral gracz %d!' %
                            self._client.result.winners[0], 40,
                            (255, 255, 255),
                            (self._resx / 2, self._resy / 2 + 40))

                    elif len(self._client.result.winners):
                        utils.drawText(
                            self.surface, 'Wygrali gracze %s!' % (', '.join(
                                [str(i)
                                 for i in self._client.result.winners])), 40,
                            (255, 255, 255),
                            (self._resx / 2, self._resy / 2 + 40))

                    self._play = False
                    self._engine.show(self.surface)
                    time.sleep(10)
                    self._engine.previousModule()
                    raise SceneQuit()

                if self._client.map:
                    if not self._map:
                        self._engine.previousModule()
                        self._play = False
                        raise SceneQuit()

                    for mine in self._client.map.mines:
                        _id = mine.position.x, mine.position.y
                        if not self._mineLayer.get(_id):
                            _mine = ObjectsLayer.Sprite(
                                utils.loadImage('data/gfx/bomb.png',
                                                alpha=True))
                            self._mineLayer.add(_id, _mine)
                            self._mineLayer.move(_id, _id)

                    for _id, player in enumerate(
                            self._client.map.playersPositions):
                        if not self._heroLayer.get(_id):
                            self._heroLayer.add(
                                _id,
                                ObjectsLayer.Sprite(
                                    utils.loadImage('data/gfx/hero/n.png',
                                                    alpha=True)))

                        _hero = self._heroLayer.get(_id)
                        _pos = _hero.getPos()
                        self._heroLayer.move(_id, (player.x, player.y))
                        _newpos = _hero.getPos()
                        if _pos[0] > _newpos[0]:
                            _hero.changeImage(
                                utils.loadImage('data/gfx/hero/w.png',
                                                alpha=True))

                        if _pos[0] < _newpos[0]:
                            _hero.changeImage(
                                utils.loadImage('data/gfx/hero/e.png',
                                                alpha=True))

                        if _pos[1] > _newpos[1]:
                            _hero.changeImage(
                                utils.loadImage('data/gfx/hero/n.png',
                                                alpha=True))

                        if _pos[1] < _newpos[1]:
                            _hero.changeImage(
                                utils.loadImage('data/gfx/hero/s.png',
                                                alpha=True))

                        if _id == self._playerID:
                            _, _, w, h = self._map.getRectangle()
                            self._map.setShift(
                                (w / 2 - _newpos[0], h / 2 - _newpos[1]))

                for event in self._engine.events():
                    if event.type == QUIT:
                        raise engine.EngineQuit()

                    if event.type == KEYDOWN:
                        if event.key == K_ESCAPE:
                            self._engine.previousModule()
                            raise SceneQuit()

                        if event.key in (K_w, K_UP):
                            self._client.sendAction('u')
                            self._last = time.time()

                        elif event.key in (K_s, K_DOWN):
                            self._client.sendAction('d')
                            self._last = time.time()

                        elif event.key in (K_a, K_LEFT):
                            self._client.sendAction('l')
                            self._last = time.time()

                        elif event.key in (K_d, K_RIGHT):
                            self._client.sendAction('r')
                            self._last = time.time()

                        elif event.key in (K_RETURN, K_RCTRL, K_LCTRL):
                            self._client.sendAction('c')
                            self._last = time.time()

                        elif event.key == K_q:
                            self._client.sendAction('e')
                            self._last = time.time()

                if self._last + 1. / self._engine.options['fps'] < time.time():
                    self._client.sendAction('m')
                    self._last = time.time()

                self.surface = self._background.copy()
                if not self._map:
                    utils.drawText(self.surface, 'Oczekiwanie na graczy!', 20,
                                   (255, 255, 255),
                                   (self._resx / 2, self._resy / 2))

                updated = []
                for submodule in self._submodules:
                    updated.extend(submodule.update())
                    submodule.draw(self.surface)

                if self._refresh:
                    self._engine.show(self.surface)
                    self._refresh = False

                else:
                    self._engine.show(self.surface, updated)

        except SceneQuit:
            pass
示例#17
0
class Scene(engine.Module):
    """Główny ekran gry."""

    def __init__(self, _engine):
        super(Scene, self).__init__(_engine)
        self._background = pygame.Surface((self._resx, self._resy))
        self.surface = self._background.copy()
        self._actual = []
        self._client = _engine.options['client'] = sock.Client(_engine.options['host'], _engine.options['port'])
        self._play = True
        self._refresh = True
        self._submodules = ()
        self._map = None
        self._playerID = None

    def _loadMap(self, _width, _height):
        self._map = Map(self._engine, self, (_width, _height))
        self._heroLayer = ObjectsLayer(self._map) # Warstwa graczy
        self._mineLayer = ObjectsLayer(self._map) # Warstwa min
        self._map.addLayer('Hero', 3, self._heroLayer)
        self._map.addLayer('Mine', 2, self._mineLayer)
        self._submodules = (self._map,)

    def isPlaying(self):
        """Czy gracz nadal gra?"""

        return self._play

    def screenUpdated(self):
        """Aktualizuje obrazy tła i submoduły."""

        super(Scene, self).screenUpdated()
        self._refresh = True
        self._background = pygame.Surface((self._resx, self._resy))
        self.surface = pygame.transform.smoothscale(self.surface, (self._resx, self._resy))
        for submodule in self._submodules:
            submodule.screenUpdated()

    def show(self):
        if not self._play:
            self._engine.previousModule()
            return

        try:
            self._last = time.time()
            while self._engine.tick():
                _upd = self._client.update(.5/self._engine.options['fps'])
                if self._play and _upd != True:
                    utils.drawText(self.surface, _upd, 20, (255, 255, 255), (self._resx / 2, self._resy / 2))
                    self._play = False
                    self._engine.show(self.surface)
                    time.sleep(5)
                    self._engine.previousModule()
                    raise SceneQuit()

                if self._client.countdown:
                    if not self._map:
                        self._loadMap(self._client.countdown.mapSize.x, self._client.countdown.mapSize.y)

                    if self._playerID == None:
                        self._playerID = self._client.countdown.playerId

                    self.surface = self._background.copy()
                    utils.drawText(self.surface, 'Gracz %d. >%d<' % (self._client.countdown.playerId, self._client.countdown.number), 30, (255, 255, 255), (self._resx / 2, self._resy / 2))
                    self._engine.show(self.surface)
                    continue

                if self._client.result:
                    utils.drawText(self.surface, 'Gra zakonczona!', 40, (255, 255, 255), (self._resx / 2, self._resy / 2))
                    if len(self._client.result.winners) == 1:
                        utils.drawText(self.surface, 'Wygral gracz %d!' % self._client.result.winners[0], 40, (255, 255, 255), (self._resx / 2, self._resy / 2 + 40))

                    elif len(self._client.result.winners):
                        utils.drawText(self.surface, 'Wygrali gracze %s!' % (', '.join([str(i) for i in self._client.result.winners])), 40, (255, 255, 255), (self._resx / 2, self._resy / 2 + 40))

                    self._play = False
                    self._engine.show(self.surface)
                    time.sleep(10)
                    self._engine.previousModule()
                    raise SceneQuit()

                if self._client.map:
                    if not self._map:
                        self._engine.previousModule()
                        self._play = False
                        raise SceneQuit()

                    for mine in self._client.map.mines:
                        _id = mine.position.x, mine.position.y
                        if not self._mineLayer.get(_id):
                            _mine = ObjectsLayer.Sprite(utils.loadImage('data/gfx/bomb.png', alpha = True))
                            self._mineLayer.add(_id, _mine)
                            self._mineLayer.move(_id, _id)

                    for _id, player in enumerate(self._client.map.playersPositions):
                        if not self._heroLayer.get(_id):
                            self._heroLayer.add(_id, ObjectsLayer.Sprite(utils.loadImage('data/gfx/hero/n.png', alpha = True)))

                        _hero = self._heroLayer.get(_id)
                        _pos = _hero.getPos()
                        self._heroLayer.move(_id, (player.x, player.y))
                        _newpos = _hero.getPos()
                        if _pos[0] > _newpos[0]:
                            _hero.changeImage(utils.loadImage('data/gfx/hero/w.png', alpha = True))

                        if _pos[0] < _newpos[0]:
                            _hero.changeImage(utils.loadImage('data/gfx/hero/e.png', alpha = True))

                        if _pos[1] > _newpos[1]:
                            _hero.changeImage(utils.loadImage('data/gfx/hero/n.png', alpha = True))

                        if _pos[1] < _newpos[1]:
                            _hero.changeImage(utils.loadImage('data/gfx/hero/s.png', alpha = True))

                        if _id == self._playerID:
                            _, _, w, h = self._map.getRectangle()
                            self._map.setShift((w / 2 - _newpos[0], h / 2 - _newpos[1]))

                for event in self._engine.events():
                    if event.type == QUIT:
                        raise engine.EngineQuit()

                    if event.type == KEYDOWN:
                        if event.key == K_ESCAPE:
                            self._engine.previousModule()
                            raise SceneQuit()

                        if event.key in (K_w, K_UP):
                            self._client.sendAction('u')
                            self._last = time.time()

                        elif event.key in (K_s, K_DOWN):
                            self._client.sendAction('d')
                            self._last = time.time()

                        elif event.key in (K_a, K_LEFT):
                            self._client.sendAction('l')
                            self._last = time.time()

                        elif event.key in (K_d, K_RIGHT):
                            self._client.sendAction('r')
                            self._last = time.time()

                        elif event.key in (K_RETURN, K_RCTRL, K_LCTRL):
                            self._client.sendAction('c')
                            self._last = time.time()

                        elif event.key == K_q:
                            self._client.sendAction('e')
                            self._last = time.time()

                if self._last + 1./self._engine.options['fps'] < time.time():
                    self._client.sendAction('m')
                    self._last = time.time()

                self.surface = self._background.copy()
                if not self._map:
                    utils.drawText(self.surface, 'Oczekiwanie na graczy!', 20, (255, 255, 255), (self._resx / 2, self._resy / 2))

                updated = []
                for submodule in self._submodules:
                    updated.extend(submodule.update())
                    submodule.draw(self.surface)

                if self._refresh:
                    self._engine.show(self.surface)
                    self._refresh = False

                else:
                    self._engine.show(self.surface, updated)

        except SceneQuit:
            pass
示例#18
0
    def read(self, fileName):
        file = QFile(fileName)
        if (not file.open(QIODevice.ReadOnly)):
            self.mError = self.tr("Could not open file for reading.")
            return None

        # default to values of the original flare alpha game.
        map = Map(Map.Orientation.Isometric, 256, 256, 64, 32)
        stream = QTextStream(file)
        line = QString()
        sectionName = QString()
        newsection = False
        path = QFileInfo(file).absolutePath()
        base = 10
        gidMapper = GidMapper()
        gid = 1
        tilelayer = None
        objectgroup = None
        mapobject = None
        tilesetsSectionFound = False
        headerSectionFound = False
        tilelayerSectionFound = False  # tile layer or objects
        while (not stream.atEnd()):
            line = stream.readLine()
            if line == '':
                continue
            startsWith = line[0]
            if (startsWith == '['):
                sectionName = line[1:line.index(']')]
                newsection = True
                continue

            if (sectionName == "header"):
                headerSectionFound = True
                #get map properties
                epos = line.index('=')
                if (epos != -1):
                    key = line[:epos].strip()
                    value = line[epos + 1:].strip()
                    if (key == "width"):
                        map.setWidth(Int(value))
                    elif (key == "height"):
                        map.setHeight(Int(value))
                    elif (key == "tilewidth"):
                        map.setTileWidth(Int(value))
                    elif (key == "tileheight"):
                        map.setTileHeight(Int(value))
                    elif (key == "orientation"):
                        map.setOrientation(orientationFromString(value))
                    else:
                        map.setProperty(key, value)

            elif (sectionName == "tilesets"):
                tilesetsSectionFound = True
                epos = line.index('=')
                key = line[:epos].strip()
                value = line[epos + 1:].strip()
                if (key == "tileset"):
                    _list = value.split(',')
                    absoluteSource = _list[0]
                    if (QDir.isRelativePath(absoluteSource)):
                        absoluteSource = path + '/' + absoluteSource
                    tilesetwidth = 0
                    tilesetheight = 0
                    if len(_list) > 2:
                        tilesetwidth = Int(_list[1])
                        tilesetheight = Int(_list[2])

                    tileset = Tileset.create(
                        QFileInfo(absoluteSource).fileName(), tilesetwidth,
                        tilesetheight)
                    ok = tileset.loadFromImage(absoluteSource)
                    if not ok:
                        self.mError = self.tr(
                            "Error loading tileset %s, which expands to %s. Path not found!"
                            % (_list[0], absoluteSource))
                        return None
                    else:
                        if len(_list) > 4:
                            tileset.setTileOffset(
                                QPoint(Int(_list[3]), Int(_list[4])))
                        gidMapper.insert(gid, tileset)
                        if len(_list) > 5:
                            gid += Int(_list[5])
                        else:
                            gid += tileset.tileCount()

                        map.addTileset(tileset)

            elif (sectionName == "layer"):
                if (not tilesetsSectionFound):
                    self.mError = self.tr(
                        "No tilesets section found before layer section.")
                    return None

                tilelayerSectionFound = True
                epos = line.index('=')
                if (epos != -1):
                    key = line[:epos].strip()
                    value = line[epos + 1:].strip()
                    if (key == "type"):
                        tilelayer = TileLayer(value, 0, 0, map.width(),
                                              map.height())
                        map.addLayer(tilelayer)
                    elif (key == "format"):
                        if (value == "dec"):
                            base = 10
                        elif (value == "hex"):
                            base = 16

                    elif (key == "data"):
                        for y in range(map.height()):
                            line = stream.readLine()
                            l = line.split(',')
                            for x in range(min(map.width(), len(l))):
                                ok = False
                                tileid = int(l[x], base)
                                c, ok = gidMapper.gidToCell(tileid)
                                if (not ok):
                                    self.mError += self.tr(
                                        "Error mapping tile id %1.").arg(
                                            tileid)
                                    return None

                                tilelayer.setCell(x, y, c)

                    else:
                        tilelayer.setProperty(key, value)

            else:
                if (newsection):
                    if (map.indexOfLayer(sectionName) == -1):
                        objectgroup = ObjectGroup(sectionName, 0, 0,
                                                  map.width(), map.height())
                        map.addLayer(objectgroup)
                    else:
                        objectgroup = map.layerAt(
                            map.indexOfLayer(sectionName))

                    mapobject = MapObject()
                    objectgroup.addObject(mapobject)
                    newsection = False

                if (not mapobject):
                    continue
                if (startsWith == '#'):
                    name = line[1].strip()
                    mapobject.setName(name)

                epos = line.index('=')
                if (epos != -1):
                    key = line[:epos].strip()
                    value = line[epos + 1:].strip()
                    if (key == "type"):
                        mapobject.setType(value)
                    elif (key == "location"):
                        loc = value.split(',')
                        x, y = 0.0, 0.0
                        w, h = 0, 0
                        if (map.orientation() == Map.Orthogonal):
                            x = loc[0].toFloat() * map.tileWidth()
                            y = loc[1].toFloat() * map.tileHeight()
                            if len(loc) > 3:
                                w = Int(loc[2]) * map.tileWidth()
                                h = Int(loc[3]) * map.tileHeight()
                            else:
                                w = map.tileWidth()
                                h = map.tileHeight()

                        else:
                            x = loc[0].toFloat() * map.tileHeight()
                            y = loc[1].toFloat() * map.tileHeight()
                            if len(loc) > 3:
                                w = Int(loc[2]) * map.tileHeight()
                                h = Int(loc[3]) * map.tileHeight()
                            else:
                                w = h = map.tileHeight()

                        mapobject.setPosition(QPointF(x, y))
                        mapobject.setSize(w, h)
                    else:
                        mapobject.setProperty(key, value)

        if (not headerSectionFound or not tilesetsSectionFound
                or not tilelayerSectionFound):
            self.mError = self.tr(
                "This seems to be no valid flare map. "
                "A Flare map consists of at least a header "
                "section, a tileset section and one tile layer.")
            return None

        return map
示例#19
0
class Scene(engine.Module):
    """Główny ekran gry."""

    def __init__(self, _engine):
        super(Scene, self).__init__(_engine)
        self._background = pygame.Surface((self._resx, self._resy))
        self.surface = self._background.copy()
        self._actual = []
        self._client = _engine.options['client'] = sock.BomberFactory(self._process, self._connectionError)
        from twisted.internet import reactor
        from twisted.internet.task import LoopingCall
        self._gameloop = LoopingCall(self._render)
        self._network = reactor.connectTCP(_engine.options['host'], _engine.options['port'], self._client)
        self._play = True
        self._refresh = True
        self._submodules = ()
        self._map = None
        self._playerID = None

    def __del__(self):
        self._network.disconnect()

    def _loadMap(self, _width, _height):
        self._map = Map(self._engine, self, (_width, _height))
        self._heroLayer = ObjectsLayer(self._map) # Warstwa graczy
        self._mineLayer = ObjectsLayer(self._map) # Warstwa min
        self._map.addLayer('Hero', 3, self._heroLayer)
        self._map.addLayer('Mine', 2, self._mineLayer)
        self._submodules = (self._map,)

    def isPlaying(self):
        """Czy gracz nadal gra?"""

        return self._play

    def screenUpdated(self):
        """Aktualizuje obrazy tła i submoduły."""

        super(Scene, self).screenUpdated()
        self._refresh = True
        self._background = pygame.Surface((self._resx, self._resy))
        self.surface = pygame.transform.smoothscale(self.surface, (self._resx, self._resy))
        for submodule in self._submodules:
            submodule.screenUpdated()

    def show(self):
        if not self._play:
            self._engine.previousModule()
            return

        self._last = time.time()
        from twisted.internet import reactor
        self._gameloop.start(self._engine.getFPS() and 1.0 / self._engine.getFPS() or 0.0)
        reactor.run()
        self._gameloop.stop()

    def _render(self):
        self._engine.tick()
        for event in self._engine.events():
            if event.type == QUIT:
                self._play = False

            elif event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    self._engine.runLoop = False
                    from twisted.internet import reactor
                    reactor.stop()
                    return

                if self._map:
                    if event.key in (K_w, K_UP):
                        self._client.sendAction('u')
                        self._last = time.time()

                    elif event.key in (K_s, K_DOWN):
                        self._client.sendAction('d')
                        self._last = time.time()

                    elif event.key in (K_a, K_LEFT):
                        self._client.sendAction('l')
                        self._last = time.time()

                    elif event.key in (K_d, K_RIGHT):
                        self._client.sendAction('r')
                        self._last = time.time()

                    elif event.key in (K_RETURN, K_RCTRL, K_LCTRL):
                        self._client.sendAction('c')
                        self._last = time.time()

                    elif event.key == K_q:
                        self._client.sendAction('e')
                        self._last = time.time()

        if self._map and self._last + 1./self._engine.options['fps'] < time.time():
            self._client.sendAction('m')
            self._last = time.time()

        if not self._map and self._playerID == None:
            self.surface = self._background.copy()
            utils.drawText(self.surface, 'Oczekiwanie na graczy!', 20, (255, 255, 255), (self._resx / 2, self._resy / 2))

        updated = []
        if self._play:
            for submodule in self._submodules:
                updated.extend(submodule.update())
                submodule.draw(self.surface)

        if self._refresh:
            self._engine.show(self.surface)
            self._refresh = False

        else:
            self._engine.show(self.surface, updated)

        if not self._play:
            time.sleep(5)
            self._engine.runLoop = False
            from twisted.internet import reactor
            reactor.stop()
            return

    def _process(self, obj):
        if isinstance(obj, protocolObjects.Countdown):
            return self._countdown(obj)

        if isinstance(obj, protocolObjects.Result):
            return self._finish(obj)

        if isinstance(obj, protocolObjects.Map):
            return self._update(obj)

        return self._connectionError(obj)

    def _connectionError(self, msg):
        self._play = False
        utils.drawText(self.surface, str(msg), 10, (255, 255, 255), (self._resx / 2, self._resy - 10))

    def _countdown(self, countdown):
        if not self._map and countdown.number == 1:
            self._loadMap(countdown.mapSize.x, countdown.mapSize.y)

        if self._playerID == None:
            self._playerID = countdown.playerId

        self.surface = self._background.copy()
        utils.drawText(self.surface, 'Gracz %d. >%d<' % (countdown.playerId, countdown.number), 30, (255, 255, 255), (self._resx / 2, self._resy / 2))

    def _finish(self, result):
        self.surface = self._background.copy()
        utils.drawText(self.surface, 'Gra zakonczona!', 40, (255, 255, 255), (self._resx / 2, self._resy / 2))
        if len(result.winners) == 1:
            utils.drawText(self.surface, 'Wygral gracz %d!' % result.winners[0], 40, (255, 255, 255), (self._resx / 2, self._resy / 2 + 40))

        elif len(result.winners):
            utils.drawText(self.surface, 'Wygrali gracze %s!' % (', '.join([str(i) for i in result.winners])), 40, (255, 255, 255), (self._resx / 2, self._resy / 2 + 40))

        self._play = False
        self._engine.show(self.surface)

    def _update(self, map):
        if not self._map:
            self._play = False
            return

        for mine in map.mines:
            _id = mine.position.x, mine.position.y
            if not self._mineLayer.get(_id):
                _mine = ObjectsLayer.Sprite(utils.loadImage('data/gfx/bomb.png', alpha = True))
                self._mineLayer.add(_id, _mine)
                self._mineLayer.move(_id, _id)

        for _id, player in enumerate(map.playersPositions):
            if not self._heroLayer.get(_id):
                self._heroLayer.add(_id, ObjectsLayer.Sprite(utils.loadImage('data/gfx/hero/n.png', alpha = True)))

            _hero = self._heroLayer.get(_id)
            _pos = _hero.getPos()
            self._heroLayer.move(_id, (player.x, player.y))
            _newpos = _hero.getPos()
            if _pos[0] > _newpos[0]:
                _hero.changeImage(utils.loadImage('data/gfx/hero/w.png', alpha = True))

            if _pos[0] < _newpos[0]:
                _hero.changeImage(utils.loadImage('data/gfx/hero/e.png', alpha = True))

            if _pos[1] > _newpos[1]:
                _hero.changeImage(utils.loadImage('data/gfx/hero/n.png', alpha = True))

            if _pos[1] < _newpos[1]:
                _hero.changeImage(utils.loadImage('data/gfx/hero/s.png', alpha = True))

            if _id == self._playerID:
                _, _, w, h = self._map.getRectangle()
                self._map.setShift((w / 2 - _newpos[0], h / 2 - _newpos[1]))
示例#20
0
    def read(self, fileName):
        # Read data.
        file = QFile(fileName)
        if (not file.open(QIODevice.ReadOnly)):
            self.mError = self.tr("Cannot open Replica Island map file!")
            return 0
        
        _in = QDataStream(file)
        _in.setByteOrder(QDataStream.LittleEndian)
        _in.setFloatingPointPrecision(QDataStream.SinglePrecision)
        # Parse file header.
        mapSignature = _in.readUInt8()
        layerCount = _in.readUInt8()
        backgroundIndex = _in.readUInt8()
        if (_in.status() == QDataStream.ReadPastEnd or mapSignature != 96):
            self.mError = self.tr("Can't parse file header!")
            return 0
        
        # Create our map, setting width and height to 0 until we load a layer.
        map = Map(Map.Orientation.Orthogonal, 0, 0, 32, 32)
        map.setProperty("background_index", QString.number(backgroundIndex))
        # Load our Tilesets.
        typeTilesets = QVector()
        tileIndexTilesets = QVector()
        
        self.loadTilesetsFromResources(map, typeTilesets, tileIndexTilesets)
        # Load each of our layers.
        for i in range(layerCount):
            # Parse layer header.
            _type = _in.readUInt8()
            tileIndex = _in.readUInt8()
            scrollSpeed = _in.readFloat()
            levelSignature = _in.readUInt8()
            width = _in.readUInt32()
            height = _in.readUInt32()
            if (_in.status() == QDataStream.ReadPastEnd or levelSignature != 42):
                self.mError = self.tr("Can't parse layer header!")
                return 0
            
            # Make sure our width and height are consistent.
            if (map.width() == 0):
                map.setWidth(width)
            if (map.height() == 0):
                map.setHeight(height)
            if (map.width() != width or map.height() != height):
                self.mError = self.tr("Inconsistent layer sizes!")
                return 0
            
            # Create a layer object.
            layer = TileLayer(self.layerTypeToName(_type), 0, 0, width, height)
            layer.setProperty("type", QString.number(_type))
            layer.setProperty("tile_index", QString.number(tileIndex))
            layer.setProperty("scroll_speed", QString.number(scrollSpeed, 'f'))
            map.addLayer(layer)
            # Look up the tileset for this layer.
            tileset = tilesetForLayer(_type, tileIndex, typeTilesets, tileIndexTilesets)
            # Read our tile data all at once.
            #tileData = QByteArray(width*height, b'\x00')
            bytesNeeded = width*height
            tileData = _in.readRawData(bytesNeeded)
            bytesRead = len(tileData)
            if (bytesRead != bytesNeeded):
                self.mError = self.tr("File ended in middle of layer!")
                return 0
            
            i = 0
            # Add the tiles to our layer.
            for y in range(0, height):
                for x in range(0, width):
                    tile_id = tileData[i]&0xff
                    i += 1
                    if (tile_id != 255):
                        tile = tileset.tileAt(tile_id)
                        layer.setCell(x, y, Cell(tile))

        # Make sure we read the entire *.bin file.
        if (_in.status() != QDataStream.Ok or not _in.atEnd()):
            self.mError = self.tr("Unexpected data at end of file!")
            return 0
        
        return map
示例#21
0
class MapReaderPrivate():
    def tr(self, sourceText, disambiguation='', n=-1):
        return QCoreApplication.translate('MapReader', sourceText,
                                          disambiguation, n)

    def trUtf8(self, sourceText, disambiguation='', n=-1):
        return QCoreApplication.translate('MapReader', sourceText,
                                          disambiguation, n)

    def __init__(self, mapReader):
        self.p = mapReader
        self.mMap = None
        self.mError = QString('')
        self.mReadingExternalTileset = False
        self.xml = QXmlStreamReader()
        self.mGidMapper = GidMapper()

    def readMap(self, device, path):
        self.mError = QString('')
        self.mPath = path
        map = None
        self.xml.setDevice(device)
        if (self.xml.readNextStartElement() and self.xml.name() == "map"):
            map = self.__readMap()
        else:
            self.xml.raiseError(self.tr("Not a map file."))

        self.mGidMapper.clear()
        return map

    def readTileset(self, device, path):
        self.mError = ''
        self.mPath = path
        tileset = None
        self.mReadingExternalTileset = True
        self.xml.setDevice(device)
        if (self.xml.readNextStartElement() and self.xml.name() == "tileset"):
            tileset = self.__readTileset()
        else:
            self.xml.raiseError(self.tr("Not a tileset file."))
        self.mReadingExternalTileset = False
        return tileset

    def openFile(self, file):
        if (not file.exists()):
            self.mError = self.tr("File not found: %s" % file.fileName())
            return False
        elif (not file.open(QFile.ReadOnly | QFile.Text)):
            self.mError = self.tr("Unable to read file: %s" % file.fileName())
            return False

        return True

    def errorString(self):
        if self.mError != '':
            return self.mError
        else:
            return self.tr("%d\n\nLine %d, column %s" %
                           (self.xml.lineNumber(), self.xml.columnNumber(),
                            self.xml.errorString()))

    def __readUnknownElement(self):
        qDebug("Unknown element (fixme): " + self.xml.name() + " at line " +
               self.xml.lineNumber() + ", column " + self.xml.columnNumber())
        self.xml.skipCurrentElement()

    def __readMap(self):
        atts = self.xml.attributes()
        mapWidth = Int(atts.value("width"))
        mapHeight = Int(atts.value("height"))
        tileWidth = Int(atts.value("tilewidth"))
        tileHeight = Int(atts.value("tileheight"))
        hexSideLength = Int(atts.value("hexsidelength"))
        orientationString = atts.value("orientation")
        orientation = orientationFromString(orientationString)
        if (orientation == Map.Orientation.Unknown):
            self.xml.raiseError(
                self.tr("Unsupported map orientation: \"%s\"" %
                        orientationString))

        staggerAxisString = atts.value("staggeraxis")
        staggerAxis = staggerAxisFromString(staggerAxisString)
        staggerIndexString = atts.value("staggerindex")
        staggerIndex = staggerIndexFromString(staggerIndexString)
        renderOrderString = atts.value("renderorder")
        renderOrder = renderOrderFromString(renderOrderString)
        nextObjectId = Int(atts.value("nextobjectid"))
        self.mMap = Map(orientation, mapWidth, mapHeight, tileWidth,
                        tileHeight)
        self.mMap.setHexSideLength(hexSideLength)
        self.mMap.setStaggerAxis(staggerAxis)
        self.mMap.setStaggerIndex(staggerIndex)
        self.mMap.setRenderOrder(renderOrder)
        if (nextObjectId):
            self.mMap.setNextObjectId(nextObjectId)

        bgColorString = atts.value("backgroundcolor")
        if len(bgColorString) > 0:
            self.mMap.setBackgroundColor(QColor(bgColorString))
        while (self.xml.readNextStartElement()):
            if (self.xml.name() == "properties"):
                self.mMap.mergeProperties(self.__readProperties())
            elif (self.xml.name() == "tileset"):
                self.mMap.addTileset(self.__readTileset())
            elif (self.xml.name() == "layer"):
                self.mMap.addLayer(self.__readLayer())
            elif (self.xml.name() == "objectgroup"):
                self.mMap.addLayer(self.__readObjectGroup())
            elif (self.xml.name() == "imagelayer"):
                self.mMap.addLayer(self.__readImageLayer())
            else:
                self.__readUnknownElement()

        # Clean up in case of error
        if (self.xml.hasError()):
            self.mMap = None

        return self.mMap

    def __readTileset(self):
        atts = self.xml.attributes()
        source = atts.value("source")
        firstGid = Int(atts.value("firstgid"))
        tileset = None
        if source == '':  # Not an external tileset
            name = atts.value("name")
            tileWidth = Int(atts.value("tilewidth"))
            tileHeight = Int(atts.value("tileheight"))
            tileSpacing = Int(atts.value("spacing"))
            margin = Int(atts.value("margin"))
            if (tileWidth < 0 or tileHeight < 0
                    or (firstGid == 0 and not self.mReadingExternalTileset)):
                self.xml.raiseError(
                    self.tr("Invalid tileset parameters for tileset '%s'" %
                            name))
            else:
                tileset = Tileset.create(name, tileWidth, tileHeight,
                                         tileSpacing, margin)

                while (self.xml.readNextStartElement()):
                    if (self.xml.name() == "tile"):
                        self.__readTilesetTile(tileset)
                    elif (self.xml.name() == "tileoffset"):
                        oa = self.xml.attributes()
                        x = Int(oa.value("x"))
                        y = Int(oa.value("y"))
                        tileset.setTileOffset(QPoint(x, y))
                        self.xml.skipCurrentElement()
                    elif (self.xml.name() == "properties"):
                        tileset.mergeProperties(self.__readProperties())
                    elif (self.xml.name() == "image"):
                        if (tileWidth == 0 or tileHeight == 0):
                            self.xml.raiseError(
                                self.
                                tr("Invalid tileset parameters for tileset '%s'"
                                   % name))

                            tileset.clear()
                            break
                        else:
                            self.__readTilesetImage(tileset)
                    elif (self.xml.name() == "terraintypes"):
                        self.__readTilesetTerrainTypes(tileset)
                    else:
                        self.__readUnknownElement()
        else:  # External tileset
            absoluteSource = self.p.resolveReference(source, self.mPath)
            tileset, error = self.p.readExternalTileset(absoluteSource)
            if (not tileset):
                self.xml.raiseError(
                    self.tr("Error while loading tileset '%s': %s" %
                            (absoluteSource, error)))

            self.xml.skipCurrentElement()

        if (tileset and not self.mReadingExternalTileset):
            self.mGidMapper.insert(firstGid, tileset)
        return tileset

    def __readTilesetTile(self, tileset):
        atts = self.xml.attributes()
        id = Int(atts.value("id"))
        if (id < 0):
            self.xml.raiseError(self.tr("Invalid tile ID: %d" % id))
            return

        hasImage = tileset.imageSource() != ''
        if (hasImage and id >= tileset.tileCount()):
            self.xml.raiseError(
                self.tr("Tile ID does not exist in tileset image: %d" % id))
            return

        if (id > tileset.tileCount()):
            self.xml.raiseError(
                self.tr("Invalid (nonconsecutive) tile ID: %d" % id))
            return

        # For tilesets without image source, consecutive tile IDs are allowed (for
        # tiles with individual images)
        if (id == tileset.tileCount()):
            tileset.addTile(QPixmap())
        tile = tileset.tileAt(id)
        # Read tile quadrant terrain ids
        terrain = atts.value("terrain")
        if terrain != '':
            quadrants = terrain.split(",")
            if (len(quadrants) == 4):
                for i in range(4):
                    if quadrants[i] == '':
                        t = -1
                    else:
                        t = Int(quadrants[i])
                    tile.setCornerTerrainId(i, t)

        # Read tile probability
        probability = atts.value("probability")
        if probability != '':
            tile.setProbability(Float(probability))
        while (self.xml.readNextStartElement()):
            if (self.xml.name() == "properties"):
                tile.mergeProperties(self.__readProperties())
            elif (self.xml.name() == "image"):
                source = self.xml.attributes().value("source")
                if source != '':
                    source = self.p.resolveReference(source, self.mPath)
                tileset.setTileImage(id, QPixmap.fromImage(self.__readImage()),
                                     source)
            elif (self.xml.name() == "objectgroup"):
                tile.setObjectGroup(self.__readObjectGroup())
            elif (self.xml.name() == "animation"):
                tile.setFrames(self.__readAnimationFrames())
            else:
                self.__readUnknownElement()

        # Temporary code to support TMW-style animation frame properties
        if (not tile.isAnimated() and tile.hasProperty("animation-frame0")):
            frames = QVector()
            i = 0
            while (i >= 0):
                frameName = "animation-frame" + str(i)
                delayName = "animation-delay" + str(i)
                if (tile.hasProperty(frameName)
                        and tile.hasProperty(delayName)):
                    frame = Frame()
                    frame.tileId = tile.property(frameName)
                    frame.duration = tile.property(delayName) * 10
                    frames.append(frame)
                else:
                    break
                i += 1

            tile.setFrames(frames)

    def __readTilesetImage(self, tileset):
        atts = self.xml.attributes()
        source = atts.value("source")
        trans = atts.value("trans")
        if len(trans) > 0:
            if (not trans.startswith('#')):
                trans = '#' + trans
            tileset.setTransparentColor(QColor(trans))

        if len(source) > 0:
            source = self.p.resolveReference(source, self.mPath)
        # Set the width that the tileset had when the map was saved
        width = Int(atts.value("width"))
        self.mGidMapper.setTilesetWidth(tileset, width)
        if (not tileset.loadFromImage(self.__readImage(), source)):
            self.xml.raiseError(
                self.tr("Error loading tileset image:\n'%s'" % source))

    def __readTilesetTerrainTypes(self, tileset):
        while (self.xml.readNextStartElement()):
            if (self.xml.name() == "terrain"):
                atts = self.xml.attributes()
                name = atts.value("name")
                tile = Int(atts.value("tile"))
                terrain = tileset.addTerrain(name, tile)
                while (self.xml.readNextStartElement()):
                    if (self.xml.name() == "properties"):
                        terrain.mergeProperties(self.__readProperties())
                    else:
                        self.__readUnknownElement()

            else:
                self.__readUnknownElement()

    def __readImage(self):
        atts = self.xml.attributes()
        source = atts.value("source")
        format = atts.value("format")
        if len(source) == 0:
            while (self.xml.readNextStartElement()):
                if (self.xml.name() == "data"):
                    atts = self.xml.attributes()
                    encoding = atts.value("encoding")
                    data = self.xml.readElementText().toLatin1()
                    if (encoding == "base64"):
                        data = QByteArray.fromBase64(data)

                    self.xml.skipCurrentElement()
                    return QImage.fromData(data, format.toLatin1())
                else:
                    self.__readUnknownElement()

        else:
            self.xml.skipCurrentElement()
            source = self.p.resolveReference(source, self.mPath)
            image = self.p.readExternalImage(source)
            if (image.isNull()):
                self.xml.raiseError(
                    self.tr("Error loading image:\n'%s'" % source))
            return image

        return QImage()

    def __readLayer(self):
        atts = self.xml.attributes()
        name = atts.value("name")
        x = Int(atts.value("x"))
        y = Int(atts.value("y"))
        width = Int(atts.value("width"))
        height = Int(atts.value("height"))
        tileLayer = TileLayer(name, x, y, width, height)
        readLayerAttributes(tileLayer, atts)
        while (self.xml.readNextStartElement()):
            if (self.xml.name() == "properties"):
                tileLayer.mergeProperties(self.__readProperties())
            elif (self.xml.name() == "data"):
                self.__readLayerData(tileLayer)
            else:
                self.__readUnknownElement()

        return tileLayer

    def __readLayerData(self, tileLayer):
        atts = self.xml.attributes()
        encoding = atts.value("encoding")
        compression = atts.value("compression")
        layerDataFormat = 0
        if (encoding == ''):
            layerDataFormat = Map.LayerDataFormat.XML
        elif (encoding == "csv"):
            layerDataFormat = Map.LayerDataFormat.CSV
        elif (encoding == "base64"):
            if (compression == ''):
                layerDataFormat = Map.LayerDataFormat.Base64
            elif (compression == "gzip"):
                layerDataFormat = Map.LayerDataFormat.Base64Gzip
            elif (compression == "zlib"):
                layerDataFormat = Map.LayerDataFormat.Base64Zlib
            else:
                self.xml.raiseError(
                    self.tr("Compression method '%s' not supported" %
                            compression))
                return
        else:
            self.xml.raiseError(self.tr("Unknown encoding: %s" % encoding))
            return

        self.mMap.setLayerDataFormat(layerDataFormat)

        x = 0
        y = 0
        while (self.xml.readNext() != QXmlStreamReader.Invalid):
            if (self.xml.isEndElement()):
                break
            elif (self.xml.isStartElement()):
                if (self.xml.name() == "tile"):
                    if (y >= tileLayer.height()):
                        self.xml.raiseError(
                            self.tr("Too many <tile> elements"))
                        continue

                    atts = self.xml.attributes()
                    gid = Int(atts.value("gid"))
                    tileLayer.setCell(x, y, self.__cellForGid(gid))
                    x += 1
                    if (x >= tileLayer.width()):
                        x = 0
                        y += 1

                    self.xml.skipCurrentElement()
                else:
                    self.__readUnknownElement()
            elif (self.xml.isCharacters() and not self.xml.isWhitespace()):
                if (encoding == "base64"):
                    self.__decodeBinaryLayerData(tileLayer, self.xml.text(),
                                                 layerDataFormat)
                elif (encoding == "csv"):
                    self.__decodeCSVLayerData(tileLayer, self.xml.text())

    def __decodeBinaryLayerData(self, tileLayer, data, format):
        error = self.mGidMapper.decodeLayerData(tileLayer, data, format)

        if error == DecodeError.CorruptLayerData:
            self.xml.raiseError(
                self.tr("Corrupt layer data for layer '%s'" %
                        tileLayer.name()))
            return
        elif error == DecodeError.TileButNoTilesets:
            self.xml.raiseError(self.tr("Tile used but no tilesets specified"))
            return
        elif error == DecodeError.InvalidTile:
            self.xml.raiseError(
                self.tr("Invalid tile: %d" % self.mGidMapper.invalidTile()))
            return
        elif error == DecodeError.NoError:
            pass

    def __decodeCSVLayerData(self, tileLayer, text):
        trimText = text.strip()
        tiles = trimText.split(',')
        if (len(tiles) != tileLayer.width() * tileLayer.height()):
            self.xml.raiseError(
                self.tr("Corrupt layer data for layer '%s'" %
                        tileLayer.name()))
            return

        for y in range(tileLayer.height()):
            for x in range(tileLayer.width()):
                conversionOk = False
                gid, conversionOk = Int2(tiles[y * tileLayer.width() + x])
                if (not conversionOk):
                    self.xml.raiseError(
                        self.tr(
                            "Unable to parse tile at (%d,%d) on layer '%s'" %
                            (x + 1, y + 1, tileLayer.name())))
                    return

                tileLayer.setCell(x, y, self.__cellForGid(gid))

    ##
    # Returns the cell for the given global tile ID. Errors are raised with
    # the QXmlStreamReader.
    #
    # @param gid the global tile ID
    # @return the cell data associated with the given global tile ID, or an
    #         empty cell if not found
    ##
    def __cellForGid(self, gid):
        ok = False
        result, ok = self.mGidMapper.gidToCell(gid)
        if (not ok):
            if (self.mGidMapper.isEmpty()):
                self.xml.raiseError(
                    self.tr("Tile used but no tilesets specified"))
            else:
                self.xml.raiseError(self.tr("Invalid tile: %d" % gid))

        return result

    def __readImageLayer(self):
        atts = self.xml.attributes()
        name = atts.value("name")
        x = Int(atts.value("x"))
        y = Int(atts.value("y"))
        width = Int(atts.value("width"))
        height = Int(atts.value("height"))
        imageLayer = ImageLayer(name, x, y, width, height)
        readLayerAttributes(imageLayer, atts)
        while (self.xml.readNextStartElement()):
            if (self.xml.name() == "image"):
                self.__readImageLayerImage(imageLayer)
            elif (self.xml.name() == "properties"):
                imageLayer.mergeProperties(self.__readProperties())
            else:
                self.__readUnknownElement()

        return imageLayer

    def __readImageLayerImage(self, imageLayer):
        atts = self.xml.attributes()
        source = atts.value("source")
        trans = atts.value("trans")
        if trans != '':
            if (not trans.startswith('#')):
                trans = '#' + trans
            imageLayer.setTransparentColor(QColor(trans))

        source = self.p.resolveReference(source, self.mPath)
        imageLayerImage = self.p.readExternalImage(source)
        if (not imageLayer.loadFromImage(imageLayerImage, source)):
            self.xml.raiseError(
                self.tr("Error loading image layer image:\n'%s'" % source))
        self.xml.skipCurrentElement()

    def __readObjectGroup(self):
        atts = self.xml.attributes()
        name = atts.value("name")
        x = Int(atts.value("x"))
        y = Int(atts.value("y"))
        width = Int(atts.value("width"))
        height = Int(atts.value("height"))
        objectGroup = ObjectGroup(name, x, y, width, height)
        readLayerAttributes(objectGroup, atts)
        color = atts.value("color")
        if color != '':
            objectGroup.setColor(color)
        if (atts.hasAttribute("draworder")):
            value = atts.value("draworder")
            drawOrder = drawOrderFromString(value)
            if (drawOrder == ObjectGroup.DrawOrder.UnknownOrder):
                #del objectGroup
                self.xml.raiseError(self.tr("Invalid draw order: %s" % value))
                return None

            objectGroup.setDrawOrder(drawOrder)

        while (self.xml.readNextStartElement()):
            if (self.xml.name() == "object"):
                objectGroup.addObject(self.__readObject())
            elif (self.xml.name() == "properties"):
                objectGroup.mergeProperties(self.__readProperties())
            else:
                self.__readUnknownElement()

        return objectGroup

    def __readObject(self):
        atts = self.xml.attributes()
        id = Int(atts.value("id"))
        name = atts.value("name")
        gid = Int(atts.value("gid"))
        x = Float(atts.value("x"))
        y = Float(atts.value("y"))
        width = Float(atts.value("width"))
        height = Float(atts.value("height"))
        type = atts.value("type")
        visibleRef = atts.value("visible")
        pos = QPointF(x, y)
        size = QSizeF(width, height)
        object = MapObject(name, type, pos, size)
        object.setId(id)

        try:
            rotation = Float(atts.value("rotation"))
            ok = True
        except:
            ok = False
        if (ok):
            object.setRotation(rotation)
        if (gid):
            object.setCell(self.__cellForGid(gid))
            if (not object.cell().isEmpty()):
                tileSize = object.cell().tile.size()
                if (width == 0):
                    object.setWidth(tileSize.width())
                if (height == 0):
                    object.setHeight(tileSize.height())

        try:
            visible = int(visibleRef)
            ok = True
        except:
            ok = False
        if ok:
            object.setVisible(visible)
        while (self.xml.readNextStartElement()):
            if (self.xml.name() == "properties"):
                object.mergeProperties(self.__readProperties())
            elif (self.xml.name() == "polygon"):
                object.setPolygon(self.__readPolygon())
                object.setShape(MapObject.Polygon)
            elif (self.xml.name() == "polyline"):
                object.setPolygon(self.__readPolygon())
                object.setShape(MapObject.Polyline)
            elif (self.xml.name() == "ellipse"):
                self.xml.skipCurrentElement()
                object.setShape(MapObject.Ellipse)
            else:
                self.__readUnknownElement()

        return object

    def __readPolygon(self):
        atts = self.xml.attributes()
        points = atts.value("points")
        pointsList = list(filter(lambda x: x.strip() != '', points.split(' ')))
        polygon = QPolygonF()
        ok = True
        for point in pointsList:
            try:
                x, y = point.split(',')
            except:
                ok = False
                break

            x, ok = Float2(x)
            if (not ok):
                break

            y, ok = Float2(y)
            if (not ok):
                break
            polygon.append(QPointF(x, y))

        if (not ok):
            self.xml.raiseError(self.tr("Invalid points data for polygon"))
        self.xml.skipCurrentElement()
        return polygon

    def __readAnimationFrames(self):
        frames = QVector()
        while (self.xml.readNextStartElement()):
            if (self.xml.name() == "frame"):
                atts = self.xml.attributes()
                frame = Frame()
                frame.tileId = Int(atts.value("tileid"))
                frame.duration = Int(atts.value("duration"))
                frames.append(frame)
                self.xml.skipCurrentElement()
            else:
                self.__readUnknownElement()

        return frames

    def __readProperties(self):
        properties = Properties()
        while (self.xml.readNextStartElement()):
            if (self.xml.name() == "property"):
                self.__readProperty(properties)
            else:
                self.__readUnknownElement()

        return properties

    def __readProperty(self, properties):
        atts = self.xml.attributes()
        propertyName = atts.value("name")
        propertyValue = atts.value("value")
        while (self.xml.readNext() != QXmlStreamReader.Invalid):
            if (self.xml.isEndElement()):
                break
            elif (self.xml.isCharacters() and not self.xml.isWhitespace()):
                if (propertyValue.isEmpty()):
                    propertyValue = self.xml.text()
            elif (self.xml.isStartElement()):
                self.__readUnknownElement()

        properties.insert(propertyName, propertyValue)
示例#22
0
    def read(self, fileName):
        # Read data.
        file = QFile(fileName)
        if (not file.open(QIODevice.ReadOnly)):
            self.mError = self.tr("Cannot open Replica Island map file!")
            return 0

        _in = QDataStream(file)
        _in.setByteOrder(QDataStream.LittleEndian)
        _in.setFloatingPointPrecision(QDataStream.SinglePrecision)
        # Parse file header.
        mapSignature = _in.readUInt8()
        layerCount = _in.readUInt8()
        backgroundIndex = _in.readUInt8()
        if (_in.status() == QDataStream.ReadPastEnd or mapSignature != 96):
            self.mError = self.tr("Can't parse file header!")
            return 0

        # Create our map, setting width and height to 0 until we load a layer.
        map = Map(Map.Orientation.Orthogonal, 0, 0, 32, 32)
        map.setProperty("background_index", QString.number(backgroundIndex))
        # Load our Tilesets.
        typeTilesets = QVector()
        tileIndexTilesets = QVector()

        self.loadTilesetsFromResources(map, typeTilesets, tileIndexTilesets)
        # Load each of our layers.
        for i in range(layerCount):
            # Parse layer header.
            _type = _in.readUInt8()
            tileIndex = _in.readUInt8()
            scrollSpeed = _in.readFloat()
            levelSignature = _in.readUInt8()
            width = _in.readUInt32()
            height = _in.readUInt32()
            if (_in.status() == QDataStream.ReadPastEnd
                    or levelSignature != 42):
                self.mError = self.tr("Can't parse layer header!")
                return 0

            # Make sure our width and height are consistent.
            if (map.width() == 0):
                map.setWidth(width)
            if (map.height() == 0):
                map.setHeight(height)
            if (map.width() != width or map.height() != height):
                self.mError = self.tr("Inconsistent layer sizes!")
                return 0

            # Create a layer object.
            layer = TileLayer(self.layerTypeToName(_type), 0, 0, width, height)
            layer.setProperty("type", QString.number(_type))
            layer.setProperty("tile_index", QString.number(tileIndex))
            layer.setProperty("scroll_speed", QString.number(scrollSpeed, 'f'))
            map.addLayer(layer)
            # Look up the tileset for this layer.
            tileset = tilesetForLayer(_type, tileIndex, typeTilesets,
                                      tileIndexTilesets)
            # Read our tile data all at once.
            #tileData = QByteArray(width*height, b'\x00')
            bytesNeeded = width * height
            tileData = _in.readRawData(bytesNeeded)
            bytesRead = len(tileData)
            if (bytesRead != bytesNeeded):
                self.mError = self.tr("File ended in middle of layer!")
                return 0

            i = 0
            # Add the tiles to our layer.
            for y in range(0, height):
                for x in range(0, width):
                    tile_id = tileData[i] & 0xff
                    i += 1
                    if (tile_id != 255):
                        tile = tileset.tileAt(tile_id)
                        layer.setCell(x, y, Cell(tile))

        # Make sure we read the entire *.bin file.
        if (_in.status() != QDataStream.Ok or not _in.atEnd()):
            self.mError = self.tr("Unexpected data at end of file!")
            return 0

        return map
示例#23
0
class Scene(engine.Module):
    """Główny ekran gry."""
    def __init__(self, _engine):
        super(Scene, self).__init__(_engine)
        self.side = utils.loadImage('data/gfx/side.png')
        self._background = pygame.Surface((self._resx, self._resy))
        self._background.blit(self.side, (self._resx - 232, self._resy - 1500))
        self.surface = self._background.copy()
        self._actual = []
        self._level = utils.loadLevel('data/level.dat')
        self._map = Map(_engine, self, self._level)
        self._minimap = Minimap(_engine, self._map)
        self._cursor = Cursor(_engine, self._map)
        self._creatureLayer = CreatureLayer(self._map,
                                            self._cursor)  # Warstwa potworów
        self._map.addLayer('Creatures', 2, self._creatureLayer)
        self._map.addLayer('Missiles', 3, MissilesLayer(
            self._map))  # Warstwa pocisków(strzał, kuli ognia itp.)
        self._shadow = ShadowLayer(self._map)
        self._map.addLayer('Shadow', 5, self._shadow)  # Mgła wojny
        self._monsters = []
        self._freeobjects = pygame.sprite.Group()  # Wolne obiekty na scenie
        _counter = 0
        _start = 0
        # szukanie bohatera w lochu
        for l, storey in enumerate(self._level):
            for row in storey:
                for cell in row:
                    if cell.getModifier() & field.MODIFIER_HERO:
                        self._hero = hero.Hero(self._map,
                                               cell.getGrid() + (l, ))
                        self._hero.move((0, 0, 0))
                        self._map.switchStorey(l)
                        _start = l
                        self._creatureLayer.add(
                            'hero',
                            self._hero.getSprite(self._creatureLayer, 'hero'))
                        break

        # szukanie potworów
        for l, storey in enumerate(self._level):
            for row in storey:
                for cell in row:
                    if cell.getModifier() & field.MODIFIER_SPIDER:
                        _monster = Spider(self._map, cell.getGrid() + (l, ))
                        self._monsters.append(('spider', _monster))
                        if l == _start:
                            self._creatureLayer.add(
                                'spider_' + str(_counter),
                                _monster.getSprite(self._creatureLayer,
                                                   'spider_' + str(_counter)))
                            self._actual.append(
                                ('spider_' + str(_counter), _monster))
                            _monster.move((0, 0, 0))
                            _counter += 1

                    elif cell.getModifier() & field.MODIFIER_SKELETON:
                        _monster = Skeleton(self._map, cell.getGrid() + (l, ))
                        self._monsters.append(('skeleton', _monster))
                        if l == _start:
                            self._creatureLayer.add(
                                'skeleton_' + str(_counter),
                                _monster.getSprite(self._creatureLayer,
                                                   'skeleton_' +
                                                   str(_counter)))
                            self._actual.append(
                                ('skeleton_' + str(_counter), _monster))
                            _monster.move((0, 0, 0))
                            _counter += 1

                    elif cell.getModifier() & field.MODIFIER_MAGE:
                        _monster = Mage(self._map, cell.getGrid() + (l, ))
                        self._monsters.append(('mage', _monster))
                        if l == _start:
                            self._creatureLayer.add(
                                'mage_' + str(_counter),
                                _monster.getSprite(self._creatureLayer,
                                                   'mage_' + str(_counter)))
                            self._actual.append(
                                ('mage_' + str(_counter), _monster))
                            _monster.move((0, 0, 0))
                            _counter += 1

                    elif cell.getModifier() & field.MODIFIER_TROLL:
                        _monster = Troll(self._map, cell.getGrid() + (l, ))
                        self._monsters.append(('troll', _monster))
                        if l == _start:
                            self._creatureLayer.add(
                                'troll_' + str(_counter),
                                _monster.getSprite(self._creatureLayer,
                                                   'troll_' + str(_counter)))
                            self._actual.append(
                                ('troll_' + str(_counter), _monster))
                            _monster.move((0, 0, 0))
                            _counter += 1

        if not self._hero:
            raise Exception('Brak bohatera w lochu!?')

        self._statusbar = StatusBar(
            _engine, self._hero)  # pasek życia/many itp. / statusu
        self.inventory = Inventory(_engine, self._hero, self._hero.inventory,
                                   self._freeobjects)
        self.chestitems = ChestItems(_engine, self._hero, self._freeobjects)
        self._submodules = (self._map, self._minimap, self._statusbar,
                            self.inventory, self.chestitems, self._cursor)
        self._play = True
        self._refresh = True

    def isPlaying(self):
        """Czy gracz nadal gra?"""

        return self._play

    def screenUpdated(self):
        """Aktualizuje obrazy tła i submoduły."""

        super(Scene, self).screenUpdated()
        self._refresh = True
        self._background = pygame.Surface((self._resx, self._resy))
        self._background.blit(self.side, (self._resx - 232, self._resy - 1500))
        self.surface = pygame.transform.smoothscale(self.surface,
                                                    (self._resx, self._resy))
        for submodule in self._submodules:
            submodule.screenUpdated()

    def show(self):
        if not self._play:
            self._engine.previousModule()
            return

        try:
            while self._engine.tick():
                for event in self._engine.events():
                    if event.type == QUIT:
                        raise engine.EngineQuit()

                    if event.type == KEYDOWN:
                        if event.key == K_ESCAPE:
                            self._engine.previousModule()
                            raise SceneQuit()

                        elif event.key in hero.MAGIC_KEYS:
                            self._hero.setSpell(hero.KEY_MAP[event.key])

                    if event.type in (MOUSEMOTION, MOUSEBUTTONDOWN,
                                      MOUSEBUTTONUP):
                        for submodule in self._submodules:
                            if submodule.getRectangle().collidepoint(
                                    event.pos):
                                x, y, _, _ = submodule.getRectangle()
                                _pos = event.pos[0] - x, event.pos[1] - y

                            else:
                                _pos = None

                            submodule.mouseEvent(event, _pos)
                            if submodule == self._map and event.type == MOUSEBUTTONDOWN and _pos:  # obsługa otwierania skrzynki(głównie)
                                _field = self._map.getLayer('Fields').get(
                                    _pos, True)
                                if _field:
                                    _field.getLogic().clicked(self, self._hero)

                            if submodule == self._map and event.type == MOUSEBUTTONUP and event.button == 1 and _pos:  # upuszczanie przedmiotu
                                _field = self._map.getLayer('Fields').get(
                                    _pos, True)
                                if _field:
                                    _field = _field.getLogic()

                                if _field and utils.distance(
                                        _field.getGrid()[:2],
                                        self._hero.getGrid()[:2]) <= 1:
                                    for _obj in self._freeobjects:
                                        if not _obj.attach(_field):
                                            _obj.attach(_obj.getAttached())
                                else:
                                    for _obj in self._freeobjects:
                                        _obj.attach(_obj.getAttached())

                            if submodule == self.inventory and event.type == MOUSEBUTTONUP and event.button == 1 and _pos:  # ↑
                                for _obj in self._freeobjects:
                                    if not _obj.attach(
                                            self.inventory.getCell(_pos)):
                                        _obj.attach(_obj.getAttached())

                            if submodule == self.chestitems and event.type == MOUSEBUTTONUP and event.button == 1 and _pos:  # ↑
                                for _obj in self._freeobjects:
                                    if not self.chestitems.opened or not _obj.attach(
                                            self.chestitems.getCell(_pos)):
                                        _obj.attach(_obj.getAttached())

                        for _obj in self._freeobjects:
                            _obj.mouseEvent(event)

                        if event.type == MOUSEBUTTONDOWN and event.button == 3 and self._map.getRectangle(
                        ).collidepoint(event.pos):  # rzucanie czaru
                            self._hero.castSpell()

                        if event.type == MOUSEBUTTONDOWN and event.button == 1 and self._map.getRectangle(
                        ).collidepoint(event.pos):  # atak
                            self._hero.punch()

                if self._hero.getGrid()[2] != self._map.getStorey(
                ):  # zmiana poziomu lochu
                    self._map.removeLayer('Missiles')
                    self._map.addLayer('Missiles', 3, MissilesLayer(self._map))
                    self._map.switchStorey(self._hero.getGrid()[2] -
                                           self._map.getStorey())
                    self._shadow.clear()
                    for _id, _ in self._actual:
                        self._creatureLayer.remove(_id)

                    self._actual = []
                    _counter = 0
                    _storey = self._map.getStorey()
                    for _name, _monster in self._monsters:
                        if _monster.getGrid()[2] == _storey:
                            self._creatureLayer.add(
                                _name + '_' + str(_counter),
                                _monster.getSprite(self._creatureLayer, _name +
                                                   '_' + str(_counter)))
                            self._actual.append(
                                (_name + '_' + str(_counter), _monster))
                            _monster.move((0, 0, 0))
                            _counter += 1

                else:
                    for key in hero.DIRECTION_KEYS:
                        if pygame.key.get_pressed()[key]:
                            self._hero.move(hero.KEY_MAP[key])

                if self._hero.getDestination(
                ):  # przesuwanie mapy za bohaterem
                    x, y = self._hero.getPos()
                    _, _, w, h = self._map.getRectangle()
                    self._map.setShift((w / 2 - x, h / 2 - y))

                if not self._hero.getLife():  # przegrana
                    utils.drawText(self.surface, "Game Over", 40,
                                   (255, 255, 255),
                                   (self._resx / 2, self._resy / 2))
                    self._play = False
                    self._engine.show(self.surface)
                    time.sleep(3)
                    self._engine.previousModule()
                    raise SceneQuit()

                if not self._monsters:  # wygrana
                    utils.drawText(self.surface, "Win", 50, (255, 255, 255),
                                   (self._resx / 2, self._resy / 2))
                    self._play = False
                    self._engine.show(self.surface)
                    time.sleep(3)
                    self._engine.previousModule()
                    raise SceneQuit()

                _hero = self._hero.getPos()
                _shift = self._map.getShift()
                _hero = _hero[0] + _shift[0], _hero[1] + _shift[1]
                _mouse = pygame.mouse.get_pos()
                _mouse = _mouse[0] - _hero[0], _mouse[1] - _hero[1]
                _angle = utils.vectorAngle((0, 1), _mouse)
                if -45 <= _angle < 45:
                    self._hero.setDirection('s')

                elif -135 <= _angle < -45:
                    self._hero.setDirection('e')

                elif 45 <= _angle < 135:
                    self._hero.setDirection('w')

                else:
                    self._hero.setDirection('n')

                self._shadow.reveal(self._hero.getPos())
                self.surface = self._background.copy()
                updated = []
                for submodule in self._submodules:
                    updated.extend(submodule.update())
                    submodule.draw(self.surface)

                for _obj in self._freeobjects:
                    updated.extend(_obj.update())
                    _obj.draw(self.surface)

                if self._refresh:
                    self._engine.show(self.surface)
                    self._refresh = False

                else:
                    self._engine.show(self.surface, updated)

                _actual = []
                for _id, _monster in self._actual:
                    if _monster.getGrid()[2] != self._map.getStorey():
                        self._creatureLayer.remove(_id)

                    else:
                        _actual.append((_id, _monster))

                self._actual = _actual
                for _id, _monster in self._monsters:  # umierające potwory dodają exp bohaterowi
                    if not _monster.getLife():
                        self._monsters.remove((_id, _monster))
                        self._hero.addExperience(_monster.stats['experience'])

        except SceneQuit:
            pass
示例#24
0
class Scene(engine.Module):
	"""Główny ekran gry."""

	def __init__(self, _engine):
		super(Scene, self).__init__(_engine)
		self.side = utils.loadImage('data/gfx/side.png')
		self._background = pygame.Surface((self._resx, self._resy))
		self._background.blit(self.side, (self._resx - 232, self._resy - 1500))
		self.surface = self._background.copy()
		self._actual = []
		self._level = utils.loadLevel('data/level.dat')
		self._map = Map(_engine, self, self._level)
		self._minimap = Minimap(_engine, self._map)
		self._cursor = Cursor(_engine, self._map)
		self._creatureLayer = CreatureLayer(self._map, self._cursor) # Warstwa potworów
		self._map.addLayer('Creatures', 2, self._creatureLayer)
		self._map.addLayer('Missiles', 3, MissilesLayer(self._map)) # Warstwa pocisków(strzał, kuli ognia itp.)
		self._shadow = ShadowLayer(self._map)
		self._map.addLayer('Shadow', 5, self._shadow) # Mgła wojny
		self._monsters = []
		self._freeobjects = pygame.sprite.Group() # Wolne obiekty na scenie
		_counter = 0
		_start = 0
		# szukanie bohatera w lochu
		for l, storey in enumerate(self._level):
			for row in storey:
				for cell in row:
					if cell.getModifier() & field.MODIFIER_HERO:
						self._hero = hero.Hero(self._map, cell.getGrid() + (l,))
						self._hero.move((0, 0, 0))
						self._map.switchStorey(l)
						_start = l
						self._creatureLayer.add('hero', self._hero.getSprite(self._creatureLayer, 'hero'))
						break

		# szukanie potworów
		for l, storey in enumerate(self._level):
			for row in storey:
				for cell in row:
					if cell.getModifier() & field.MODIFIER_SPIDER:
						_monster = Spider(self._map, cell.getGrid() + (l,))
						self._monsters.append(('spider', _monster))
						if l == _start:
							self._creatureLayer.add('spider_' + str(_counter), _monster.getSprite(self._creatureLayer, 'spider_' + str(_counter)))
							self._actual.append(('spider_' + str(_counter), _monster))
							_monster.move((0, 0, 0))
							_counter += 1

					elif cell.getModifier() & field.MODIFIER_SKELETON:
						_monster = Skeleton(self._map, cell.getGrid() + (l,))
						self._monsters.append(('skeleton', _monster))
						if l == _start:
							self._creatureLayer.add('skeleton_' + str(_counter), _monster.getSprite(self._creatureLayer, 'skeleton_' + str(_counter)))
							self._actual.append(('skeleton_' + str(_counter), _monster))
							_monster.move((0, 0, 0))
							_counter += 1

					elif cell.getModifier() & field.MODIFIER_MAGE:
						_monster = Mage(self._map, cell.getGrid() + (l,))
						self._monsters.append(('mage', _monster))
						if l == _start:
							self._creatureLayer.add('mage_' + str(_counter), _monster.getSprite(self._creatureLayer, 'mage_' + str(_counter)))
							self._actual.append(('mage_' + str(_counter), _monster))
							_monster.move((0, 0, 0))
							_counter += 1

					elif cell.getModifier() & field.MODIFIER_TROLL:
						_monster = Troll(self._map, cell.getGrid() + (l,))
						self._monsters.append(('troll', _monster))
						if l == _start:
							self._creatureLayer.add('troll_' + str(_counter), _monster.getSprite(self._creatureLayer, 'troll_' + str(_counter)))
							self._actual.append(('troll_' + str(_counter), _monster))
							_monster.move((0, 0, 0))
							_counter += 1

		if not self._hero:
			raise Exception('Brak bohatera w lochu!?')

		self._statusbar = StatusBar(_engine, self._hero) # pasek życia/many itp. / statusu
		self.inventory = Inventory(_engine, self._hero, self._hero.inventory, self._freeobjects)
		self.chestitems = ChestItems(_engine, self._hero, self._freeobjects)
		self._submodules = (self._map, self._minimap, self._statusbar, self.inventory, self.chestitems, self._cursor)
		self._play = True
		self._refresh = True

	def isPlaying(self):
		"""Czy gracz nadal gra?"""

		return self._play

	def screenUpdated(self):
		"""Aktualizuje obrazy tła i submoduły."""

		super(Scene, self).screenUpdated()
		self._refresh = True
		self._background = pygame.Surface((self._resx, self._resy))
		self._background.blit(self.side, (self._resx - 232, self._resy - 1500))
		self.surface = pygame.transform.smoothscale(self.surface, (self._resx, self._resy))
		for submodule in self._submodules:
			submodule.screenUpdated()

	def show(self):
		if not self._play:
			self._engine.previousModule()
			return

		try:
			while self._engine.tick():
				for event in self._engine.events():
					if event.type == QUIT:
						raise engine.EngineQuit()

					if event.type == KEYDOWN:
						if event.key == K_ESCAPE:
							self._engine.previousModule()
							raise SceneQuit()

						elif event.key in hero.MAGIC_KEYS:
							self._hero.setSpell(hero.KEY_MAP[event.key])

					if event.type in (MOUSEMOTION, MOUSEBUTTONDOWN, MOUSEBUTTONUP):
						for submodule in self._submodules:
							if submodule.getRectangle().collidepoint(event.pos):
								x, y, _, _ = submodule.getRectangle()
								_pos = event.pos[0] - x, event.pos[1] - y

							else:
								_pos = None

							submodule.mouseEvent(event, _pos)
							if submodule == self._map and event.type == MOUSEBUTTONDOWN and _pos: # obsługa otwierania skrzynki(głównie)
								_field = self._map.getLayer('Fields').get(_pos, True)
								if _field:
									_field.getLogic().clicked(self, self._hero)

							if submodule == self._map and event.type == MOUSEBUTTONUP and event.button == 1 and _pos: # upuszczanie przedmiotu
								_field = self._map.getLayer('Fields').get(_pos, True)
								if _field:
									_field = _field.getLogic()

								if _field and utils.distance(_field.getGrid()[:2], self._hero.getGrid()[:2]) <= 1:
									for _obj in self._freeobjects:
										if not _obj.attach(_field):
											_obj.attach(_obj.getAttached())
								else:
									for _obj in self._freeobjects:
										_obj.attach(_obj.getAttached())

							if submodule == self.inventory and event.type == MOUSEBUTTONUP and event.button == 1 and _pos: # ↑
								for _obj in self._freeobjects:
									if not _obj.attach(self.inventory.getCell(_pos)):
										_obj.attach(_obj.getAttached())

							if submodule == self.chestitems and event.type == MOUSEBUTTONUP and event.button == 1 and _pos: # ↑
								for _obj in self._freeobjects:
									if not self.chestitems.opened or not _obj.attach(self.chestitems.getCell(_pos)):
										_obj.attach(_obj.getAttached())

						for _obj in self._freeobjects:
							_obj.mouseEvent(event)

						if event.type == MOUSEBUTTONDOWN and event.button == 3 and self._map.getRectangle().collidepoint(event.pos): # rzucanie czaru
							self._hero.castSpell()

						if event.type == MOUSEBUTTONDOWN and event.button == 1 and self._map.getRectangle().collidepoint(event.pos): # atak
							self._hero.punch()

				if self._hero.getGrid()[2] != self._map.getStorey(): # zmiana poziomu lochu
					self._map.removeLayer('Missiles')
					self._map.addLayer('Missiles', 3, MissilesLayer(self._map))
					self._map.switchStorey(self._hero.getGrid()[2] - self._map.getStorey())
					self._shadow.clear()
					for _id, _ in self._actual:
						self._creatureLayer.remove(_id)

					self._actual = []
					_counter = 0
					_storey = self._map.getStorey()
					for _name, _monster in self._monsters:
						if _monster.getGrid()[2] == _storey:
							self._creatureLayer.add(_name + '_' + str(_counter), _monster.getSprite(self._creatureLayer, _name + '_' + str(_counter)))
							self._actual.append((_name + '_' + str(_counter), _monster))
							_monster.move((0, 0, 0))
							_counter += 1

				else:
					for key in hero.DIRECTION_KEYS:
						if pygame.key.get_pressed()[key]:
							self._hero.move(hero.KEY_MAP[key])

				if self._hero.getDestination(): # przesuwanie mapy za bohaterem
					x, y = self._hero.getPos()
					_, _, w, h = self._map.getRectangle()
					self._map.setShift((w / 2 - x, h / 2 - y))

				if not self._hero.getLife(): # przegrana
					utils.drawText(self.surface, "Game Over", 40, (255, 255, 255), (self._resx / 2, self._resy / 2))
					self._play = False
					self._engine.show(self.surface)
					time.sleep(3)
					self._engine.previousModule()
					raise SceneQuit()

				if not self._monsters: # wygrana
					utils.drawText(self.surface, "Win", 50, (255, 255, 255), (self._resx / 2, self._resy / 2))
					self._play = False
					self._engine.show(self.surface)
					time.sleep(3)
					self._engine.previousModule()
					raise SceneQuit()

				_hero = self._hero.getPos()
				_shift = self._map.getShift()
				_hero = _hero[0] + _shift[0], _hero[1] + _shift[1]
				_mouse = pygame.mouse.get_pos()
				_mouse = _mouse[0] - _hero[0], _mouse[1] - _hero[1]
				_angle = utils.vectorAngle((0, 1), _mouse)
				if -45 <= _angle < 45:
					self._hero.setDirection('s')

				elif -135 <= _angle < -45:
					self._hero.setDirection('e')

				elif 45 <= _angle < 135:
					self._hero.setDirection('w')

				else:
					self._hero.setDirection('n')

				self._shadow.reveal(self._hero.getPos())
				self.surface = self._background.copy()
				updated = []
				for submodule in self._submodules:
					updated.extend(submodule.update())
					submodule.draw(self.surface)

				for _obj in self._freeobjects:
					updated.extend(_obj.update())
					_obj.draw(self.surface)

				if self._refresh:
					self._engine.show(self.surface)
					self._refresh = False

				else:
					self._engine.show(self.surface, updated)

				_actual = []
				for _id, _monster in self._actual:
					if _monster.getGrid()[2] != self._map.getStorey():
						self._creatureLayer.remove(_id)

					else:
						_actual.append((_id, _monster))

				self._actual = _actual
				for _id, _monster in self._monsters: # umierające potwory dodają exp bohaterowi
					if not _monster.getLife():
						self._monsters.remove((_id, _monster))
						self._hero.addExperience(_monster.stats['experience'])

		except SceneQuit:
			pass
示例#25
0
class MapReaderPrivate():
    def tr(self, sourceText, disambiguation = '', n = -1):
        return QCoreApplication.translate('MapReader', sourceText, disambiguation, n)

    def trUtf8(self, sourceText, disambiguation = '', n = -1):
        return QCoreApplication.translate('MapReader', sourceText, disambiguation, n)

    def __init__(self, mapReader):
        self.p = mapReader
        self.mMap = None
        self.mError = QString('')
        self.mReadingExternalTileset = False
        self.xml = QXmlStreamReader()
        self.mGidMapper = GidMapper()

    def readMap(self, device, path):
        self.mError = QString('')
        self.mPath = path
        map = None
        self.xml.setDevice(device)
        if (self.xml.readNextStartElement() and self.xml.name() == "map"):
            map = self.__readMap()
        else:
            self.xml.raiseError(self.tr("Not a map file."))

        self.mGidMapper.clear()
        return map

    def readTileset(self, device, path):
        self.mError = ''
        self.mPath = path
        tileset = None
        self.mReadingExternalTileset = True
        self.xml.setDevice(device)
        if (self.xml.readNextStartElement() and self.xml.name() == "tileset"):
            tileset = self.__readTileset()
        else:
            self.xml.raiseError(self.tr("Not a tileset file."))
        self.mReadingExternalTileset = False
        return tileset

    def openFile(self, file):
        if (not file.exists()):
            self.mError = self.tr("File not found: %s"%file.fileName())
            return False
        elif (not file.open(QFile.ReadOnly | QFile.Text)):
            self.mError = self.tr("Unable to read file: %s"%file.fileName())
            return False

        return True

    def errorString(self):
        if self.mError != '':
            return self.mError
        else:
            return self.tr("%d\n\nLine %d, column %s"%(self.xml.lineNumber(), self.xml.columnNumber(), self.xml.errorString()))

    def __readUnknownElement(self):
        qDebug("Unknown element (fixme): "+self.xml.name()+" at line "+self.xml.lineNumber()+", column "+self.xml.columnNumber())
        self.xml.skipCurrentElement()

    def __readMap(self):
        atts = self.xml.attributes()
        mapWidth = Int(atts.value("width"))
        mapHeight = Int(atts.value("height"))
        tileWidth = Int(atts.value("tilewidth"))
        tileHeight = Int(atts.value("tileheight"))
        hexSideLength = Int(atts.value("hexsidelength"))
        orientationString = atts.value("orientation")
        orientation = orientationFromString(orientationString)
        if (orientation == Map.Orientation.Unknown):
            self.xml.raiseError(self.tr("Unsupported map orientation: \"%s\""%orientationString))

        staggerAxisString = atts.value("staggeraxis")
        staggerAxis = staggerAxisFromString(staggerAxisString)
        staggerIndexString = atts.value("staggerindex")
        staggerIndex = staggerIndexFromString(staggerIndexString)
        renderOrderString = atts.value("renderorder")
        renderOrder = renderOrderFromString(renderOrderString)
        nextObjectId = Int(atts.value("nextobjectid"))
        self.mMap = Map(orientation, mapWidth, mapHeight, tileWidth, tileHeight)
        self.mMap.setHexSideLength(hexSideLength)
        self.mMap.setStaggerAxis(staggerAxis)
        self.mMap.setStaggerIndex(staggerIndex)
        self.mMap.setRenderOrder(renderOrder)
        if (nextObjectId):
            self.mMap.setNextObjectId(nextObjectId)

        bgColorString = atts.value("backgroundcolor")
        if len(bgColorString)>0:
            self.mMap.setBackgroundColor(QColor(bgColorString))
        while (self.xml.readNextStartElement()):
            if (self.xml.name() == "properties"):
                self.mMap.mergeProperties(self.__readProperties())
            elif (self.xml.name() == "tileset"):
                self.mMap.addTileset(self.__readTileset())
            elif (self.xml.name() == "layer"):
                self.mMap.addLayer(self.__readLayer())
            elif (self.xml.name() == "objectgroup"):
                self.mMap.addLayer(self.__readObjectGroup())
            elif (self.xml.name() == "imagelayer"):
                self.mMap.addLayer(self.__readImageLayer())
            else:
                self.__readUnknownElement()

        # Clean up in case of error
        if (self.xml.hasError()):
            self.mMap = None

        return self.mMap

    def __readTileset(self):
        atts = self.xml.attributes()
        source = atts.value("source")
        firstGid = Int(atts.value("firstgid"))
        tileset = None
        if source == '': # Not an external tileset
            name = atts.value("name")
            tileWidth = Int(atts.value("tilewidth"))
            tileHeight = Int(atts.value("tileheight"))
            tileSpacing = Int(atts.value("spacing"))
            margin = Int(atts.value("margin"))
            if (tileWidth < 0 or tileHeight < 0
                or (firstGid == 0 and not self.mReadingExternalTileset)):
                self.xml.raiseError(self.tr("Invalid tileset parameters for tileset '%s'"%name))
            else:
                tileset = Tileset.create(name, tileWidth, tileHeight, tileSpacing, margin)

                while (self.xml.readNextStartElement()):
                    if (self.xml.name() == "tile"):
                        self.__readTilesetTile(tileset)
                    elif (self.xml.name() == "tileoffset"):
                        oa = self.xml.attributes()
                        x = Int(oa.value("x"))
                        y = Int(oa.value("y"))
                        tileset.setTileOffset(QPoint(x, y))
                        self.xml.skipCurrentElement()
                    elif (self.xml.name() == "properties"):
                        tileset.mergeProperties(self.__readProperties())
                    elif (self.xml.name() == "image"):
                        if (tileWidth == 0 or tileHeight == 0):
                            self.xml.raiseError(self.tr("Invalid tileset parameters for tileset '%s'"%name))
                            
                            tileset.clear()
                            break
                        else:
                            self.__readTilesetImage(tileset)
                    elif (self.xml.name() == "terraintypes"):
                        self.__readTilesetTerrainTypes(tileset)
                    else:
                        self.__readUnknownElement()
        else: # External tileset
            absoluteSource = self.p.resolveReference(source, self.mPath)
            tileset, error = self.p.readExternalTileset(absoluteSource)
            if (not tileset):
                self.xml.raiseError(self.tr("Error while loading tileset '%s': %s"%(absoluteSource, error)))

            self.xml.skipCurrentElement()

        if (tileset and not self.mReadingExternalTileset):
            self.mGidMapper.insert(firstGid, tileset)
        return tileset

    def __readTilesetTile(self, tileset):
        atts = self.xml.attributes()
        id = Int(atts.value("id"))
        if (id < 0):
            self.xml.raiseError(self.tr("Invalid tile ID: %d"%id))
            return

        hasImage = tileset.imageSource()!=''
        if (hasImage and id >= tileset.tileCount()):
            self.xml.raiseError(self.tr("Tile ID does not exist in tileset image: %d"%id))
            return

        if (id > tileset.tileCount()):
            self.xml.raiseError(self.tr("Invalid (nonconsecutive) tile ID: %d"%id))
            return

        # For tilesets without image source, consecutive tile IDs are allowed (for
        # tiles with individual images)
        if (id == tileset.tileCount()):
            tileset.addTile(QPixmap())
        tile = tileset.tileAt(id)
        # Read tile quadrant terrain ids
        terrain = atts.value("terrain")
        if terrain != '':
            quadrants = terrain.split(",")
            if (len(quadrants) == 4):
                for i in range(4):
                    if quadrants[i]=='':
                        t = -1
                    else:
                        t = Int(quadrants[i])
                    tile.setCornerTerrainId(i, t)

        # Read tile probability
        probability = atts.value("probability")
        if probability != '':
            tile.setProbability(Float(probability))
        while (self.xml.readNextStartElement()):
            if (self.xml.name() == "properties"):
                tile.mergeProperties(self.__readProperties())
            elif (self.xml.name() == "image"):
                source = self.xml.attributes().value("source")
                if source != '':
                    source = self.p.resolveReference(source, self.mPath)
                tileset.setTileImage(id, QPixmap.fromImage(self.__readImage()), source)
            elif (self.xml.name() == "objectgroup"):
                tile.setObjectGroup(self.__readObjectGroup())
            elif (self.xml.name() == "animation"):
                tile.setFrames(self.__readAnimationFrames())
            else:
                self.__readUnknownElement()

        # Temporary code to support TMW-style animation frame properties
        if (not tile.isAnimated() and tile.hasProperty("animation-frame0")):
            frames = QVector()
            i = 0
            while(i>=0):
                frameName = "animation-frame" + str(i)
                delayName = "animation-delay" + str(i)
                if (tile.hasProperty(frameName) and tile.hasProperty(delayName)):
                    frame = Frame()
                    frame.tileId = tile.property(frameName)
                    frame.duration = tile.property(delayName) * 10
                    frames.append(frame)
                else:
                    break
                i += 1

            tile.setFrames(frames)

    def __readTilesetImage(self, tileset):
        atts = self.xml.attributes()
        source = atts.value("source")
        trans = atts.value("trans")
        if len(trans)>0:
            if (not trans.startswith('#')):
                trans = '#' + trans
            tileset.setTransparentColor(QColor(trans))

        if len(source)>0:
            source = self.p.resolveReference(source, self.mPath)
        # Set the width that the tileset had when the map was saved
        width = Int(atts.value("width"))
        self.mGidMapper.setTilesetWidth(tileset, width)
        if (not tileset.loadFromImage(self.__readImage(), source)):
            self.xml.raiseError(self.tr("Error loading tileset image:\n'%s'"%source))

    def __readTilesetTerrainTypes(self, tileset):
        while (self.xml.readNextStartElement()):
            if (self.xml.name() == "terrain"):
                atts = self.xml.attributes()
                name = atts.value("name")
                tile = Int(atts.value("tile"))
                terrain = tileset.addTerrain(name, tile)
                while (self.xml.readNextStartElement()):
                    if (self.xml.name() == "properties"):
                        terrain.mergeProperties(self.__readProperties())
                    else:
                        self.__readUnknownElement()

            else:
                self.__readUnknownElement()

    def __readImage(self):
        atts = self.xml.attributes()
        source = atts.value("source")
        format = atts.value("format")
        if len(source)==0:
            while (self.xml.readNextStartElement()):
                if (self.xml.name() == "data"):
                    atts = self.xml.attributes()
                    encoding = atts.value("encoding")
                    data = self.xml.readElementText().toLatin1()
                    if (encoding == "base64"):
                        data = QByteArray.fromBase64(data)

                    self.xml.skipCurrentElement()
                    return QImage.fromData(data, format.toLatin1())
                else:
                    self.__readUnknownElement()

        else:
            self.xml.skipCurrentElement()
            source = self.p.resolveReference(source, self.mPath)
            image = self.p.readExternalImage(source)
            if (image.isNull()):
                self.xml.raiseError(self.tr("Error loading image:\n'%s'"%source))
            return image

        return QImage()

    def __readLayer(self):
        atts = self.xml.attributes()
        name = atts.value("name")
        x = Int(atts.value("x"))
        y = Int(atts.value("y"))
        width = Int(atts.value("width"))
        height = Int(atts.value("height"))
        tileLayer = TileLayer(name, x, y, width, height)
        readLayerAttributes(tileLayer, atts)
        while (self.xml.readNextStartElement()):
            if (self.xml.name() == "properties"):
                tileLayer.mergeProperties(self.__readProperties())
            elif (self.xml.name() == "data"):
                self.__readLayerData(tileLayer)
            else:
                self.__readUnknownElement()

        return tileLayer

    def __readLayerData(self, tileLayer):
        atts = self.xml.attributes()
        encoding = atts.value("encoding")
        compression = atts.value("compression")
        layerDataFormat = 0
        if (encoding == ''):
            layerDataFormat = Map.LayerDataFormat.XML
        elif (encoding == "csv"):
            layerDataFormat = Map.LayerDataFormat.CSV
        elif (encoding == "base64"):
            if (compression == ''):
                layerDataFormat = Map.LayerDataFormat.Base64
            elif (compression == "gzip"):
                layerDataFormat = Map.LayerDataFormat.Base64Gzip
            elif (compression == "zlib"):
                layerDataFormat = Map.LayerDataFormat.Base64Zlib
            else:
                self.xml.raiseError(self.tr("Compression method '%s' not supported"%compression))
                return
        else:
            self.xml.raiseError(self.tr("Unknown encoding: %s"%encoding))
            return
        
        self.mMap.setLayerDataFormat(layerDataFormat)
        
        x = 0
        y = 0
        while (self.xml.readNext() != QXmlStreamReader.Invalid):
            if (self.xml.isEndElement()):
                break
            elif (self.xml.isStartElement()):
                if (self.xml.name() == "tile"):
                    if (y >= tileLayer.height()):
                        self.xml.raiseError(self.tr("Too many <tile> elements"))
                        continue

                    atts = self.xml.attributes()
                    gid = Int(atts.value("gid"))
                    tileLayer.setCell(x, y, self.__cellForGid(gid))
                    x += 1
                    if (x >= tileLayer.width()):
                        x = 0
                        y += 1

                    self.xml.skipCurrentElement()
                else:
                    self.__readUnknownElement()
            elif (self.xml.isCharacters() and not self.xml.isWhitespace()):
                if (encoding == "base64"):
                    self.__decodeBinaryLayerData(tileLayer,
                                          self.xml.text(),
                                          layerDataFormat)
                elif (encoding == "csv"):
                    self.__decodeCSVLayerData(tileLayer, self.xml.text())

    def __decodeBinaryLayerData(self, tileLayer, data, format):
        error = self.mGidMapper.decodeLayerData(tileLayer, data, format)

        if error==DecodeError.CorruptLayerData:
            self.xml.raiseError(self.tr("Corrupt layer data for layer '%s'"%tileLayer.name()))
            return
        elif error==DecodeError.TileButNoTilesets:
            self.xml.raiseError(self.tr("Tile used but no tilesets specified"))
            return
        elif error==DecodeError.InvalidTile:
            self.xml.raiseError(self.tr("Invalid tile: %d"%self.mGidMapper.invalidTile()))
            return
        elif error==DecodeError.NoError:
            pass

    def __decodeCSVLayerData(self, tileLayer, text):
        trimText = text.strip()
        tiles = trimText.split(',')
        if (len(tiles) != tileLayer.width() * tileLayer.height()):
            self.xml.raiseError(self.tr("Corrupt layer data for layer '%s'"%tileLayer.name()))
            return

        for y in range(tileLayer.height()):
            for x in range(tileLayer.width()):
                conversionOk = False
                gid, conversionOk = Int2(tiles[y * tileLayer.width() + x])
                if (not conversionOk):
                    self.xml.raiseError(self.tr("Unable to parse tile at (%d,%d) on layer '%s'"%(x + 1, y + 1, tileLayer.name())))
                    return

                tileLayer.setCell(x, y, self.__cellForGid(gid))

    ##
    # Returns the cell for the given global tile ID. Errors are raised with
    # the QXmlStreamReader.
    #
    # @param gid the global tile ID
    # @return the cell data associated with the given global tile ID, or an
    #         empty cell if not found
    ##
    def __cellForGid(self, gid):
        ok = False
        result, ok = self.mGidMapper.gidToCell(gid)
        if (not ok):
            if (self.mGidMapper.isEmpty()):
                self.xml.raiseError(self.tr("Tile used but no tilesets specified"))
            else:
                self.xml.raiseError(self.tr("Invalid tile: %d"%gid))

        return result

    def __readImageLayer(self):
        atts = self.xml.attributes()
        name = atts.value("name")
        x = Int(atts.value("x"))
        y = Int(atts.value("y"))
        width = Int(atts.value("width"))
        height = Int(atts.value("height"))
        imageLayer = ImageLayer(name, x, y, width, height)
        readLayerAttributes(imageLayer, atts)
        while (self.xml.readNextStartElement()):
            if (self.xml.name() == "image"):
                self.__readImageLayerImage(imageLayer)
            elif (self.xml.name() == "properties"):
                imageLayer.mergeProperties(self.__readProperties())
            else:
                self.__readUnknownElement()

        return imageLayer

    def __readImageLayerImage(self, imageLayer):
        atts = self.xml.attributes()
        source = atts.value("source")
        trans = atts.value("trans")
        if trans != '':
            if (not trans.startswith('#')):
                trans = '#' + trans
            imageLayer.setTransparentColor(QColor(trans))

        source = self.p.resolveReference(source, self.mPath)
        imageLayerImage = self.p.readExternalImage(source)
        if (not imageLayer.loadFromImage(imageLayerImage, source)):
            self.xml.raiseError(self.tr("Error loading image layer image:\n'%s'"%source))
        self.xml.skipCurrentElement()

    def __readObjectGroup(self):
        atts = self.xml.attributes()
        name = atts.value("name")
        x = Int(atts.value("x"))
        y = Int(atts.value("y"))
        width = Int(atts.value("width"))
        height = Int(atts.value("height"))
        objectGroup = ObjectGroup(name, x, y, width, height)
        readLayerAttributes(objectGroup, atts)
        color = atts.value("color")
        if color != '':
            objectGroup.setColor(color)
        if (atts.hasAttribute("draworder")):
            value = atts.value("draworder")
            drawOrder = drawOrderFromString(value)
            if (drawOrder == ObjectGroup.DrawOrder.UnknownOrder):
                #del objectGroup
                self.xml.raiseError(self.tr("Invalid draw order: %s"%value))
                return None

            objectGroup.setDrawOrder(drawOrder)

        while (self.xml.readNextStartElement()):
            if (self.xml.name() == "object"):
                objectGroup.addObject(self.__readObject())
            elif (self.xml.name() == "properties"):
                objectGroup.mergeProperties(self.__readProperties())
            else:
                self.__readUnknownElement()

        return objectGroup

    def __readObject(self):
        atts = self.xml.attributes()
        id = Int(atts.value("id"))
        name = atts.value("name")
        gid = Int(atts.value("gid"))
        x = Float(atts.value("x"))
        y = Float(atts.value("y"))
        width = Float(atts.value("width"))
        height = Float(atts.value("height"))
        type = atts.value("type")
        visibleRef = atts.value("visible")
        pos = QPointF(x, y)
        size = QSizeF(width, height)
        object = MapObject(name, type, pos, size)
        object.setId(id)

        try:
            rotation = Float(atts.value("rotation"))
            ok = True
        except:
            ok = False
        if (ok):
            object.setRotation(rotation)
        if (gid):
            object.setCell(self.__cellForGid(gid))
            if (not object.cell().isEmpty()):
                tileSize = object.cell().tile.size()
                if (width == 0):
                    object.setWidth(tileSize.width())
                if (height == 0):
                    object.setHeight(tileSize.height())
        
        try:
            visible = int(visibleRef)
            ok = True
        except:
            ok = False
        if ok:
            object.setVisible(visible)
        while (self.xml.readNextStartElement()):
            if (self.xml.name() == "properties"):
                object.mergeProperties(self.__readProperties())
            elif (self.xml.name() == "polygon"):
                object.setPolygon(self.__readPolygon())
                object.setShape(MapObject.Polygon)
            elif (self.xml.name() == "polyline"):
                object.setPolygon(self.__readPolygon())
                object.setShape(MapObject.Polyline)
            elif (self.xml.name() == "ellipse"):
                self.xml.skipCurrentElement()
                object.setShape(MapObject.Ellipse)
            else:
                self.__readUnknownElement()

        return object

    def __readPolygon(self):
        atts = self.xml.attributes()
        points = atts.value("points")
        pointsList = list(filter(lambda x:x.strip()!='', points.split(' ')))
        polygon = QPolygonF()
        ok = True
        for point in pointsList:
            try:
                x, y = point.split(',')
            except:
                ok = False
                break
            
            x, ok = Float2(x)
            if (not ok):
                break

            y, ok = Float2(y)
            if (not ok):
                break
            polygon.append(QPointF(x, y))

        if (not ok):
            self.xml.raiseError(self.tr("Invalid points data for polygon"))
        self.xml.skipCurrentElement()
        return polygon

    def __readAnimationFrames(self):
        frames = QVector()
        while (self.xml.readNextStartElement()):
            if (self.xml.name() == "frame"):
                atts = self.xml.attributes()
                frame = Frame()
                frame.tileId = Int(atts.value("tileid"))
                frame.duration = Int(atts.value("duration"))
                frames.append(frame)
                self.xml.skipCurrentElement()
            else:
                self.__readUnknownElement()

        return frames

    def __readProperties(self):
        properties = Properties()
        while (self.xml.readNextStartElement()):
            if (self.xml.name() == "property"):
                self.__readProperty(properties)
            else:
                self.__readUnknownElement()

        return properties

    def __readProperty(self, properties):
        atts = self.xml.attributes()
        propertyName = atts.value("name")
        propertyValue = atts.value("value")
        while (self.xml.readNext() != QXmlStreamReader.Invalid):
            if (self.xml.isEndElement()):
                break
            elif (self.xml.isCharacters() and not self.xml.isWhitespace()):
                if (propertyValue.isEmpty()):
                    propertyValue = self.xml.text()
            elif (self.xml.isStartElement()):
                self.__readUnknownElement()

        properties.insert(propertyName, propertyValue)
示例#26
0
    def read(self, fileName):
        file = QFile(fileName)
        if (not file.open (QIODevice.ReadOnly)):
            self.mError = self.tr("Could not open file for reading.")
            return None
        
        # default to values of the original flare alpha game.
        map = Map(Map.Orientation.Isometric, 256, 256, 64, 32)
        stream = QTextStream(file)
        line = QString()
        sectionName = QString()
        newsection = False
        path = QFileInfo(file).absolutePath()
        base = 10
        gidMapper = GidMapper()
        gid = 1
        tilelayer = None
        objectgroup = None
        mapobject = None
        tilesetsSectionFound = False
        headerSectionFound = False
        tilelayerSectionFound = False # tile layer or objects
        while (not stream.atEnd()):
            line = stream.readLine()
            if line == '':
                continue
            startsWith = line[0]
            if (startsWith == '['):
                sectionName = line[1:line.index(']')]
                newsection = True
                continue
            
            if (sectionName == "header"):
                headerSectionFound = True
                #get map properties
                epos = line.index('=')
                if (epos != -1):
                    key = line[:epos].strip()
                    value = line[epos + 1:].strip()
                    if (key == "width"):
                        map.setWidth(Int(value))
                    elif (key == "height"):
                        map.setHeight(Int(value))
                    elif (key == "tilewidth"):
                        map.setTileWidth(Int(value))
                    elif (key == "tileheight"):
                        map.setTileHeight(Int(value))
                    elif (key == "orientation"):
                        map.setOrientation(orientationFromString(value))
                    else:
                        map.setProperty(key, value)
                
            elif (sectionName == "tilesets"):
                tilesetsSectionFound = True
                epos = line.index('=')
                key = line[:epos].strip()
                value = line[epos + 1:].strip()
                if (key == "tileset"):
                    _list = value.split(',')
                    absoluteSource = _list[0]
                    if (QDir.isRelativePath(absoluteSource)):
                        absoluteSource = path + '/' + absoluteSource
                    tilesetwidth = 0
                    tilesetheight = 0
                    if len(_list) > 2:
                        tilesetwidth = Int(_list[1])
                        tilesetheight = Int(_list[2])
                    
                    tileset = Tileset.create(QFileInfo(absoluteSource).fileName(), tilesetwidth, tilesetheight)
                    ok = tileset.loadFromImage(absoluteSource)
                    if not ok:
                        self.mError = self.tr("Error loading tileset %s, which expands to %s. Path not found!"%(_list[0], absoluteSource))
                        return None
                    else :
                        if len(_list) > 4:
                            tileset.setTileOffset(QPoint(Int(_list[3]),Int(_list[4])))
                        gidMapper.insert(gid, tileset)
                        if len(_list) > 5:
                            gid += Int(_list[5])
                        else :
                            gid += tileset.tileCount()
                        
                        map.addTileset(tileset)

            elif (sectionName == "layer"):
                if (not tilesetsSectionFound):
                    self.mError = self.tr("No tilesets section found before layer section.")
                    return None
                
                tilelayerSectionFound = True
                epos = line.index('=')
                if (epos != -1):
                    key = line[:epos].strip()
                    value = line[epos + 1:].strip()
                    if (key == "type"):
                        tilelayer = TileLayer(value, 0, 0, map.width(),map.height())
                        map.addLayer(tilelayer)
                    elif (key == "format"):
                        if (value == "dec"):
                            base = 10
                        elif (value == "hex"):
                            base = 16
                        
                    elif (key == "data"):
                        for y in range(map.height()):
                            line = stream.readLine()
                            l = line.split(',')
                            for x in range(min(map.width(), len(l))):
                                ok = False
                                tileid = int(l[x], base)
                                c, ok = gidMapper.gidToCell(tileid)
                                if (not ok):
                                    self.mError += self.tr("Error mapping tile id %1.").arg(tileid)
                                    return None
                                
                                tilelayer.setCell(x, y, c)

                    else :
                        tilelayer.setProperty(key, value)

            else :
                if (newsection):
                    if (map.indexOfLayer(sectionName) == -1):
                        objectgroup = ObjectGroup(sectionName, 0,0,map.width(), map.height())
                        map.addLayer(objectgroup)
                    else :
                        objectgroup = map.layerAt(map.indexOfLayer(sectionName))
                    
                    mapobject = MapObject()
                    objectgroup.addObject(mapobject)
                    newsection = False
                
                if (not mapobject):
                    continue
                if (startsWith == '#'):
                    name = line[1].strip()
                    mapobject.setName(name)
                
                epos = line.index('=')
                if (epos != -1):
                    key = line[:epos].strip()
                    value = line[epos + 1:].strip()
                    if (key == "type"):
                        mapobject.setType(value)
                    elif (key == "location"):
                        loc = value.split(',')
                        x,y = 0.0, 0.0
                        w,h = 0, 0
                        if (map.orientation() == Map.Orthogonal):
                            x = loc[0].toFloat()*map.tileWidth()
                            y = loc[1].toFloat()*map.tileHeight()
                            if len(loc) > 3:
                                w = Int(loc[2])*map.tileWidth()
                                h = Int(loc[3])*map.tileHeight()
                            else :
                                w = map.tileWidth()
                                h = map.tileHeight()
                            
                        else :
                            x = loc[0].toFloat()*map.tileHeight()
                            y = loc[1].toFloat()*map.tileHeight()
                            if len(loc) > 3:
                                w = Int(loc[2])*map.tileHeight()
                                h = Int(loc[3])*map.tileHeight()
                            else :
                                w = h = map.tileHeight()

                        mapobject.setPosition(QPointF(x, y))
                        mapobject.setSize(w, h)
                    else :
                        mapobject.setProperty(key, value)


        if (not headerSectionFound or not tilesetsSectionFound or not tilelayerSectionFound):
            self.mError = self.tr("This seems to be no valid flare map. "
                        "A Flare map consists of at least a header "
                        "section, a tileset section and one tile layer.")
            return None
        
        return map