Search in sources :

Example 1 with Tile

use of games.strategy.triplea.ui.screen.Tile in project triplea by triplea-game.

the class MapPanel method updateUndrawnTiles.

/**
 * If we have nothing left undrawn, draw the tiles within preDrawMargin of us, optionally
 * forcing the tiles to remain in memory.
 */
private void updateUndrawnTiles(final List<Tile> undrawnTiles, final int preDrawMargin, final boolean forceInMemory) {
    // that way when we scroll slowly we wont notice a glitch
    if (undrawnTiles.isEmpty()) {
        final Rectangle2D extendedBounds = new Rectangle2D.Double(Math.max(model.getX() - preDrawMargin, 0), Math.max(model.getY() - preDrawMargin, 0), getScaledWidth() + (2 * preDrawMargin), getScaledHeight() + (2 * preDrawMargin));
        final List<Tile> tileList = tileManager.getTiles(extendedBounds);
        for (final Tile tile : tileList) {
            if (tile.isDirty()) {
                undrawnTiles.add(tile);
            } else if (forceInMemory) {
                images.add(tile);
            }
        }
    }
}
Also used : Rectangle2D(java.awt.geom.Rectangle2D) Tile(games.strategy.triplea.ui.screen.Tile)

Example 2 with Tile

use of games.strategy.triplea.ui.screen.Tile in project triplea by triplea-game.

the class MapPanel method paint.

@Override
public void paint(final Graphics g) {
    final Graphics2D g2d = (Graphics2D) g;
    super.paint(g2d);
    g2d.clip(new Rectangle2D.Double(0, 0, (getImageWidth() * scale), (getImageHeight() * scale)));
    int x = model.getX();
    int y = model.getY();
    final List<Tile> images = new ArrayList<>();
    final List<Tile> undrawnTiles = new ArrayList<>();
    final Stopwatch stopWatch = new Stopwatch(Logger.getLogger(MapPanel.class.getName()), Level.FINER, "Paint");
    // make sure we use the same data for the entire paint
    final GameData data = gameData;
    // if the map fits on screen, dont draw any overlap
    final boolean fitAxisX = !mapWidthFitsOnScreen() && uiContext.getMapData().scrollWrapX();
    final boolean fitAxisY = !mapHeightFitsOnScreen() && uiContext.getMapData().scrollWrapY();
    if (fitAxisX || fitAxisY) {
        if (fitAxisX && x + (int) getScaledWidth() > model.getMaxWidth()) {
            x -= model.getMaxWidth();
        }
        if (fitAxisY && y + (int) getScaledHeight() > model.getMaxHeight()) {
            y -= model.getMaxHeight();
        }
        // handle wrapping off the screen
        if (fitAxisX && x < 0) {
            if (fitAxisY && y < 0) {
                final Rectangle2D.Double leftUpperBounds = new Rectangle2D.Double(model.getMaxWidth() + x, model.getMaxHeight() + y, -x, -y);
                drawTiles(g2d, images, data, leftUpperBounds, undrawnTiles);
            }
            final Rectangle2D.Double leftBounds = new Rectangle2D.Double(model.getMaxWidth() + x, y, -x, getScaledHeight());
            drawTiles(g2d, images, data, leftBounds, undrawnTiles);
        }
        if (fitAxisY && y < 0) {
            final Rectangle2D.Double upperBounds = new Rectangle2D.Double(x, model.getMaxHeight() + y, getScaledWidth(), -y);
            drawTiles(g2d, images, data, upperBounds, undrawnTiles);
        }
    }
    // handle non overlap
    final Rectangle2D.Double mainBounds = new Rectangle2D.Double(x, y, getScaledWidth(), getScaledHeight());
    drawTiles(g2d, images, data, mainBounds, undrawnTiles);
    if (routeDescription != null && mouseShadowImage != null && routeDescription.getEnd() != null) {
        final AffineTransform t = new AffineTransform();
        t.translate(scale * normalizeX(routeDescription.getEnd().getX() - getXOffset()), scale * normalizeY(routeDescription.getEnd().getY() - getYOffset()));
        t.translate(mouseShadowImage.getWidth() / -2, mouseShadowImage.getHeight() / -2);
        t.scale(scale, scale);
        g2d.drawImage(mouseShadowImage, t, this);
    }
    if (routeDescription != null) {
        routeDrawer.drawRoute(g2d, routeDescription, movementLeftForCurrentUnits, movementFuelCost, uiContext.getResourceImageFactory());
    }
    // used to keep strong references to what is on the screen so it wont be garbage collected
    // other references to the images are weak references
    this.images.clear();
    this.images.addAll(images);
    if (highlightedUnits != null) {
        for (final Entry<Territory, List<Unit>> entry : highlightedUnits.entrySet()) {
            final Set<UnitCategory> categories = UnitSeperator.categorize(entry.getValue());
            for (final UnitCategory category : categories) {
                final List<Unit> territoryUnitsOfSameCategory = category.getUnits();
                if (territoryUnitsOfSameCategory.isEmpty()) {
                    continue;
                }
                final Rectangle r = tileManager.getUnitRect(territoryUnitsOfSameCategory, gameData);
                if (r == null) {
                    continue;
                }
                final Optional<Image> image = uiContext.getUnitImageFactory().getHighlightImage(category.getType(), category.getOwner(), category.hasDamageOrBombingUnitDamage(), category.getDisabled());
                if (image.isPresent()) {
                    final AffineTransform t = new AffineTransform();
                    t.translate(normalizeX(r.getX() - getXOffset()) * scale, normalizeY(r.getY() - getYOffset()) * scale);
                    t.scale(scale, scale);
                    g2d.drawImage(image.get(), t, this);
                }
            }
        }
    }
    // draw the tiles nearest us first
    // then draw farther away
    updateUndrawnTiles(undrawnTiles, 30, true);
    updateUndrawnTiles(undrawnTiles, 257, true);
    // when we are this far away, dont force the tiles to stay in memroy
    updateUndrawnTiles(undrawnTiles, 513, false);
    updateUndrawnTiles(undrawnTiles, 767, false);
    clearPendingDrawOperations();
    undrawnTiles.forEach(tile -> pendingDrawOperations.add(Tuple.of(tile, data)));
    stopWatch.done();
}
Also used : Territory(games.strategy.engine.data.Territory) GameData(games.strategy.engine.data.GameData) Rectangle2D(java.awt.geom.Rectangle2D) ArrayList(java.util.ArrayList) Stopwatch(games.strategy.triplea.util.Stopwatch) Rectangle(java.awt.Rectangle) Tile(games.strategy.triplea.ui.screen.Tile) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit) TimeUnit(java.util.concurrent.TimeUnit) Image(java.awt.Image) BufferedImage(java.awt.image.BufferedImage) Point(java.awt.Point) Graphics2D(java.awt.Graphics2D) AffineTransform(java.awt.geom.AffineTransform) List(java.util.List) ArrayList(java.util.ArrayList) UnitCategory(games.strategy.triplea.util.UnitCategory)

Example 3 with Tile

use of games.strategy.triplea.ui.screen.Tile in project triplea by triplea-game.

the class MapPanel method drawMapImage.

/**
 * Draws an image of the complete map to the specified graphics context.
 *
 * <p>
 * This method is useful for capturing screenshots. This method can be called from a thread other than the EDT.
 * </p>
 *
 * @param g The graphics context on which to draw the map; must not be {@code null}.
 */
public void drawMapImage(final Graphics g) {
    final Graphics2D g2d = (Graphics2D) checkNotNull(g);
    // make sure we use the same data for the entire print
    final GameData gameData = this.gameData;
    gameData.acquireReadLock();
    try {
        final Rectangle2D.Double bounds = new Rectangle2D.Double(0, 0, getImageWidth(), getImageHeight());
        final Collection<Tile> tileList = tileManager.getTiles(bounds);
        for (final Tile tile : tileList) {
            tile.acquireLock();
            try {
                final Image img = tile.getImage(gameData, uiContext.getMapData());
                if (img != null) {
                    final AffineTransform t = new AffineTransform();
                    t.translate((tile.getBounds().x - bounds.getX()) * scale, (tile.getBounds().y - bounds.getY()) * scale);
                    g2d.drawImage(img, t, this);
                }
            } finally {
                tile.releaseLock();
            }
        }
    } finally {
        gameData.releaseReadLock();
    }
}
Also used : GameData(games.strategy.engine.data.GameData) Rectangle2D(java.awt.geom.Rectangle2D) Tile(games.strategy.triplea.ui.screen.Tile) AffineTransform(java.awt.geom.AffineTransform) Image(java.awt.Image) BufferedImage(java.awt.image.BufferedImage) Graphics2D(java.awt.Graphics2D)

Example 4 with Tile

use of games.strategy.triplea.ui.screen.Tile in project triplea by triplea-game.

the class MapPanel method drawTiles.

private void drawTiles(final Graphics2D g, final List<Tile> images, final GameData data, Rectangle2D.Double bounds, final List<Tile> undrawn) {
    final List<Tile> tileList = tileManager.getTiles(bounds);
    bounds = new Rectangle2D.Double(bounds.getX(), bounds.getY(), bounds.getHeight(), bounds.getWidth());
    for (final Tile tile : tileList) {
        final Image img;
        tile.acquireLock();
        try {
            if (tile.isDirty()) {
                // take what we can get to avoid screen flicker
                undrawn.add(tile);
                img = tile.getRawImage();
            } else {
                img = tile.getImage(data, uiContext.getMapData());
                images.add(tile);
            }
            if (img != null) {
                final AffineTransform t = new AffineTransform();
                t.translate(scale * (tile.getBounds().x - bounds.getX()), scale * (tile.getBounds().y - bounds.getY()));
                g.drawImage(img, t, this);
            }
        } finally {
            tile.releaseLock();
        }
    }
}
Also used : Rectangle2D(java.awt.geom.Rectangle2D) Tile(games.strategy.triplea.ui.screen.Tile) AffineTransform(java.awt.geom.AffineTransform) Image(java.awt.Image) BufferedImage(java.awt.image.BufferedImage)

Aggregations

Tile (games.strategy.triplea.ui.screen.Tile)4 Rectangle2D (java.awt.geom.Rectangle2D)4 Image (java.awt.Image)3 AffineTransform (java.awt.geom.AffineTransform)3 BufferedImage (java.awt.image.BufferedImage)3 GameData (games.strategy.engine.data.GameData)2 Graphics2D (java.awt.Graphics2D)2 Territory (games.strategy.engine.data.Territory)1 Unit (games.strategy.engine.data.Unit)1 TripleAUnit (games.strategy.triplea.TripleAUnit)1 Stopwatch (games.strategy.triplea.util.Stopwatch)1 UnitCategory (games.strategy.triplea.util.UnitCategory)1 Point (java.awt.Point)1 Rectangle (java.awt.Rectangle)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 TimeUnit (java.util.concurrent.TimeUnit)1