/** * Load all tiles from the layer * * @param element the layer element * @return an array containing all tile information of this layer * @throws IOException * @throws Exception */ private TileInfo[][] loadTiles(TmxLayer element) throws IOException, Exception { List<Integer> ids = element.getData().getIds(); int id = 0; TileInfo[][] result = new TileInfo[width][height]; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int tileId = ids.get(id++); if (tileId == 0) { result[x][y] = null; } else { TileSet set = map.findTileSet(tileId); if (set != null) { result[x][y] = new TileInfo( set.getIndex(), tileId - set.getFirstGID(), tileId, set.getTileProperties(tileId)); } else { result[x][y] = new TileInfo(0, 0, tileId, null); } } } } return result; }
/** * Find a tile for a given global tile id * * @param gid The global tile id we're looking for * @return The tileset in which that tile lives or null if the gid is not defined */ public TileSet findTileSet(int gid) { for (int i = 0; i < tileSets.size(); i++) { TileSet set = (TileSet) tileSets.get(i); if (set.contains(gid)) { return set; } } return null; }
public void setTile(int value) { if (value < 0) { tilesetRow = -1; tilesetColumn = -1; hasTile = false; } else { tilesetRow = value / tileset.getColumns(); tilesetColumn = value % tileset.getColumns(); hasTile = true; } }
/** * Get a propety given to a particular tile. Note that this method will not perform well and * should not be used as part of the default code path in the game loop. * * @param tileID The global ID of the tile to retrieve * @param propertyName The name of the property to retireve * @param def The default value to return * @return The value assigned to the property on the tile (or the default value if none is * supplied) */ public String getTileProperty(int tileID, String propertyName, String def) { if (tileID == 0) { return def; } TileSet set = findTileSet(tileID); Properties props = set.getProperties(tileID); if (props == null) { return def; } return props.getProperty(propertyName, def); }
/** * Gets the Image used to draw the tile at the given x and y coordinates. * * @param x The x coordinate of the tile whose image should be retrieved * @param y The y coordinate of the tile whose image should be retrieved * @param layerIndex The index of the layer on which the tile whose image should be retrieve * exists * @return The image used to draw the specified tile or null if there is no image for the * specified tile. */ public Image getTileImage(int x, int y, int layerIndex) { Layer layer = (Layer) layers.get(layerIndex); int tileSetIndex = layer.data[x][y][0]; if ((tileSetIndex >= 0) && (tileSetIndex < tileSets.size())) { TileSet tileSet = (TileSet) tileSets.get(tileSetIndex); int sheetX = tileSet.getTileX(layer.data[x][y][1]); int sheetY = tileSet.getTileY(layer.data[x][y][1]); return tileSet.tiles.getSprite(sheetX, sheetY); } return null; }
/** @param set */ public void setTileSet(TileSet set) { if (tileset != null && tileset != set) { setImage(set.addImage(getImage())); } tileset = set; }
/** @return */ public int getHeight() { if (tileset != null) { Dimension d = tileset.getImageDimensions(tileImageId); return d.height; } return 0; }
/** @return */ public int getWidth() { if (tileset != null) { Dimension d = tileset.getImageDimensions(tileImageId); return d.width; } return 0; }
/** * Handle left click on a picture by bringing it to the top. * * @param event The object providing details of the mouse event. */ public void mousePressed(final MouseEvent event) { Picture picture; if (!event.isMetaDown()) { picture = mMosaic.pictureAt(event.getX(), event.getY()); if (null != picture) bringToTop(picture); } }
/** * Paints this component. Runs through the list of tiles and for every one that intersects the * clip region performs a <code>drawImage()</code>. * * @param graphics The graphics context used to paint with. */ public void paint(final Graphics graphics) { Rectangle clip; Enumeration enumeration; HashSet set; // just so we don't draw things twice Picture picture; Image image; Point origin; int width; int height; adjustClipForInsets(graphics); clip = graphics.getClipBounds(); synchronized (mMosaic) { if (0 == mMosaic.getSize()) super.paint(graphics); else { super.paint(graphics); enumeration = mMosaic.getPictures(); set = new HashSet(); while (enumeration.hasMoreElements()) { picture = (Picture) enumeration.nextElement(); if ((null == clip) || (clip.intersects(picture))) { image = picture.getImage(); if (!set.contains(image)) { origin = picture.getOrigin(); width = image.getWidth(this); height = image.getHeight(this); graphics.drawImage( picture.getImage(), origin.x, origin.y, origin.x + width, origin.y + height, 0, 0, width, height, this); set.add(image); } } } } } }
/** * Find a picture with the given URL in the panel. This should really only be used to discover if * the picture is still visible. There could be more than one picture with the given URL because * it may be partially obscured by another picture, in which case the pieces are each given their * own picture object, but all point at the same <code>URL</code> and <code>Image</code>. * * @param url The url to locate. * @return The first picture encountered in the panel, or null if the picture was not found. */ public Picture find(final String url) { Enumeration enumeration; Picture picture; Picture ret; ret = null; enumeration = mMosaic.getPictures(); while ((null == ret) && enumeration.hasMoreElements()) { picture = (Picture) enumeration.nextElement(); if (url.equals(picture.getURL().toExternalForm())) ret = picture; } return (ret); }
/** * Draw an image on screen. * * @param picture The picture to draw. * @param add If <code>true</code>, the picture is added to the history. */ protected void draw(final Picture picture, final boolean add) { Component parent; boolean dolayout; Dimension before; Dimension after; parent = getParent(); dolayout = false; synchronized (mMosaic) { if (parent instanceof JViewport) { before = getPreferredSize(); mMosaic.add(picture); after = calculatePreferredSize(); if (after.width > before.width) dolayout = true; else after.width = before.width; if (after.height > before.height) dolayout = true; else after.height = before.height; if (dolayout) mPreferredSize = after; } else mMosaic.add(picture); } if (dolayout) revalidate(); repaint(picture.x, picture.y, picture.width, picture.height); if (add) mThumbelina.addHistory(picture.getURL().toExternalForm()); }
@Override public void init(AssetManagerX assetManager) { engine = new Engine(); entityManager = new EntityManager(); physixManager = new PhysixManager(BOX2D_SCALE, 0, GRAVITY); map = loadMap("data/maps/SebFirstPlayable_reworked.tmx"); HashMap<TileSet, Texture> tilesetImages = new HashMap(); for (TileSet tileset : map.getTileSets()) { TmxImage img = tileset.getImage(); String filename = CurrentResourceLocator.combinePaths(tileset.getFilename(), img.getSource()); tilesetImages.put(tileset, new Texture(filename)); } mapRenderer = new TiledMapRendererGdx(map, tilesetImages); // Generate static world int tileWidth = map.getTileWidth(); int tileHeight = map.getTileHeight(); RectangleGenerator generator = new RectangleGenerator(); generator.generate( map, (Layer layer, TileInfo info) -> info.getBooleanProperty("blocked", false), (Rectangle rect) -> addShape(physixManager, rect, tileWidth, tileHeight)); }
/** * Compute the preferred size of the component. Computes the minimum bounding rectangle covering * all the pictures in the panel. It then does some funky stuff to handle embedding in the view * port of a scroll pane, basically asking up the ancestor heirarchy what size is available, and * filling it. * * @return The optimal dimension for this component. */ protected Dimension calculatePreferredSize() { Enumeration enumeration; int x; int y; Picture picture; Component parent; Insets insets; Dimension ret; enumeration = mMosaic.getPictures(); x = 0; y = 0; picture = null; while (enumeration.hasMoreElements()) { picture = (Picture) enumeration.nextElement(); if (picture.x + picture.width > x) x = picture.x + picture.width; if (picture.y + picture.height > y) y = picture.y + picture.height; } parent = getParent(); if (parent instanceof JViewport) { ret = parent.getSize(); insets = ((JViewport) parent).getInsets(); ret.width -= insets.left + insets.right; ret.height -= insets.top + insets.bottom; if ((0 != ret.width) || (0 != ret.height)) ret.width -= 2; // ... I dunno why, it just needs it if (ret.width < x) ret.width = x; if (ret.height < y) ret.height = y; } else { insets = getInsets(); x += insets.left + insets.right; y += insets.top + insets.bottom; ret = new Dimension(x, y); } return (ret); }
/** * Move the given picture to the top of the Z order. Adds it, even it if it doesn't exist. Also * puts the URL in the url text of the status bar. * * @param picture The picture being brought forward. */ public void bringToTop(final Picture picture) { picture.reset(); mMosaic.bringToTop(picture); repaint(picture.x, picture.y, picture.width, picture.height); mThumbelina.mUrlText.setText(picture.getURL().toExternalForm()); }
/** * Changes the image of the tile as long as it is not null. * * @param i the new image of the tile */ public void setImage(Image i) { if (tileset != null) { tileset.overlayImage(tileImageId, i); } }
/** * Returns the tile image for this Tile. * * @return Image */ public Image getImage() { if (tileset != null) { return tileset.getImageById(tileImageId); } return null; }
/** * Create a new layer object * * @param node The xml node storing the information we need */ LayerObject(TiledMap map, TmxObject node, PolyMode polyMode) { this.node = node; properties = node.getProperties(); if (node.getPolygon() != null) { primitive = Primitive.POLYGON; } else if (node.getPolyline() != null) { primitive = Primitive.POLYLINE; } else if (node.getGid() != null) { primitive = Primitive.TILE; } else if (node.getWidth() == null || node.getHeight() == null) { primitive = Primitive.POINT; } else { primitive = Primitive.RECT; } x = (int) node.getX(); y = (int) node.getY(); width = (node.getWidth() == null) ? 0 : node.getWidth().intValue(); height = (node.getHeight() == null) ? 0 : node.getHeight().intValue(); if (primitive == Primitive.POLYGON || primitive == Primitive.POLYLINE) { TmxPointList pointsNode = node.getPolygon(); if (pointsNode == null) { pointsNode = node.getPolyline(); } String[] numbers = pointsNode.getPoints().split("[\\s,]"); points = new ArrayList(); lowestX = 0; lowestY = 0; for (int i = 0; i < numbers.length; i += 2) { int px = Integer.parseInt(numbers[i]); int py = Integer.parseInt(numbers[i + 1]); points.add(new Point(px, py)); if (px < lowestX) { lowestX = px; } if (py < lowestY) { lowestY = py; } } if (polyMode == PolyMode.RELATIVE_TO_TOPLEFT && (lowestX < 0 || lowestY < 0)) { for (Point p : points) { p.x += -lowestX; p.y += -lowestY; } x -= -lowestX; y -= -lowestY; } else if (polyMode == PolyMode.ABSOLUTE) { int dx = (int) node.getX(); int dy = (int) node.getY(); for (Point p : points) { p.x += dx; p.y += dy; } x = 0; y = 0; } lowestX += node.getX(); lowestY += node.getY(); } else { points = null; lowestX = (int) node.getX(); lowestY = (int) node.getY(); if (primitive == Primitive.TILE) { TileSet set = map.findTileSet(node.getGid()); if (set != null) { width = set.getTileWidth(); height = set.getTileHeight(); if (properties == null) { properties = new SafeProperties(); } properties.setDefaults(set.getTileProperties(node.getGid())); lowestY -= height; } } } }
public void draw(Graphics g, int x, int y) { if (hasTile) tileset.drawTile(g, this, x, y); }
/** * Load a TilED map * * @param in The input stream from which to load the map * @param tileSetsLocation The location from which we can retrieve tileset images * @throws SlickException Indicates a failure to parse the map or find a tileset */ private void load(InputStream in, String tileSetsLocation) throws SlickException { tilesLocation = tileSetsLocation; try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(false); DocumentBuilder builder = factory.newDocumentBuilder(); builder.setEntityResolver( new EntityResolver() { public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { return new InputSource(new ByteArrayInputStream(new byte[0])); } }); Document doc = builder.parse(in); Element docElement = doc.getDocumentElement(); if (docElement.getAttribute("orientation").equals("orthogonal")) { orientation = ORTHOGONAL; } else { orientation = ISOMETRIC; } width = Integer.parseInt(docElement.getAttribute("width")); height = Integer.parseInt(docElement.getAttribute("height")); tileWidth = Integer.parseInt(docElement.getAttribute("tilewidth")); tileHeight = Integer.parseInt(docElement.getAttribute("tileheight")); // now read the map properties Element propsElement = (Element) docElement.getElementsByTagName("properties").item(0); if (propsElement != null) { NodeList properties = propsElement.getElementsByTagName("property"); if (properties != null) { props = new Properties(); 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); } } } if (loadTileSets) { TileSet tileSet = null; TileSet lastSet = null; NodeList setNodes = docElement.getElementsByTagName("tileset"); for (int i = 0; i < setNodes.getLength(); i++) { Element current = (Element) setNodes.item(i); tileSet = new TileSet(this, current, !headless); tileSet.index = i; if (lastSet != null) { lastSet.setLimit(tileSet.firstGID - 1); } lastSet = tileSet; tileSets.add(tileSet); } } NodeList layerNodes = docElement.getElementsByTagName("layer"); for (int i = 0; i < layerNodes.getLength(); i++) { Element current = (Element) layerNodes.item(i); Layer layer = new Layer(this, current); layer.index = i; layers.add(layer); } // acquire object-groups NodeList objectGroupNodes = docElement.getElementsByTagName("objectgroup"); for (int i = 0; i < objectGroupNodes.getLength(); i++) { Element current = (Element) objectGroupNodes.item(i); ObjectGroup objectGroup = new ObjectGroup(current, this); objectGroup.index = i; objectGroups.add(objectGroup); } } catch (Exception e) { Log.error(e); throw new SlickException("Failed to parse tilemap", e); } }