private void addTileByGlobalTileID( final int pGlobalTileID, final ITMXTilePropertiesListener pTMXTilePropertyListener) { final TMXTiledMap tmxTiledMap = this.mTMXTiledMap; final int tilesHorizontal = this.mTileColumns; final int column = this.mTilesAdded % tilesHorizontal; final int row = this.mTilesAdded / tilesHorizontal; final TMXTile[][] tmxTiles = this.mTMXTiles; final ITextureRegion tmxTileTextureRegion; if (pGlobalTileID == 0) { tmxTileTextureRegion = null; } else { tmxTileTextureRegion = tmxTiledMap.getTextureRegionFromGlobalTileID(pGlobalTileID); } final int tileHeight = this.mTMXTiledMap.getTileHeight(); final int tileWidth = this.mTMXTiledMap.getTileWidth(); if (this.mTexture == null) { this.mTexture = tmxTileTextureRegion.getTexture(); super.initBlendFunction(this.mTexture); } else { if (this.mTexture != tmxTileTextureRegion.getTexture()) { throw new AndEngineRuntimeException( "All TMXTiles in a TMXLayer need to be in the same TMXTileSet."); } } final TMXTile tmxTile = new TMXTile(pGlobalTileID, column, row, tileWidth, tileHeight, tmxTileTextureRegion); tmxTiles[row][column] = tmxTile; this.setIndex(this.getSpriteBatchIndex(column, row)); this.drawWithoutChecks( tmxTileTextureRegion, tmxTile.getTileX(), tmxTile.getTileY(), tileWidth, tileHeight, Color.WHITE_ABGR_PACKED_FLOAT); this .submit(); // TODO Doesn't need to be called here, but should rather be called in a "init" // step, when parsing the XML is complete. if (pGlobalTileID != 0) { /* Notify the ITMXTilePropertiesListener if it exists. */ if (pTMXTilePropertyListener != null) { final TMXProperties<TMXTileProperty> tmxTileProperties = tmxTiledMap.getTMXTileProperties(pGlobalTileID); if (tmxTileProperties != null) { pTMXTilePropertyListener.onTMXTileWithPropertiesCreated( tmxTiledMap, this, tmxTile, tmxTileProperties); } } } this.mTilesAdded++; }
/** * 渲染当前层画面到LGraphics之上 * * @param g * @param x * @param y * @param sx * @param sy * @param width * @param ty * @param isLine * @param mapTileWidth * @param mapTileHeight */ public void draw( Canvas g, int x, int y, int sx, int sy, int width, int ty, boolean isLine, int mapTileWidth, int mapTileHeight) { int tileCount = map.getTileSetCount(); int nx, ny, sheetX, sheetY, tileOffsetY; for (int tileset = 0; tileset < tileCount; tileset++) { TMXTileSet set = null; for (int tx = 0; tx < width; tx++) { nx = sx + tx; ny = sy + ty; if ((nx < 0) || (ny < 0)) { continue; } if ((nx >= this.width) || (ny >= this.height)) { continue; } if (data[nx][ny][0] == tileset) { if (set == null) { set = map.getTileSet(tileset); } sheetX = set.getTileX(data[nx][ny][1]); sheetY = set.getTileY(data[nx][ny][1]); tileOffsetY = set.tileHeight - mapTileHeight; set.tiles.draw( g, x + (tx * mapTileWidth), y + (ty * mapTileHeight) - tileOffsetY, sheetX, sheetY); } } if (isLine) { if (set != null) { set = null; } map.rendered(ty, ty + sy, index); } } }
/** * @param pX in SceneCoordinates. * @param pY in SceneCoordinates. * @return the {@link TMXTile} located at <code>pX/pY</code>. */ public TMXTile getTMXTileAt(final float pX, final float pY) { final float[] localCoords = this.convertSceneToLocalCoordinates(pX, pY); final TMXTiledMap tmxTiledMap = this.mTMXTiledMap; final int tileColumn = (int) (localCoords[SpriteBatch.VERTEX_INDEX_X] / tmxTiledMap.getTileWidth()); if (tileColumn < 0 || tileColumn > this.mTileColumns - 1) { return null; } final int tileRow = (int) (localCoords[SpriteBatch.VERTEX_INDEX_Y] / tmxTiledMap.getTileWidth()); if (tileRow < 0 || tileRow > this.mTileRows - 1) { return null; } return this.mTMXTiles[tileRow][tileColumn]; }
public TMXLayer( final TMXTiledMap pTMXTiledMap, final Attributes pAttributes, final VertexBufferObjectManager pVertexBufferObjectManager) { super( null, SAXUtils.getIntAttributeOrThrow(pAttributes, TMXConstants.TAG_LAYER_ATTRIBUTE_WIDTH) * SAXUtils.getIntAttributeOrThrow(pAttributes, TMXConstants.TAG_LAYER_ATTRIBUTE_HEIGHT), pVertexBufferObjectManager); this.mTMXTiledMap = pTMXTiledMap; this.mName = pAttributes.getValue("", TMXConstants.TAG_LAYER_ATTRIBUTE_NAME); this.mTileColumns = SAXUtils.getIntAttributeOrThrow(pAttributes, TMXConstants.TAG_LAYER_ATTRIBUTE_WIDTH); this.mTileRows = SAXUtils.getIntAttributeOrThrow(pAttributes, TMXConstants.TAG_LAYER_ATTRIBUTE_HEIGHT); this.mTMXTiles = new TMXTile[this.mTileRows][this.mTileColumns]; this.mWidth = pTMXTiledMap.getTileWidth() * this.mTileColumns; this.mHeight = pTMXTiledMap.getTileHeight() * this.mTileRows; this.mRotationCenterX = this.mWidth * 0.5f; this.mRotationCenterY = this.mHeight * 0.5f; this.mScaleCenterX = this.mRotationCenterX; this.mScaleCenterY = this.mRotationCenterY; this.mGlobalTileIDsExpected = this.mTileColumns * this.mTileRows; this.setVisible( SAXUtils.getIntAttribute( pAttributes, TMXConstants.TAG_LAYER_ATTRIBUTE_VISIBLE, TMXConstants.TAG_LAYER_ATTRIBUTE_VISIBLE_VALUE_DEFAULT) == 1); this.setAlpha( SAXUtils.getFloatAttribute( pAttributes, TMXConstants.TAG_LAYER_ATTRIBUTE_OPACITY, TMXConstants.TAG_LAYER_ATTRIBUTE_OPACITY_VALUE_DEFAULT)); }
/** * 设置指定位置的瓦片ID * * @param x * @param y * @param tile */ public void setTileID(int x, int y, int tile) { if (tile == 0) { data[x][y][0] = -1; data[x][y][1] = 0; data[x][y][2] = 0; } else { TMXTileSet set = map.findTileSet(tile); data[x][y][0] = set.index; data[x][y][1] = tile - set.firstGID; data[x][y][2] = tile; } }
/** * 根据TMX地图描述创建一个新层 * * @param map * @param element * @throws RuntimeException */ public TMXLayer(TMXTiledMap map, Element element) throws RuntimeException { this.map = map; name = element.getAttribute("name"); width = Integer.parseInt(element.getAttribute("width")); height = Integer.parseInt(element.getAttribute("height")); data = new int[width][height][3]; // 获得当前图层属性 Element propsElement = (Element) element.getElementsByTagName("properties").item(0); if (propsElement != null) { NodeList properties = propsElement.getElementsByTagName("property"); if (properties != null) { props = new TMXProperty(); for (int p = 0; p < properties.getLength(); p++) { Element propElement = (Element) properties.item(p); String name = propElement.getAttribute("name"); String value = propElement.getAttribute("value"); props.setProperty(name, value); } } } Element dataNode = (Element) element.getElementsByTagName("data").item(0); String encoding = dataNode.getAttribute("encoding"); String compression = dataNode.getAttribute("compression"); // 进行base64的压缩解码 if ("base64".equals(encoding) && "gzip".equals(compression)) { try { Node cdata = dataNode.getFirstChild(); char[] enc = cdata.getNodeValue().trim().toCharArray(); byte[] dec = decodeBase64(enc); GZIPInputStream is = new GZIPInputStream(new ByteArrayInputStream(dec)); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int tileId = 0; tileId |= is.read(); tileId |= is.read() << 8; tileId |= is.read() << 16; tileId |= is.read() << 24; if (tileId == 0) { data[x][y][0] = -1; data[x][y][1] = 0; data[x][y][2] = 0; } else { TMXTileSet set = map.findTileSet(tileId); if (set != null) { data[x][y][0] = set.index; data[x][y][1] = tileId - set.firstGID; } data[x][y][2] = tileId; } } } } catch (IOException e) { throw new RuntimeException("Unable to decode base64 !"); } } else { throw new RuntimeException( "Unsupport tiled map type " + encoding + "," + compression + " only gzip base64 Support !"); } }