use of games.strategy.triplea.util.Stopwatch 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();
}
use of games.strategy.triplea.util.Stopwatch in project triplea by triplea-game.
the class TileImageFactory method loadUnblendedImage.
private Image loadUnblendedImage(final URL imageLocation, final String fileName, final boolean transparent, final boolean cache, final boolean scaled) {
Image image;
try {
final Stopwatch loadingImages = new Stopwatch(logger, Level.FINE, "Loading image:" + imageLocation);
final BufferedImage fromFile = ImageIO.read(imageLocation);
loadingImages.done();
final Stopwatch copyingImage = new Stopwatch(logger, Level.FINE, "Copying image:" + imageLocation);
// if we dont copy, drawing the tile to the screen takes significantly longer
// has something to do with the colour model and type of the images
// some images can be copeid quickly to the screen
// this step is a significant bottle neck in the image drawing process
// we should try to find a way to avoid it, and load the
// png directly as the right type
image = Util.createImage(fromFile.getWidth(null), fromFile.getHeight(null), transparent);
final Graphics2D g = (Graphics2D) image.getGraphics();
if (scaled && scale != 1.0) {
final AffineTransform transform = new AffineTransform();
transform.scale(scale, scale);
g.setTransform(transform);
}
g.drawImage(fromFile, 0, 0, null);
g.dispose();
fromFile.flush();
copyingImage.done();
} catch (final IOException e) {
ClientLogger.logError("Could not load image, url: " + imageLocation.toString(), e);
image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
}
final ImageRef ref = new ImageRef(image);
if (cache) {
imageCache.put(fileName, ref);
}
return image;
}
use of games.strategy.triplea.util.Stopwatch in project triplea by triplea-game.
the class SmallMapImageManager method update.
public void update(final MapData mapData) {
final Stopwatch stopwatch = new Stopwatch(logger, Level.FINEST, "Small map updating took");
final Graphics onScreenGraphics = view.getOffScreenImage().getGraphics();
onScreenGraphics.drawImage(offscreen, 0, 0, null);
for (final UnitsDrawer drawer : new ArrayList<>(tileManager.getUnitDrawables())) {
final int x = (int) (drawer.getPlacementPoint().x * view.getRatioX());
final int y = (int) (drawer.getPlacementPoint().y * view.getRatioY());
onScreenGraphics.setColor(mapData.getPlayerColor(drawer.getPlayer()).darker());
onScreenGraphics.fillRect(x, y, UNIT_BOX_SIZE, UNIT_BOX_SIZE);
}
onScreenGraphics.dispose();
stopwatch.done();
}
use of games.strategy.triplea.util.Stopwatch in project triplea by triplea-game.
the class TileImageFactory method loadBlendedImage.
private Image loadBlendedImage(final String fileName, final boolean cache, final boolean scaled) {
BufferedImage reliefFile = null;
BufferedImage baseFile = null;
// The relief tile
final String reliefFileName = fileName.replace("baseTiles", "reliefTiles");
final URL urlrelief = resourceLoader.getResource(reliefFileName);
// The base tile
final String baseFileName = fileName.replace("reliefTiles", "baseTiles");
final URL urlBase = resourceLoader.getResource(baseFileName);
// blank relief tile
final String blankReliefFileName = "reliefTiles/blank_relief.png";
final URL urlBlankRelief = resourceLoader.getResource(blankReliefFileName);
// Get buffered images
try {
final Stopwatch loadingImages = new Stopwatch(logger, Level.FINE, "Loading images:" + urlrelief + " and " + urlBase);
if (urlrelief != null) {
reliefFile = loadCompatibleImage(urlrelief);
}
if (urlBase != null) {
baseFile = loadCompatibleImage(urlBase);
}
loadingImages.done();
} catch (final IOException e) {
ClientLogger.logQuietly("Failed to load one or more images: " + urlrelief + ", " + urlBase, e);
}
// This does the blend
final float alpha = getShowMapBlendAlpha();
if (reliefFile == null) {
try {
reliefFile = loadCompatibleImage(urlBlankRelief);
} catch (final IOException e) {
ClientLogger.logQuietly("Failed to load image: " + urlBlankRelief, e);
}
}
// This fixes the blank land territories
if (baseFile == null) {
baseFile = makeMissingBaseTile(reliefFile);
}
/* reversing the to/from files leaves white underlays visible */
if (reliefFile != null) {
final BufferedImage blendedImage = new BufferedImage(reliefFile.getWidth(null), reliefFile.getHeight(null), BufferedImage.TYPE_INT_ARGB);
final Graphics2D g2 = blendedImage.createGraphics();
if (scaled && scale != 1.0) {
final AffineTransform transform = new AffineTransform();
transform.scale(scale, scale);
g2.setTransform(transform);
}
g2.drawImage(reliefFile, 0, 0, null);
final BlendingMode blendMode = BlendComposite.BlendingMode.valueOf(getShowMapBlendMode());
final BlendComposite blendComposite = BlendComposite.getInstance(blendMode).derive(alpha);
g2.setComposite(blendComposite);
g2.drawImage(baseFile, 0, 0, null);
final ImageRef ref = new ImageRef(blendedImage);
if (cache) {
imageCache.put(fileName, ref);
}
return blendedImage;
}
final ImageRef ref = new ImageRef(baseFile);
if (cache) {
imageCache.put(fileName, ref);
}
return baseFile;
}
use of games.strategy.triplea.util.Stopwatch in project triplea by triplea-game.
the class HeadedUiContext method internalSetMapDir.
@Override
protected void internalSetMapDir(final String dir, final GameData data) {
final Stopwatch stopWatch = new Stopwatch(logger, Level.FINE, "Loading UI Context");
resourceLoader = ResourceLoader.getMapResourceLoader(dir);
if (mapData != null) {
mapData.close();
}
mapData = new MapData(resourceLoader);
// DiceImageFactory needs loader and game data
diceImageFactory = new DiceImageFactory(resourceLoader, data.getDiceSides());
final double unitScale = getPreferencesMapOrSkin(dir).getDouble(UNIT_SCALE_PREF, mapData.getDefaultUnitScale());
scale = getPreferencesMapOrSkin(dir).getDouble(MAP_SCALE_PREF, 1);
if (scale < 1) {
setDrawTerritoryBordersAgainToMedium();
}
unitImageFactory.setResourceLoader(resourceLoader, unitScale, mapData.getDefaultUnitWidth(), mapData.getDefaultUnitHeight(), mapData.getDefaultUnitCounterOffsetWidth(), mapData.getDefaultUnitCounterOffsetHeight());
// TODO: separate scale for resources
resourceImageFactory.setResourceLoader(resourceLoader);
territoryEffectImageFactory.setResourceLoader(resourceLoader);
flagIconImageFactory.setResourceLoader(resourceLoader);
puImageFactory.setResourceLoader(resourceLoader);
tileImageFactory.setMapDir(resourceLoader);
tileImageFactory.setScale(scale);
// load map data
mapImage.loadMaps(resourceLoader);
mapDir = dir;
drawTerritoryEffects = mapData.useTerritoryEffectMarkers();
// load the sounds in a background thread,
// avoids the pause where sounds dont load right away
// change the resource loader (this allows us to play sounds the map folder, rather than just default sounds)
new Thread(() -> ClipPlayer.getInstance(resourceLoader), "Triplea sound loader").start();
// load a new cursor
cursor = Cursor.getDefaultCursor();
final Toolkit toolkit = Toolkit.getDefaultToolkit();
// URL's use "/" not "\"
final URL cursorUrl = resourceLoader.getResource("misc" + "/" + "cursor.gif");
if (cursorUrl != null) {
try {
final Image image = ImageIO.read(cursorUrl);
if (image != null) {
final Point hotSpot = new Point(mapData.getMapCursorHotspotX(), mapData.getMapCursorHotspotY());
cursor = toolkit.createCustomCursor(image, hotSpot, data.getGameName() + " Cursor");
}
} catch (final Exception e) {
ClientLogger.logQuietly("Failed to create cursor from: " + cursorUrl, e);
}
}
stopWatch.done();
}
Aggregations