class GameScreen(Screen): def __init__(self, levelfile): self.level = leveltypes[levelfile.properties.get('leveltype', 'Level')](levelfile) self.player = self.level.sprites['Player'].pop() self.tileset = Tileset(config.tilepath, config.tilesize) self.renderer = Renderer(self.tileset) self.redraw = True def resize_view(self): """Given the window size, set view size and cell size, then resize the view and tileset.""" ww, wh = self.window.view.get_size() vw, vh = config.maxviewcells # set view size in cells and cell size in pixels self.viewcells = min(vw, self.level.width), min(vh, self.level.height) self.cellsize = self._get_cell_size((ww, wh), self.viewcells) # resize view and tileset, and schedule a full redraw self.view = self.window.view.subsurface(self._get_view_rect((ww, wh), self.viewcells)) self.tileset.resize_tileset(self.cellsize) self.redraw = True def _get_cell_size(self, (ww, wh), (vw, vh)): """Given a window size in pixels, and a view size in cells, return the largest cell size that will fit the view in the window.""" tw, th = self.tileset.dims # divide and multiply by tile size, to force cell size to be an exact multiple return min(ww / vw / tw * tw, wh / vh / th * th)
def __init__(self, game): """init and position the wall""" # we use only white dragons for building the wall. We could actually # use any tile because the face is never shown anyway. self.initWindMarkers() game.wall = self Wall.__init__(self, game) self.__square = Board(1, 1, Tileset.current()) self.__square.setZValue(ZValues.markerZ) sideLength = len(self.tiles) // 8 self.__sides = [ UIWallSide(Tileset.current(), boardRotation, sideLength) for boardRotation in self.sideAngles ] for idx, side in enumerate(self.__sides): side.setParentItem(self.__square) side.lightSource = self.lightSource side.windTile = Wind.all4[idx].marker side.windTile.hide() side.message = YellowText(side) side.message.setZValue(ZValues.popupZ) side.message.setVisible(False) side.message.setPos(side.center()) self.__sides[self.Lower].setPos(yWidth=sideLength) self.__sides[self.Left].setPos(xHeight=1) self.__sides[self.Upper].setPos(xHeight=1, xWidth=sideLength, yHeight=1) self.__sides[self.Right].setPos(xWidth=sideLength, yWidth=sideLength, yHeight=1) Internal.scene.addItem(self.__square) Internal.Preferences.addWatch('showShadows', self.showShadowsChanged)
def __init__(self, game): """init and position the wall""" # we use only white dragons for building the wall. We could actually # use any tile because the face is never shown anyway. game.wall = self Wall.__init__(self, game) self.__square = Board(1, 1, Tileset.activeTileset()) self.__square.setZValue(ZValues.marker) sideLength = len(self.tiles) // 8 self.__sides = [UIWallSide( Tileset.activeTileset(), boardRotation, sideLength) for boardRotation in (0, 270, 180, 90)] for side in self.__sides: side.setParentItem(self.__square) side.lightSource = self.lightSource side.windTile = PlayerWind( East, Internal.scene.windTileset, parent=side) side.windTile.hide() side.nameLabel = QGraphicsSimpleTextItem('', side) side.message = YellowText(side) side.message.setZValue(ZValues.popup) side.message.setVisible(False) side.message.setPos(side.center()) self.__sides[0].setPos(yWidth=sideLength) self.__sides[3].setPos(xHeight=1) self.__sides[2].setPos(xHeight=1, xWidth=sideLength, yHeight=1) self.__sides[1].setPos(xWidth=sideLength, yWidth=sideLength, yHeight=1) self.__findOptimalFontHeight() Internal.scene.addItem(self.__square) Internal.Preferences.addWatch('showShadows', self.showShadowsChanged)
def init(): global goal_obstacles, allsprites, tileset, walls, obstacles, player, levelTime tileset = Tileset(levels[cur_level]) walls = tileset.get_walls() obstacles = tileset.get_obstacles() player.set_walls(walls) player.set_obstacles(obstacles) player.move_to(48, 76) goal_obstacles = [] for o in obstacles: if o.get_obs_type() == "Goal": goal_obstacles.append(o) allsprites = pygame.sprite.RenderPlain(obstacles) allsprites.add(player) levelTime = 60.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
def replaceReferencesToTileset(self, oldTileset, newTileset): for object in self.mObjects: tile = object.cell().tile if (tile and tile.tileset() == oldTileset): cell = object.cell() cell.tile = Tileset.tileAt(tile.id()) object.setCell(cell)
def applySettings(self): """apply preferences""" self.mainWindow.actionAngle.setEnabled( bool(self.game) and Internal.Preferences.showShadows) with MoveImmediate(): for item in self.nonTiles(): item.tileset = Tileset.activeTileset()
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
def setUp(self): """set-up the selector""" # The lineEdit widget holds our tileset path, but the user does # not manipulate it directly self.kcfg_tilesetName.hide() self.tilesetNameList.currentRowChanged.connect(self.tilesetRowChanged) self.kcfg_tilesetName.textChanged.connect(self.tilesetNameChanged) Tileset.loadAll() # list default tileset first self.tilesetList = Tileset.available() for aset in self.tilesetList: self.tilesetNameList.addItem(aset.name) self.kcfg_tilesetName.setText(Internal.Preferences.tilesetName)
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 setup(self): """Setup game.""" pygame.init() pygame.display.set_caption("pacman") self.maze_tiles = Tileset("data/tiles.gif", TILE_WIDTH, TILE_HEIGHT) self.pacman_tiles = Tileset("data/pacman.gif", SPRITE_WIDTH, SPRITE_HEIGHT)
def __init__(self, levelfile): self.level = leveltypes[levelfile.properties.get('leveltype', 'Level')](levelfile) self.player = self.level.sprites['Player'].pop() self.tileset = Tileset(config.tilepath, config.tilesize) self.renderer = Renderer(self.tileset) self.redraw = True
def applySettings(self): """apply preferences""" self.mainWindow.actionAngle.setEnabled( bool(self.game) and Internal.Preferences.showShadows) with AnimationSpeed(): for item in self.nonTiles(): if hasattr(item, 'tileset'): item.tileset = Tileset.current()
def __init__(self, leveldata, lskip=0): self.viewcells = 10, 6 # size of the view in cells # init levels self.leveldata = leveldata self.current_level = lskip self.level = Level(self.leveldata[self.current_level]) self.tileset = Tileset(config.tilepath, config.tilesize)
def __init__(self, tilesets, optional=None): self.tilesets = [] self.pair = [] self.pungs = [] self.kongs = [] self.chows = [] self.knitted = [] self.special = [] self.tilecount = 0 self.standardhand = False self.prevalentwind = "" self.seatwind = "" if optional is not None: #self.concealed is True if the hand is fully concealed, otherwise it's a list corresponding to the tilesets self.concealed = False if optional.get("concealed", None) is None else optional["concealed"] self.winningtile = False if optional.get("winning tile", None) is None else optional["winning tile"] self.flowers = 0 if optional.get("flowers", None) is None else optional["flowers"] self.prevalentwind = "E" if optional.get("prevalent wind", None) is None else optional["prevalent wind"] self.seatwind = "" if optional.get("seat wind", None) is None else optional["seat wind"] flat_list = [] for sublist in tilesets: for item in sublist: flat_list.append(item) self.tilecount = len(flat_list) for i, tileset in enumerate(tilesets): if optional is not None and type(self.concealed) is list: self.tilesets.append(Tileset(tileset, self.concealed[i])) else: self.tilesets.append(Tileset(tileset)) for tileset in self.tilesets: if tileset.type == "pair": self.pair.append(tileset) elif tileset.type == "pung": self.pungs.append(tileset) elif tileset.type == "kong": self.kongs.append(tileset) elif tileset.type == "chow": self.chows.append(tileset) elif tileset.type == "knitted": self.knitted.append(tileset) elif tileset.type == "special": self.special.append(tileset) standard_sets = self.kongs + self.pungs + self.chows + self.knitted self.standardhand = True if len(standard_sets) == 4 and len(self.pair) == 1 and len(self.special) == 0 else False
def __findOptimalFontHeight(self): """for names on walls""" tileHeight = Tileset.activeTileset().faceSize.height() font = self.__sides[0].nameLabel.font() size = 80 font.setPointSize(size) while QFontMetrics(font).ascent() > tileHeight: size -= 1 font.setPointSize(size) for side in self.__sides: side.nameLabel.setFont(font)
def setUp(self): """set-up the selector""" # The lineEdit widget holds our tileset path, but the user does # not manipulate it directly self.kcfg_tilesetName.hide() self.tilesetNameList.currentRowChanged.connect(self.tilesetRowChanged) self.kcfg_tilesetName.textChanged.connect(self.tilesetNameChanged) self.tilesetList = Tileset.tilesAvailable() for aset in self.tilesetList: self.tilesetNameList.addItem(aset.name) self.kcfg_tilesetName.setText(Internal.Preferences.tilesetName)
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 tryAccept(self): # Used for storing the settings for next time s = preferences.Preferences.instance().settings() name = self.mUi.name.text() if (tilesetType(self.mUi) == TilesetType.TilesetImage): image = self.mUi.image.text() useTransparentColor = self.mUi.useTransparentColor.isChecked() transparentColor = self.mUi.colorButton.color() tileWidth = self.mUi.tileWidth.value() tileHeight = self.mUi.tileHeight.value() spacing = self.mUi.spacing.value() margin = self.mUi.margin.value() tileset = Tileset.create(name, tileWidth, tileHeight, spacing, margin) if (useTransparentColor): tileset.setTransparentColor(transparentColor) if image != '': if (not tileset.loadFromImage(image)): QMessageBox.critical(self, self.tr("Error"), self.tr("Failed to load tileset image '%s'."%image)) return if (tileset.tileCount() == 0): QMessageBox.critical(self, self.tr("Error"), self.tr("No tiles found in the tileset image " "when using the given tile size, " "margin and spacing!")) return s.setValue(COLOR_ENABLED_KEY, useTransparentColor) s.setValue(COLOR_KEY, transparentColor.name()) s.setValue(SPACING_KEY, spacing) s.setValue(MARGIN_KEY, margin) else: tileset = Tileset.create(name, 1, 1) s.setValue(TYPE_KEY, self.mUi.tilesetType.currentIndex()) self.mNewTileset = tileset self.accept()
def __init__(self, player): assert player self._player = weakref.ref(player) self.exposedMeldDistance = 0.15 self.concealedMeldDistance = 0.0 self.lowerY = 1.0 Board.__init__(self, 15.6, 2.0, Tileset.activeTileset()) self.isHandBoard = True self.tileDragEnabled = False self.setParentItem(player.front) self.setPosition() self.setAcceptDrops(True) Internal.Preferences.addWatch( 'rearrangeMelds', self.rearrangeMeldsChanged) Internal.Preferences.addWatch( 'showShadows', self.showShadowsChanged)
def draw_tilegrid(self, grid: TileGrid, tileset: Tileset, offset, scale, tile_size, layer_offset, tile_layer_index): h = len(grid)*tile_size[1] y = h+layer_offset[1] # float y = h + y_offset, x; for row in grid: x = layer_offset[0] for cell in row: if cell: img = tileset.get_variant(cell-1, tile_layer_index) pt = [x, self.height - y] pt = np.multiply(pt, scale) pt = np.add(pt, offset) ts = np.multiply(tile_size, scale) self.add_image(img, at=pt, final_size=ts) x += tile_size[0] y -= tile_size[1]
def __init__(self, player): assert player self._player = weakref.ref(player) self.exposedMeldDistance = 0.15 self.concealedMeldDistance = 0.0 self.lowerY = 1.0 Board.__init__(self, 15.6, 2.0, Tileset.current()) self.isHandBoard = True self.tileDragEnabled = False self.setParentItem(player.front) self.setPosition() self.setAcceptDrops(True) Internal.Preferences.addWatch('rearrangeMelds', self.rearrangeMeldsChanged) self.rearrangeMeldsChanged(None, Internal.Preferences.rearrangeMelds) Internal.Preferences.addWatch('showShadows', self.showShadowsChanged)
def __init__(self, data): defaults = { 'size': [32.0, 32.0], 'x_offset': 0.0, 'y_offset': 0.0, 'tile_layer': 0, 'tiles': [[]] } data = {**defaults, **data} self.tileset = Tileset(data['tileset']) self.name = data['name'] self.tile_size = data['size'] if isinstance(self.tile_size, (float, int)): self.tile_size = [self.tile_size, self.tile_size] self.offset = (data['x_offset'] * self.tile_size[0], data['y_offset'] * self.tile_size[1]) self.tile_layer_index = data['tile_layer'] self.grid = TileGrid(data['tiles'])
def genWINDPIXMAPS(): """prepare wind tiles""" tileset = Tileset(Preferences.windTilesetName) for wind in WINDS: for prevailing in False, True: pwind = PlayerWind(wind, tileset, prevailing) pMap = QPixmap(40, 40) pMap.fill(Qt.transparent) painter = QPainter(pMap) painter.setRenderHint(QPainter.Antialiasing) painter.scale(0.40, 0.40) pwind.paint(painter, QStyleOptionGraphicsItem()) for child in pwind.childItems(): if isinstance(child, QGraphicsSvgItem): painter.save() painter.translate(child.mapToParent(0.0, 0.0)) child.paint(painter, QStyleOptionGraphicsItem()) painter.restore() WINDPIXMAPS[(wind, prevailing)] = pMap
def __init__(self, parent): super(TilesetSelector, self).__init__(parent) loadUi(self) self.kcfg_tilesetName = QLineEdit(self) self.kcfg_tilesetName.setVisible(False) self.kcfg_tilesetName.setObjectName('kcfg_tilesetName') self.tileScene = SceneWithFocusRect() self.tileView = FittingView() self.tileView.setScene(self.tileScene) self.tileset = Tileset(Internal.Preferences.tilesetName) self.uiTiles = [UITile('w' + s.char.lower()) for s in Wind.all4] self.board = Board(2, 2, self.tileset) self.board.showShadows = True self.tileScene.addItem(self.board) self.tileView.setParent(self.tilesetPreview) layout = QHBoxLayout(self.tilesetPreview) layout.addWidget(self.tileView) for idx, offsets in enumerate([(0, 0), (0, 1), (1, 0), (1, 1)]): self.uiTiles[idx].setBoard(self.board, *offsets) self.uiTiles[idx].focusable = False self.setUp()
class TMXHandler(sax.ContentHandler): def __init__(self): super().__init__() self.column = 0 self.line = 0 self.tile_width = 0 self.tile_height = 0 self.columns = 0 self.lines = 0 self.layers = 0 # Quantas camada's foram processadas (conterão o número total de camadas quando o ContentHandler for concluído) self.properties = [ {} ] # Lista de dicionários (um por camada) de pares nome / valor. Especificado pelas tags <property> self.tileset = None # O objeto Tileset criado a partir de tags <tileset> self.image = [ ] # Uma lista de camadas, cada uma contendo uma lista 2D de referências a células Tileset self.cur_row = [] self.cur_layer = [] self.blocking = [ ] # Lista de áreas de bloqueio nas quais os itens não podem entrar (pintados em terrenos intransitáveis) self.items = [] # Lista de todos os itens self.in_item = False # se estou colocando propriedades em um item ou em uma camada def start_element(self, name, attributes): if name == 'map': self.columns = int(attributes.get('width', None)) self.lines = int(attributes.get('height', None)) self.tile_width = int(attributes.get('tilewidth', None)) self.tile_height = int(attributes.get('tileheight', None)) elif name == 'image': # criar um tileset # É possível usar mais de um conjunto de peças, mas eles devem ter tamanhos e peças idênticos. # chaves de cores transparentes. source = attributes.get('source', None) transp = attributes.get('trans', None) if self.tileset is None: self.tileset = Tileset(self.tile_width, self.tile_height) self.tileset.add_set(source, ("0x" + str(transp))) elif name == 'property': # armazena propriedades adicionais. # adicionar às propriedades do item ou da camada, dependendo da tag pai em que estamos if self.in_item: self.items[-1].properties[attributes.get( 'name', None)] = attributes.get('value', None) else: self.properties[self.layers][attributes.get( 'name', None)] = attributes.get('value', None) elif name == 'layer': # começando a contagem self.line = 0 self.column = 0 self.layers += 1 self.properties.append({}) self.in_item = False elif name == 'tile': # obter informações de cada bloco e colocar no mapa # ID do arquivo para fazer referência ao conjunto de blocos gid = int(attributes.get('gid', None)) - 1 if gid < 0: gid = 0 self.cur_row.append(self.tileset.tiles[gid]) self.column += 1 if self.column >= self.columns: self.line += 1 self.column = 0 self.cur_layer.append(self.cur_row) self.cur_row = [] if self.line >= self.lines: self.image.append(self.cur_layer) self.cur_layer = [] elif name == 'object': # áreas de objetos podem ser pintadas em azulejo ou especificadas manualmente, como no mapa de amostra self.in_item = True x = int(attributes.get('x', None)) / self.tile_width y = int(attributes.get('y', None)) / self.tile_height if attributes.get( 'type', None ) == 'block': # impede que itens entrem em quadrados contidos width = int(attributes.get('width', None)) / self.tile_width height = int(attributes.get('height', None)) / self.tile_height self.blocking.append(Rect(x, y, width, height)) if attributes.get('type', None) == 'boulder': # empurrável self.items.append( item.Item( sprites.Sprite('sprites/rock.png', 32, 64, (0, 198, 198)), Rect(x, y, 1, 1), 'boulder')) if attributes.get('type', None) == 'girl': self.items.append( item.Item( sprites.Sprite('sprites/girl.png', 32, 64, (0, 198, 198)), Rect(x, y, 1, 1), 'person')) if attributes.get('type', None) == 'boy': self.items.append( item.Item( sprites.Sprite('sprites/boy.png', 32, 64, (0, 198, 198)), Rect(x, y, 1, 1), 'person'))
from tileset import Tileset import detect path = 'data/tiles/originals' prep_path = 'data/images/tiled/prepped' tiles = Tileset(path, cols=4, rows=3, tilew=1024, tileh=1024, scale=9.767, detection_method=detect.tiled) tiles = tiles.prepTiles(prep_path, 5) tiles.displayTileRegion(0, 3, 0, 2) tiles.plotDensity(1, 400) print('Yield:', round(tiles.getYield() * 100, 2), '%') tiles.displayTileRegion(0, 3, 0, 2) tiles.plotHistogram('diameter', bins=100) tiles.plotBlobRegion(property='radius', colormap='viridis') tiles.plotHistogram('distance', bins=50) tiles.plotBlobRegion(property='distance') tiles.plotRadialHistogram(bins=30, fontsize=10) tiles.plotBlobRegion(property='angle')
class TMXHandler(sax.ContentHandler): """Adapted from http://silveiraneto.net/2009/12/19/tiled-tmx-map-loader-for-pygame/""" def __init__(self): #Inform self.tile_width = 0 self.tile_height = 0 self.columns = 0 self.lines = 0 self.layers = 0 #How many <layer>s have been processed (will contain total number of layers when the ContentHandler is finished) self.properties = [{}] #List of dictionaries (one per layer) of name/value pairs. Specified by <property> tags. self.tileset = None #The Tileset object built from <tileset> tags self.image = [] #A list of layers, each containing a 2D list of references to Tileset cells self.cur_row = [] self.cur_layer = [] self.blocking = [] #List of blocking areas which items cannot go into (painted over impassable terrain) self.items = [] #List of all items self.in_item = False; #whether I'm putting properties into an item or into a layer def startElement(self, name, attrs): if name == 'map': self.columns = int(attrs.get('width', None)) self.lines = int(attrs.get('height', None)) self.tile_width = int(attrs.get('tilewidth', None)) self.tile_height = int(attrs.get('tileheight', None)) # create a tileset elif name=="image": #It's possible to use more than one tileset, but they must have identical tile sizes and identical #transparent color keys. source = attrs.get('source', None) transp = attrs.get('trans', None) if(self.tileset == None): self.tileset = Tileset(self.tile_width, self.tile_height) self.tileset.addSet(source, pygame.Color("0x" + str(transp))) # store additional properties. elif name == 'property': #add to item or layer properties depending on which parent tag we're in if self.in_item: self.items[-1].properties[attrs.get('name', None)] = attrs.get('value', None) else: self.properties[self.layers][attrs.get('name', None)] = attrs.get('value', None) # starting counting elif name == 'layer': self.line = 0 self.column = 0 self.layers += 1 self.properties.append({}); self.in_item = False # get information of each tile and put on the map elif name == 'tile': #tile ID for referencing the tile set gid = int(attrs.get('gid', None)) - 1 if gid <0: gid = 0 self.cur_row.append(self.tileset.tiles[gid]) self.column += 1 if(self.column>=self.columns): self.line += 1 self.column = 0 self.cur_layer.append(self.cur_row) self.cur_row = [] if(self.line>=self.lines): self.image.append(self.cur_layer) self.cur_layer = [] elif name == "object": #object areas can be painted in tiled, or specified by hand like in the sample map self.in_item = True x = int(attrs.get('x', None)) / self.tile_width y = int(attrs.get('y', None)) / self.tile_height if(attrs.get('type', None) == "block"): #blocks items from entering contained squares width = int(attrs.get('width', None)) / self.tile_width height = int(attrs.get('height', None)) / self.tile_height self.blocking.append(Rect(x, y, width, height)) if(attrs.get('type', None) == "boulder"): #pushable self.items.append(item.Item(sprites.Sprite("sprites/rock.png", 32, 64, Color("0x00c6c6")), Rect(x, y, 1, 1), "boulder")) if(attrs.get('type', None) == "girl"): self.items.append(item.Item(sprites.Sprite("sprites/girl.png", 32, 64, Color("0x00c6c6")), Rect(x, y, 1, 1), "person")) if(attrs.get('type', None) == "boy"): self.items.append(item.Item(sprites.Sprite("sprites/boy.png", 32, 64, Color("0x00c6c6")), Rect(x, y, 1, 1), "person"))
def start_element(self, name, attributes): if name == 'map': self.columns = int(attributes.get('width', None)) self.lines = int(attributes.get('height', None)) self.tile_width = int(attributes.get('tilewidth', None)) self.tile_height = int(attributes.get('tileheight', None)) elif name == 'image': # criar um tileset # É possível usar mais de um conjunto de peças, mas eles devem ter tamanhos e peças idênticos. # chaves de cores transparentes. source = attributes.get('source', None) transp = attributes.get('trans', None) if self.tileset is None: self.tileset = Tileset(self.tile_width, self.tile_height) self.tileset.add_set(source, ("0x" + str(transp))) elif name == 'property': # armazena propriedades adicionais. # adicionar às propriedades do item ou da camada, dependendo da tag pai em que estamos if self.in_item: self.items[-1].properties[attributes.get( 'name', None)] = attributes.get('value', None) else: self.properties[self.layers][attributes.get( 'name', None)] = attributes.get('value', None) elif name == 'layer': # começando a contagem self.line = 0 self.column = 0 self.layers += 1 self.properties.append({}) self.in_item = False elif name == 'tile': # obter informações de cada bloco e colocar no mapa # ID do arquivo para fazer referência ao conjunto de blocos gid = int(attributes.get('gid', None)) - 1 if gid < 0: gid = 0 self.cur_row.append(self.tileset.tiles[gid]) self.column += 1 if self.column >= self.columns: self.line += 1 self.column = 0 self.cur_layer.append(self.cur_row) self.cur_row = [] if self.line >= self.lines: self.image.append(self.cur_layer) self.cur_layer = [] elif name == 'object': # áreas de objetos podem ser pintadas em azulejo ou especificadas manualmente, como no mapa de amostra self.in_item = True x = int(attributes.get('x', None)) / self.tile_width y = int(attributes.get('y', None)) / self.tile_height if attributes.get( 'type', None ) == 'block': # impede que itens entrem em quadrados contidos width = int(attributes.get('width', None)) / self.tile_width height = int(attributes.get('height', None)) / self.tile_height self.blocking.append(Rect(x, y, width, height)) if attributes.get('type', None) == 'boulder': # empurrável self.items.append( item.Item( sprites.Sprite('sprites/rock.png', 32, 64, (0, 198, 198)), Rect(x, y, 1, 1), 'boulder')) if attributes.get('type', None) == 'girl': self.items.append( item.Item( sprites.Sprite('sprites/girl.png', 32, 64, (0, 198, 198)), Rect(x, y, 1, 1), 'person')) if attributes.get('type', None) == 'boy': self.items.append( item.Item( sprites.Sprite('sprites/boy.png', 32, 64, (0, 198, 198)), Rect(x, y, 1, 1), 'person'))
def startElement(self, name, attrs): if name == 'map': self.columns = int(attrs.get('width', None)) self.lines = int(attrs.get('height', None)) self.tile_width = int(attrs.get('tilewidth', None)) self.tile_height = int(attrs.get('tileheight', None)) # create a tileset elif name=="image": #It's possible to use more than one tileset, but they must have identical tile sizes and identical #transparent color keys. source = attrs.get('source', None) transp = attrs.get('trans', None) if(self.tileset == None): self.tileset = Tileset(self.tile_width, self.tile_height) self.tileset.addSet(source, pygame.Color("0x" + str(transp))) # store additional properties. elif name == 'property': #add to item or layer properties depending on which parent tag we're in if self.in_item: self.items[-1].properties[attrs.get('name', None)] = attrs.get('value', None) else: self.properties[self.layers][attrs.get('name', None)] = attrs.get('value', None) # starting counting elif name == 'layer': self.line = 0 self.column = 0 self.layers += 1 self.properties.append({}); self.in_item = False # get information of each tile and put on the map elif name == 'tile': #tile ID for referencing the tile set gid = int(attrs.get('gid', None)) - 1 if gid <0: gid = 0 self.cur_row.append(self.tileset.tiles[gid]) self.column += 1 if(self.column>=self.columns): self.line += 1 self.column = 0 self.cur_layer.append(self.cur_row) self.cur_row = [] if(self.line>=self.lines): self.image.append(self.cur_layer) self.cur_layer = [] elif name == "object": #object areas can be painted in tiled, or specified by hand like in the sample map self.in_item = True x = int(attrs.get('x', None)) / self.tile_width y = int(attrs.get('y', None)) / self.tile_height if(attrs.get('type', None) == "block"): #blocks items from entering contained squares width = int(attrs.get('width', None)) / self.tile_width height = int(attrs.get('height', None)) / self.tile_height self.blocking.append(Rect(x, y, width, height)) if(attrs.get('type', None) == "boulder"): #pushable self.items.append(item.Item(sprites.Sprite("sprites/rock.png", 32, 64, Color("0x00c6c6")), Rect(x, y, 1, 1), "boulder")) if(attrs.get('type', None) == "girl"): self.items.append(item.Item(sprites.Sprite("sprites/girl.png", 32, 64, Color("0x00c6c6")), Rect(x, y, 1, 1), "person")) if(attrs.get('type', None) == "boy"): self.items.append(item.Item(sprites.Sprite("sprites/boy.png", 32, 64, Color("0x00c6c6")), Rect(x, y, 1, 1), "person"))
from tileset import Tileset, createTilesFromImage import detect path = 'data/test_random' image_filename = 'stitch.png' createTilesFromImage(path, image_filename) tiles = Tileset(path, 3, 2, 1024, 1024, 13.02, detection_method=detect.random, ext='.png') tiles.plotHistogram('diameter') tiles.plotDensity(1, 200) tiles.plotRadius(1, 200)
class Game(Screen): move_keys = pygame.K_UP, pygame.K_RIGHT, pygame.K_DOWN, pygame.K_LEFT def __init__(self, leveldata, lskip=0): self.viewcells = 10, 6 # size of the view in cells # init levels self.leveldata = leveldata self.current_level = lskip self.level = Level(self.leveldata[self.current_level]) self.tileset = Tileset(config.tilepath, config.tilesize) def resize_view(self): """Set cell size, and resize the view and the tileset.""" # find the largest rectangle with the same ratio as viewcells ww, wh = self.window_view.get_size() vw, vh = self.viewcells self.cellsize = min(ww / vw, wh / vh) width, height = vw * self.cellsize, vh * self.cellsize left, top = int((ww - width) / 2), int((wh - height) / 2) self.view = self.window_view.subsurface((left, top, width, height)) self.tileset.init_tileset(self.cellsize) self.level.redraw = True def draw_frame(self): """Draw a frame at the current state of the level.""" # redraw cells if self.level.redraw: # draw entire level background self.background = pygame.Surface((self.level.width * self.cellsize, self.level.height * self.cellsize)) redraw_cells = self.level.cells.keys() self.level.redraw = False else: # draw individual cells redraw_cells = self.level.redraw_cells.copy() self.level.redraw_cells.clear() for cx, cy in redraw_cells: self.background.blit(self.level.get_cell((cx, cy)).draw(self.cellsize, self.tileset), (cx * self.cellsize, cy * self.cellsize)) # find offset that places the player in the centre px, py = self.level.player.pos vw, vh = self.viewcells ox = px - (vw - 1) / 2.0 oy = py - (vh - 1) / 2.0 # clamp values so as not to go off the edge ox = max(0, min(ox, self.level.width - vw)) oy = max(0, min(oy, self.level.height - vh)) # blit background onto the view left, top = int(ox * self.cellsize), int(oy * self.cellsize) width, height = self.view.get_size() self.view.blit(self.background, (0, 0), (left, top, width, height)) # update sprite positions, draw sprites, update display self.level.sprites.update(self.cellsize, (left, top), self.tileset) self.level.sprites.draw(self.view) def run_frame(self, elapsed, keys): """Run a single frame for this level.""" def advance_level(): # start the next level, or return false if there is none self.current_level += 1 try: self.level = Level(self.leveldata[self.current_level]) except IndexError: return False # check collisions for sprite in self.level.sprites: sprite.check_collisions() # check for death -> reset level if self.level.check_for_failure(): self.level = Level(self.leveldata[self.current_level]) # check for win condition -> advance level, or quit if last level if self.level.check_for_success(): if advance_level() is False: return False # handle events for key, keydown in keys: # move controls if keydown and key in self.move_keys: self.level.player.move_key_down(self.move_keys.index(key)) elif not keydown and key in self.move_keys: self.level.player.move_key_up(self.move_keys.index(key)) # skip level, or quit if last level elif keydown and key == pygame.K_RETURN: if advance_level() is False: return False # quit to menu elif keydown and key == pygame.K_ESCAPE: return False # run hooks for all sprites in layer order for sprite in self.level.sprites: sprite.start_turn() for sprite in self.level.sprites: sprite.do_move(elapsed) for sprite in self.level.sprites: if sprite.new_cell: sprite.after_move() sprite.new_cell = False for sprite in self.level.sprites: sprite.end_turn()
class Map: """ Represents the map for the game. Example usage: ``` import map default_map = map.Map(MAP_FOLDER + 'sky.tcm') print(default_map) ``` """ def __init__(self, file_name): self.file_name = file_name self.tileset = Tileset() self.layers = [] # Reading from file lines = None file = open(file_name, 'r') lines = file.read() file.close() lines = lines.splitlines() current_layer = Layer() in_a_layer = False in_a_tile = False is_tile_set_loaded = False # Parse file line by line for line in lines: if not line or line.isspace(): continue # Load tileset if not is_tile_set_loaded and line.split( '=')[0].strip() == 'tileset_file': self.tileset.load(TILESET_FOLDER + line.split('=')[1].strip()) is_tile_set_loaded = True continue if line.strip() == '{': in_a_layer = True continue elif line.strip() == '}': self.layers.append(current_layer) current_layer = Layer() in_a_layer = False continue if not in_a_layer: continue if line.strip() == '[': in_a_tile = True continue elif line.strip() == ']': in_a_tile = False continue if not in_a_tile: # We are not in a tile but in a layer, # so let's parse in the properties of the layer parts = line.strip().split('=') if len(parts) != 2: continue current_layer.set_property(parts[0].strip(), parts[1].strip()) continue # Parse in a tilerow tile_row = [ int(val.strip()) for val in line.strip().split(',') if val ] current_layer.tiles.append(tile_row) def draw(self, screen, player, from_layer_index=0, to_layer_index=5): """ Draw the tiles what the user can see. """ for layer in self.layers[from_layer_index:to_layer_index]: layer_offset_x = player.camera_x * layer.x_speed + layer.x_offset layer_offset_y = player.camera_y * layer.y_speed + layer.y_offset layer_width = len(layer.tiles[0]) layer_height = len(layer.tiles) start_x = layer_offset_x / 32 - 2 if start_x < 0: start_x = 0 start_y = layer_offset_y / 32 - 2 if start_y < 0: start_y = 0 end_x = (CONFIG.WINDOW_WIDTH + layer_offset_x) / 32 if end_x < layer_width - 1: end_x = layer_width - 1 end_y = (CONFIG.WINDOW_HEIGHT + layer_offset_y) / 32 if end_y < layer_height - 1: end_y = layer_height - 1 for y, tiles in enumerate(layer.tiles): if y < start_y: continue elif y > end_y: break for x, tile in enumerate(tiles): if tile == 0 or x < start_x: continue elif x > end_x: break screen.blit(self.tileset.tiles[tile], ( x * 32 - layer_offset_x, y * 32 - layer_offset_y, )) @staticmethod def get_tile(map, layer, x_tile, y_tile): """ :returns int: the tileid of the tile at x_tile and y_tile """ x_tile, y_tile = int(x_tile), int(y_tile) if x_tile >= 0 and x_tile < (len(map.layers[layer].tiles[0]) - 1) and y_tile >= 0 and y_tile < ( len(map.layers[layer].tiles) - 1): return map.layers[layer].tiles[y_tile][x_tile] return 0 @staticmethod def is_masked_pixel(map, layer, x_pos, y_pos): """ :returns bool: true if a pixel in map is masked in layer at (x_pos, yPos) """ x_pos, y_pos = int(x_pos), int(y_pos) if x_pos >= 0 and x_pos < (len(map.layers[layer].tiles[0]) - 1) * 32 and y_pos >= 0 and y_pos < ( len(map.layers[layer].tiles) - 1) * 32: tile_at_coords = Map.get_tile(map, layer, x_pos / 32, y_pos / 32) x_tile = tile_at_coords % 10 y_tile = int(tile_at_coords / 10) return bool(map.tileset.mask[y_tile * 32 + y_pos % 32][x_tile * 32 + x_pos % 32]) return None # In case the x_pos or y_pos tries to go outside the map @staticmethod def is_masked_h_line(map, layer, x_pos, y_pos, length): """ :returns bool: true if any pixel in map is masked in layer from (x_pos, y_pos) to (x_pos + length, y_pos) """ x_pos, y_pos, length = int(x_pos), int(y_pos), int(length) if length >= 0: for i in range(x_pos, x_pos + length): if Map.is_masked_pixel(map, layer, i, y_pos): return True else: for i in range(x_pos - length, x_pos, -1): if Map.is_masked_pixel(map, layer, i, y_pos): return True return False @staticmethod def masked_top_v_line(map, layer, x_pos, y_pos, length): """ :returns int: the index of the topmost masked pixel in inMap in layer from (x_pos, y_pos) to (x_pos, y_pos + length) """ x_pos, y_pos, length = int(x_pos), int(y_pos), int(length) for i in range(length): if Map.is_masked_pixel(map, layer, x_pos, y_pos + i): return i return length @staticmethod def masked_top_v_area(map, layer, x_pos, y_pos, h_length, v_length): """ :returns int: the index of the topmost horizontal line it finds a masked pixel in """ x_pos, y_pos, h_length, v_length = int(x_pos), int(y_pos), int( h_length), int(v_length) if v_length >= 0: for i in range(v_length): if Map.is_masked_h_line(map, layer, x_pos, y_pos + i, h_length): return i else: for i in range(v_length, 0, -1): if Map.is_masked_h_line(map, layer, x_pos, y_pos + i, h_length): return i return v_length @staticmethod def masked_first_h_area(map, layer, x_pos, y_pos, h_length, v_length): """ :returns int: the index of the first vertical line it finds a masked pixel in """ x_pos, y_pos, h_length, v_length = int(x_pos), int(y_pos), int( h_length), int(v_length) if h_length >= 0: for i in range(h_length): if Map.masked_top_v_line(map, layer, x_pos + i, y_pos, v_length): return i else: for i in range(h_length, 0, -1): if Map.masked_top_v_line(map, layer, x_pos + i, y_pos, v_length): return i return h_length
def startElement(self, name, attrs): if name == 'map': # We can get some basic info about the map from this tag if 'width' in attrs.getNames(): # Be careful here, attrs.getValue always return a # string, so always convert afterwards self.map.size[0] = int(attrs.getValue('width')) if 'height' in attrs.getNames(): self.map.size[1] = int(attrs.getValue('height')) # remember that we are in this tag self.inMap = True # Tileset tag # Add a new tileset to the map with all the options if name == 'tileset' and self.inMap == True: # Make a new blank tileset. tileset = Tileset() # Attach the map to the tileset tileset.map = self.map # Fill it with some of the new info in this tag if 'tilewidth' in attrs.getNames(): tileset.tileSize[0] = int(attrs.getValue('tilewidth')) if 'tileheight' in attrs.getNames(): tileset.tileSize[1] = int(attrs.getValue('tileheight')) if 'name' in attrs.getNames(): tileset.name = attrs.getValue('name') # K, add this tileset to the loaded map self.map.tilesets.append(tileset) # We can add things from nested tags into it later. self.inTileset = True # Image Tag # We should add this image to the current tileset if name == 'image' and self.inTileset: # Find the location of the image and load it if 'source' in attrs.getNames(): self.map.tilesets[-1].load(attrs.getValue('source'), self.map.tilesets[-1].tileSize) # K, done... assuming that image loaded. # Layer Tag if name == 'layer' and self.inMap: # Make a new layer layer = Layer() # Attach layer to map layer.map = self.map # Get the name of the layer if 'name' in attrs.getNames(): layer.name = attrs.getValue('name') # Width and Height if 'width' in attrs.getNames(): layer.width = int(attrs.getValue('width')) if 'height' in attrs.getNames(): layer.height = int(attrs.getValue('height')) # Add the new layer to the map self.map.layers.append(layer) # We're inside the layer tag now self.inLayer = True # Properties if name == 'properties' and self.inLayer: self.inProperties = True if name == 'property' and self.inProperties and self.inLayer: # Add this property to the current layer if 'name' in attrs.getNames(): if attrs.getValue('name') == 'Solid': if 'value' in attrs.getNames(): if attrs.getValue('value') == '1': self.map.layers[-1].solid = True # Data Tag if name == 'data' and self.inLayer: # Find out how the data is encoded if 'encoding' in attrs.getNames(): self.dataEncoding = attrs.getValue('encoding') # Flush the buffer self.dataBuffer = '' # Inside data, now we can load the layer data self.inData = True
def __toTileset(self, variant): variantMap = variant firstGid = variantMap.get("firstgid", 0) # Handle external tilesets sourceVariant = variantMap.get("source", '') if sourceVariant != '': source = resolvePath(self.mMapDir, sourceVariant) tileset, error = readTileset(source) if not tileset: self.mError = self.tr("Error while loading tileset '%s': %s" % (source, error)) else: self.mGidMapper.insert(firstGid, tileset) return tileset name = variantMap.get("name", '') tileWidth = variantMap.get("tilewidth", 0) tileHeight = variantMap.get("tileheight", 0) spacing = variantMap.get("spacing", 0) margin = variantMap.get("margin", 0) tileOffset = variantMap.get("tileoffset", {}) tileOffsetX = tileOffset.get("x", 0) tileOffsetY = tileOffset.get("y", 0) if (tileWidth <= 0 or tileHeight <= 0 or (firstGid == 0 and not self.mReadingExternalTileset)): self.mError = self.tr( "Invalid tileset parameters for tileset '%s'" % name) return None tileset = Tileset.create(name, tileWidth, tileHeight, spacing, margin) tileset.setTileOffset(QPoint(tileOffsetX, tileOffsetY)) trans = variantMap.get("transparentcolor", '') if (trans != '' and QColor.isValidColor(trans)): tileset.setTransparentColor(QColor(trans)) imageVariant = variantMap.get("image", '') if imageVariant != '': imagePath = resolvePath(self.mMapDir, imageVariant) if (not tileset.loadFromImage(imagePath)): self.mError = self.tr("Error loading tileset image:\n'%s'" % imagePath) return None tileset.setProperties( self.toProperties(variantMap.get("properties", {}))) # Read terrains terrainsVariantList = variantMap.get("terrains", []) for terrainMap in terrainsVariantList: tileset.addTerrain(terrainMap.get("name", ''), terrainMap.get("tile", 0)) # Read tile terrain and external image information tilesVariantMap = variantMap.get("tiles", {}) for it in tilesVariantMap.items(): ok = False tileIndex = Int(it[0]) if (tileIndex < 0): self.mError = self.tr("Tileset tile index negative:\n'%d'" % tileIndex) if (tileIndex >= tileset.tileCount()): # Extend the tileset to fit the tile if (tileIndex >= len(tilesVariantMap)): # If tiles are defined this way, there should be an entry # for each tile. # Limit the index to number of entries to prevent running out # of memory on malicious input.f self.mError = self.tr( "Tileset tile index too high:\n'%d'" % tileIndex) return None for i in range(tileset.tileCount(), tileIndex + 1): tileset.addTile(QPixmap()) tile = tileset.tileAt(tileIndex) if (tile): tileVar = it[1] terrains = tileVar.get("terrain", []) if len(terrains) == 4: for i in range(0, 4): terrainId, ok = Int2(terrains[i]) if (ok and terrainId >= 0 and terrainId < tileset.terrainCount()): tile.setCornerTerrainId(i, terrainId) probability, ok = Float2(tileVar.get("probability", 0.0)) if (ok): tile.setProbability(probability) imageVariant = tileVar.get("image", '') if imageVariant != '': imagePath = resolvePath(self.mMapDir, imageVariant) tileset.setTileImage(tileIndex, QPixmap(imagePath), imagePath) objectGroupVariant = tileVar.get("objectgroup", {}) if len(objectGroupVariant) > 0: tile.setObjectGroup(self.toObjectGroup(objectGroupVariant)) frameList = tileVar.get("animation", []) lenFrames = len(frameList) if lenFrames > 0: frames = QVector() for i in range(lenFrames): frames.append(Frame()) for i in range(lenFrames - 1, -1, -1): frameVariantMap = frameList[i] frame = frames[i] frame.tileId = frameVariantMap.get("tileid", 0) frame.duration = frameVariantMap.get("duration", 0) tile.setFrames(frames) # Read tile properties propertiesVariantMap = variantMap.get("tileproperties", {}) for it in propertiesVariantMap.items(): tileIndex = Int(it[0]) propertiesVar = it[1] if (tileIndex >= 0 and tileIndex < tileset.tileCount()): properties = self.toProperties(propertiesVar) tileset.tileAt(tileIndex).setProperties(properties) if not self.mReadingExternalTileset: self.mGidMapper.insert(firstGid, tileset) return tileset
def setupUi(self): """create all other widgets we could make the scene view the central widget but I did not figure out how to correctly draw the background with QGraphicsView/QGraphicsScene. QGraphicsView.drawBackground always wants a pixmap for a huge rect like 4000x3000 where my screen only has 1920x1200""" # pylint: disable=R0915 self.setObjectName("MainWindow") centralWidget = QWidget() scene = MJScene() self.centralScene = scene self.centralView = FittingView() layout = QGridLayout(centralWidget) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.centralView) self.tileset = None # just for pylint self.background = None # just for pylint self.tilesetName = Preferences.tilesetName self.windTileset = Tileset(Preferences.windTilesetName) self.discardBoard = DiscardBoard() self.discardBoard.setVisible(False) scene.addItem(self.discardBoard) self.selectorBoard = SelectorBoard() self.selectorBoard.setVisible(False) scene.addItem(self.selectorBoard) self.setCentralWidget(centralWidget) self.centralView.setScene(scene) self.centralView.setFocusPolicy(Qt.StrongFocus) self.adjustView() self.actionScoreGame = self.__kajonggAction("scoreGame", "draw-freehand", self.scoreGame, Qt.Key_C) self.actionPlayGame = self.__kajonggAction("play", "arrow-right", self.playGame, Qt.Key_N) self.actionAbortGame = self.__kajonggAction("abort", "dialog-close", self.abortAction, Qt.Key_W) self.actionAbortGame.setEnabled(False) self.actionQuit = self.__kajonggAction("quit", "application-exit", self.close, Qt.Key_Q) self.actionPlayers = self.__kajonggAction("players", "im-user", self.slotPlayers) self.actionRulesets = self.__kajonggAction("rulesets", "games-kajongg-law", self.slotRulesets) self.actionChat = self.__kajonggToggleAction("chat", "call-start", shortcut=Qt.Key_H, actionData=ChatWindow) game = self.game self.actionChat.setEnabled( bool(game) and bool(game.client) and not game.client.hasLocalServer()) self.actionChat.setChecked( bool(game) and bool(game.client) and bool(game.client.table.chatWindow)) self.actionScoring = self.__kajonggToggleAction( "scoring", "draw-freehand", shortcut=Qt.Key_S, actionData=ScoringDialog) self.actionScoring.setEnabled(False) self.actionAngle = self.__kajonggAction("angle", "object-rotate-left", self.changeAngle, Qt.Key_G) self.actionAngle.setEnabled(False) self.actionFullscreen = KToggleFullScreenAction( self.actionCollection()) self.actionFullscreen.setShortcut(Qt.CTRL + Qt.Key_F) self.actionFullscreen.setShortcutContext(Qt.ApplicationShortcut) self.actionFullscreen.setWindow(self) self.actionCollection().addAction("fullscreen", self.actionFullscreen) self.actionFullscreen.toggled.connect(self.fullScreen) self.actionScoreTable = self.__kajonggToggleAction( "scoreTable", "format-list-ordered", Qt.Key_T, actionData=ScoreTable) self.actionExplain = self.__kajonggToggleAction( "explain", "applications-education", Qt.Key_E, actionData=ExplainView) self.actionAutoPlay = self.__kajonggAction("demoMode", "arrow-right-double", None, Qt.Key_D) self.actionAutoPlay.setCheckable(True) self.actionAutoPlay.toggled.connect(self.__toggleDemoMode) self.actionAutoPlay.setChecked(Internal.autoPlay) QMetaObject.connectSlotsByName(self)
from Objects.map import Map from names import Names import pygame from tileset import Tileset from date import Date from Objects.university import University # Important global variables # Object that generates human names names = Names() # Our pygame object pygame = pygame # Tileset of game graphics tileset = Tileset(pygame, './Resources/city_tiles.png', 8, 21) # Standard size of one tile tile_size = 8 # How much we scale each tile tile_scale = 2 # Current date date = Date() # The University university = University() import admissions admissions.first_students() from Objects.program import * programs = {
def loadTilesetFromResource(self, name): tileset = Tileset.create(name, 32, 32) tileset.loadFromImage(QImage(":/" + name + ".png"), name + ".png") return tileset
def set_tileset(self, path): try: newtileset = Tileset(path) self.tileset = newtileset except Exception as e: print(f'error creating tileset: {e}')
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
def setupUi(self): """prepare scene""" # pylint: disable=too-many-statements self.windTileset = Tileset(Internal.Preferences.windTilesetName)
def __init__(self, file_name): self.file_name = file_name self.tileset = Tileset() self.layers = [] # Reading from file lines = None file = open(file_name, 'r') lines = file.read() file.close() lines = lines.splitlines() current_layer = Layer() in_a_layer = False in_a_tile = False is_tile_set_loaded = False # Parse file line by line for line in lines: if not line or line.isspace(): continue # Load tileset if not is_tile_set_loaded and line.split( '=')[0].strip() == 'tileset_file': self.tileset.load(TILESET_FOLDER + line.split('=')[1].strip()) is_tile_set_loaded = True continue if line.strip() == '{': in_a_layer = True continue elif line.strip() == '}': self.layers.append(current_layer) current_layer = Layer() in_a_layer = False continue if not in_a_layer: continue if line.strip() == '[': in_a_tile = True continue elif line.strip() == ']': in_a_tile = False continue if not in_a_tile: # We are not in a tile but in a layer, # so let's parse in the properties of the layer parts = line.strip().split('=') if len(parts) != 2: continue current_layer.set_property(parts[0].strip(), parts[1].strip()) continue # Parse in a tilerow tile_row = [ int(val.strip()) for val in line.strip().split(',') if val ] current_layer.tiles.append(tile_row)
def setupUi(self): """create all other widgets we could make the scene view the central widget but I did not figure out how to correctly draw the background with QGraphicsView/QGraphicsScene. QGraphicsView.drawBackground always wants a pixmap for a huge rect like 4000x3000 where my screen only has 1920x1200""" # pylint: disable=too-many-statements self.setObjectName("MainWindow") centralWidget = QWidget() self.centralView = FittingView() layout = QGridLayout(centralWidget) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.centralView) self.setCentralWidget(centralWidget) self.centralView.setFocusPolicy(Qt.StrongFocus) self.background = None # just for pylint self.windTileset = Tileset(Internal.Preferences.windTilesetName) self.adjustMainView() self.actionScoreGame = self.kajonggAction("scoreGame", "draw-freehand", self.scoringScene, Qt.Key_C) self.actionPlayGame = self.kajonggAction("play", "arrow-right", self.playGame, Qt.Key_N) self.actionAbortGame = self.kajonggAction("abort", "dialog-close", self.abortAction, Qt.Key_W) self.actionAbortGame.setEnabled(False) self.actionQuit = self.kajonggAction("quit", "application-exit", self.close, Qt.Key_Q) self.actionPlayers = self.kajonggAction("players", "im-user", self.slotPlayers) self.actionRulesets = self.kajonggAction("rulesets", "games-kajongg-law", self.slotRulesets) self.actionChat = self._kajonggToggleAction("chat", "call-start", shortcut=Qt.Key_H, actionData=ChatWindow) self.actionChat.setEnabled(False) self.actionAngle = self.kajonggAction("angle", "object-rotate-left", self.changeAngle, Qt.Key_G) self.actionAngle.setEnabled(False) self.actionScoreTable = self._kajonggToggleAction( "scoreTable", "format-list-ordered", Qt.Key_T, actionData=ScoreTable) self.actionScoreTable.setEnabled(False) self.actionExplain = self._kajonggToggleAction( "explain", "applications-education", Qt.Key_E, actionData=ExplainView) self.actionExplain.setEnabled(False) self.actionFullscreen = self._kajonggToggleAction("fullscreen", "view-fullscreen", shortcut=Qt.Key_F + Qt.ShiftModifier) self.actionFullscreen.toggled.connect(self.fullScreen) self.actionAutoPlay = self.kajonggAction("demoMode", "arrow-right-double", None, Qt.Key_D) self.actionAutoPlay.setCheckable(True) self.actionAutoPlay.setEnabled(True) self.actionAutoPlay.toggled.connect(self._toggleDemoMode) self.actionAutoPlay.setChecked(Internal.autoPlay) QMetaObject.connectSlotsByName(self)
def tilesetName(self, name): """the name of the current tileset""" self.tileset = Tileset(name)
def __toTileset(self, variant): variantMap = variant firstGid = variantMap.get("firstgid",0) # Handle external tilesets sourceVariant = variantMap.get("source", '') if sourceVariant != '': source = resolvePath(self.mMapDir, sourceVariant) tileset, error = readTileset(source) if not tileset: self.mError = self.tr("Error while loading tileset '%s': %s"%(source, error)) else: self.mGidMapper.insert(firstGid, tileset) return tileset name = variantMap.get("name",'') tileWidth = variantMap.get("tilewidth",0) tileHeight = variantMap.get("tileheight",0) spacing = variantMap.get("spacing",0) margin = variantMap.get("margin",0) tileOffset = variantMap.get("tileoffset", {}) tileOffsetX = tileOffset.get("x",0) tileOffsetY = tileOffset.get("y",0) if (tileWidth <= 0 or tileHeight <= 0 or (firstGid == 0 and not self.mReadingExternalTileset)): self.mError = self.tr("Invalid tileset parameters for tileset '%s'"%name) return None tileset = Tileset.create(name, tileWidth, tileHeight, spacing, margin) tileset.setTileOffset(QPoint(tileOffsetX, tileOffsetY)) trans = variantMap.get("transparentcolor", '') if (trans!='' and QColor.isValidColor(trans)): tileset.setTransparentColor(QColor(trans)) imageVariant = variantMap.get("image",'') if imageVariant != '': imagePath = resolvePath(self.mMapDir, imageVariant) if (not tileset.loadFromImage(imagePath)): self.mError = self.tr("Error loading tileset image:\n'%s'"%imagePath) return None tileset.setProperties(self.toProperties(variantMap.get("properties", {}))) # Read terrains terrainsVariantList = variantMap.get("terrains", []) for terrainMap in terrainsVariantList: tileset.addTerrain(terrainMap.get("name", ''), terrainMap.get("tile", 0)) # Read tile terrain and external image information tilesVariantMap = variantMap.get("tiles", {}) for it in tilesVariantMap.items(): ok = False tileIndex = Int(it[0]) if (tileIndex < 0): self.mError = self.tr("Tileset tile index negative:\n'%d'"%tileIndex) if (tileIndex >= tileset.tileCount()): # Extend the tileset to fit the tile if (tileIndex >= len(tilesVariantMap)): # If tiles are defined this way, there should be an entry # for each tile. # Limit the index to number of entries to prevent running out # of memory on malicious input.f self.mError = self.tr("Tileset tile index too high:\n'%d'"%tileIndex) return None for i in range(tileset.tileCount(), tileIndex+1): tileset.addTile(QPixmap()) tile = tileset.tileAt(tileIndex) if (tile): tileVar = it[1] terrains = tileVar.get("terrain", []) if len(terrains) == 4: for i in range(0, 4): terrainId, ok = Int2(terrains[i]) if (ok and terrainId >= 0 and terrainId < tileset.terrainCount()): tile.setCornerTerrainId(i, terrainId) probability, ok = Float2(tileVar.get("probability", 0.0)) if (ok): tile.setProbability(probability) imageVariant = tileVar.get("image",'') if imageVariant != '': imagePath = resolvePath(self.mMapDir, imageVariant) tileset.setTileImage(tileIndex, QPixmap(imagePath), imagePath) objectGroupVariant = tileVar.get("objectgroup", {}) if len(objectGroupVariant) > 0: tile.setObjectGroup(self.toObjectGroup(objectGroupVariant)) frameList = tileVar.get("animation", []) lenFrames = len(frameList) if lenFrames > 0: frames = QVector() for i in range(lenFrames): frames.append(Frame()) for i in range(lenFrames - 1, -1, -1): frameVariantMap = frameList[i] frame = frames[i] frame.tileId = frameVariantMap.get("tileid", 0) frame.duration = frameVariantMap.get("duration", 0) tile.setFrames(frames) # Read tile properties propertiesVariantMap = variantMap.get("tileproperties", {}) for it in propertiesVariantMap.items(): tileIndex = Int(it[0]) propertiesVar = it[1] if (tileIndex >= 0 and tileIndex < tileset.tileCount()): properties = self.toProperties(propertiesVar) tileset.tileAt(tileIndex).setProperties(properties) if not self.mReadingExternalTileset: self.mGidMapper.insert(firstGid, tileset) return tileset
levels_text.append("Level 1\n\nToday a freak meteor hit an orbiting space station and caused\nit to fall out of orbit. We have calculated that it will hit Boxopolis and we need\nyour help to find our best astronaut and our rocket ship. We only have\n60 seconds to get our astronaut into space before the space station is too\nclose to stop.") levels_text.append("Level 2\n\nThe neighboring nation of Grasslandia has just declared war on\nBoxopolis, their army is already on their way to our capital and we need you to help\nus assemble our army. We need you to find our military airships, our troops\nand the general. Their army is approaching quickly so you only have\n60 seconds before they reach our capital.") levels_text.append("Level 3\n\nOur scientists have recent discovered a deadly disease that has\nbeen spreading through the population of Boxopolis. Our scientists have found a\ncure, but don't have the materials necessary to produce enough for the rest of the\npopulation.It is up to you to find the materials they need. The disease is spreading\nquickly so you only have 60 seconds to help the scientists with their cure.") levels_text.append("Level 4\n\nThe ambassador from the local neighboring country of Bearland was on his\nway to our capital to discuss our relations as countries. His motorcade was\nlost and we need your help to find him, find our diplomat and find the materials for\nthe meeting. Relations between Bearland and Boxopolis are rocky at best and if\nthis meeting doesn't happen soon they will declare war. You only\nhave 60 seconds before they declare war.") levels_text.append("Level 5\n\nThe Capitol of Boxopolis is being attacked by a wild dinosaur. Our leader\nhas determined that the best way to fight this dinosaur is to use our own giant\ndinosaurs along with our fearless general in his plane. We need you to find the\ndinosaur, the plane and our general. Our capitol city is being destroyed quickly\nso you only have 60 seconds before the city is destroyed.") levels_text.append("Level 6\n\nOur espionage teams have recovered information that points to you being\nabducted and taken to the mad doctor's office. Our leader has a plan, but he\nneeds your help before he can put his plan into action. He needs to gather our army,\nbuilding materials and the Special Forces unit to help our leader keep you hidden\nand safe. This information doesn't point to when you will be abducted\nso our leader has decided that if you don't come back within\n60 seconds you will be presumed abducted.") levels_text.append("Level 7\n\nA great fire approaches the capitol city. We need your help to find our\nfire brigade to help put out the fire and our armed forces to supplement our\nfire brigade. The fire comes closer every second so you only have 60 seconds\nto put out the fire.") levels_text.append("Level 8\n\nOur scientists have found a meteor hurtling towards Boxopolis and we only\nhave a short amount of time to stop it. We need you to find and bring back\nour best astronauts, our rocket and something to break the meteor with. The meteor\nis getting closer at a rapid pace so you only have 60 seconds before the meteor is\ntoo close to do anything about.") levels_text.append("Level 9\n\nLooks like the army ants are on the move. We need to be ready in case they\nattack. They move quickly so you only have 60 seconds to find supplies of\nfood, fortification materials, and extra vehicles in case civilians need to be\nevacuated.") levels_text.append("Level 10\n\nThe army ants attacked and we are defenseless. We need you to do everything\nin your power to help save the capitol of Boxopolis. We need every service\nperson and vehicle we can find. We need you to find the Fire brigade, our General,\nthe Special Forces unit, the air units and our army. Good luck, you only have\n60 seconds.") levelTime = 60.0 state = START_MENU goal_obstacles = [] screen = pygame.display.set_mode((1024, 768), HWSURFACE|DOUBLEBUF) tileset = Tileset("../assets/maps/Level1.tmx") walls = [] obstacles = [] player = Player((32, 32), 1, lambda o: collide_obstacle(o)) clock = pygame.time.Clock() allsprites = pygame.sprite.RenderPlain(obstacles) allsprites.add(player) font = pygame.font.Font(None,36) init() start_bg, start_rect = resources.load_image("../assets/images/bg/start.bmp") win_bg, win_rect = resources.load_image("../assets/images/bg/win.bmp")
def __init__(self, width, height): Board.__init__(self, width, height, Tileset.activeTileset()) self.setAcceptDrops(True)
class Game(object): def __init__(self): self.maze_tiles = None self.pacman_tiles = None @staticmethod def tile_to_screen(x, y): """Returns tile bounding box (screen coordinates). Keyword argument(s): tile -- Tile coordinates (x, y) """ x *= TILE_WIDTH y *= TILE_HEIGHT return x, y, x + TILE_WIDTH - 1, y + TILE_HEIGHT - 1 @staticmethod def screen_to_tile(x, y): """Convert screen coordinate/point to tile/maze coordinate. Keyword argument(s): coordinate -- Screen coordinate (x, y) Returns tile coordinate. """ # This is weird, no? # Should be: # return x / TILE_WIDTH, y / TILE_HEIGHT return (x / TILE_WIDTH) + 1, (y / TILE_HEIGHT) + 1 @staticmethod def is_aligned(coordinate): """Check if coordinate is aligned with tile border. Keyword argument(s): coordinate -- Coordinate to check Returns True if aligned, False otherwise. """ return (coordinate + 4) % 8 == 0 def get_sprite_bounding_box(self, sprite): """Returns sprite bounding box. Keyword argument(s): sprite -- The sprite """ return (sprite.x, sprite.y, sprite.x + SPRITE_WIDTH - 1, sprite.y + SPRITE_HEIGHT - 1) def setup(self): """Setup game.""" pygame.init() pygame.display.set_caption("pacman") self.maze_tiles = Tileset("data/tiles.gif", TILE_WIDTH, TILE_HEIGHT) self.pacman_tiles = Tileset("data/pacman.gif", SPRITE_WIDTH, SPRITE_HEIGHT) def write_message(self, x, y, message): """Write message. Keyword arguments: x -- x-coordinate y -- y-coordinate message -- Message to write """ for i, char in enumerate(message): self.maze_tiles.draw(x + i, y, ord(char)) def legal_move(self, maze, sprite, delta): """Check if move is collision. Keyword argument(s): maze -- Maze/playfield sprite -- Sprite to move delta -- Delta tuple (x, y) Returns True if the move is collision, False otherwise. """ x, y = self.screen_to_tile(sprite.x + delta[0], sprite.y + delta[1]) next_tile_type = maze[(x + delta[0], y + delta[1])] collision = False if next_tile_type > 3: # > 3 is wall type x0, y0, x1, y1 = self.tile_to_screen(x, y) x2, y2, x3, y3 = self.get_sprite_bounding_box(sprite) if delta[0] > 0 and x3 >= x1 + 4: # Right collision = True elif delta[0] < 0 and x2 - 1 < x0 - 4: # Left collision = True elif delta[1] > 0 and y3 - 4 >= y1: # Down collision = True elif delta[1] < 0 and y2 + 4 <= y0: # Up collision = True aligned = False if delta[0] != 0: # left/right align y aligned = self.is_aligned(sprite.y) elif delta[1] != 0: # up/down align x aligned = self.is_aligned(sprite.x) return aligned and not collision def game_loop(self): """Main loop. """ pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) score = 0 high_score = 0 maze = Maze(self.maze_tiles, HORIZONTAL_TILES, VERTICAL_TILES) maze.load_level(maze.MAZE) pac = PacMan(104, 204, self.pacman_tiles) delta = (0, 0) while True: event = pygame.event.poll() if event.type == pygame.QUIT: sys.exit(0) if event.type == pygame.KEYUP: if event.key == pygame.K_ESCAPE: sys.exit(0) pressed = pygame.key.get_pressed() if pressed[pygame.K_LEFT]: delta = (-1, 0) elif pressed[pygame.K_RIGHT]: delta = (1, 0) elif pressed[pygame.K_DOWN]: delta = (0, 1) elif pressed[pygame.K_UP]: delta = (0, -1) x, y = self.screen_to_tile(pac.x, pac.y) if maze[(x, y)] > 0: score += 10 maze[(x, y)] = 0 if score > high_score: high_score = score if self.legal_move(maze, pac, delta): pac.delta = delta elif not self.legal_move(maze, pac, pac.delta): pac.delta = (0, 0) pac.move() maze.draw() pac.draw() self.write_message(3, 0, "1UP") self.write_message(4, 1, str(score)) self.write_message(9, 0, "HIGH SCORE") self.write_message(10, 1, str(score)) pygame.display.flip()
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