mirror of https://github.com/FreeCol/freecol.git
194 lines
6.6 KiB
Java
194 lines
6.6 KiB
Java
/**
|
|
* Copyright (C) 2002-2022 The FreeCol Team
|
|
*
|
|
* This file is part of FreeCol.
|
|
*
|
|
* FreeCol is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* FreeCol is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with FreeCol. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
package net.sf.freecol.client.gui.animation;
|
|
|
|
import java.awt.Image;
|
|
import java.util.logging.Logger;
|
|
import javax.swing.ImageIcon;
|
|
import javax.swing.JLabel;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
import net.sf.freecol.client.gui.ImageLibrary;
|
|
import net.sf.freecol.common.io.sza.AnimationEvent;
|
|
import net.sf.freecol.common.io.sza.ImageAnimationEvent;
|
|
import net.sf.freecol.common.io.sza.SimpleZippedAnimation;
|
|
import net.sf.freecol.common.model.Direction;
|
|
import net.sf.freecol.common.model.Tile;
|
|
import net.sf.freecol.common.model.Unit;
|
|
import static net.sf.freecol.common.util.CollectionUtils.*;
|
|
import static net.sf.freecol.common.util.ImageUtils.*;
|
|
import static net.sf.freecol.common.util.StringUtils.*;
|
|
import net.sf.freecol.common.util.Utils;
|
|
|
|
|
|
/**
|
|
* Class for in-place animation of units.
|
|
*/
|
|
public final class UnitImageAnimation extends Animation {
|
|
|
|
private static final Logger logger = Logger.getLogger(UnitImageAnimation.class.getName());
|
|
|
|
/**
|
|
Alternate directions to check when a directional animation is
|
|
not found.
|
|
*/
|
|
public static final Map<Direction, List<Direction>> alternatives
|
|
= new HashMap<>();
|
|
|
|
/** The animation image series. */
|
|
private final SimpleZippedAnimation animation;
|
|
|
|
/** Reflect the images? */
|
|
private boolean mirror;
|
|
|
|
|
|
/**
|
|
* Build a new image animation.
|
|
*
|
|
* @param unit The {@code Unit} to be animated.
|
|
* @param tile The {@code Tile} where the animation occurs.
|
|
* @param animation The {@code SimpleZippedAnimation} to show.
|
|
*/
|
|
public UnitImageAnimation(Unit unit, Tile tile,
|
|
SimpleZippedAnimation animation) {
|
|
super(unit, makeUnmodifiableList(tile));
|
|
|
|
this.animation = animation;
|
|
this.mirror = false;
|
|
}
|
|
|
|
/**
|
|
* Set the mirror state.
|
|
*
|
|
* @param mirror The new mirror state.
|
|
*/
|
|
public void setMirrored(boolean mirror) {
|
|
this.mirror = mirror;
|
|
}
|
|
|
|
|
|
/**
|
|
* Get a list of directions to try when looking for a
|
|
* direction-keyed animation given a preferred direction which has
|
|
* failed.
|
|
*
|
|
* @param direction The preferred {@code Direction}.
|
|
* @return A list of {@code Direction}s.
|
|
*/
|
|
private static synchronized List<Direction> trialDirections(Direction direction) {
|
|
if (alternatives.isEmpty()) { // Populate first time
|
|
// Favour the closest E-W cases
|
|
for (Direction d : Direction.allDirections) {
|
|
List<Direction> a = new ArrayList<>();
|
|
a.add(d);
|
|
switch (d) {
|
|
case N: case S:
|
|
a.add(Direction.E); a.add(Direction.W);
|
|
a.add(d.rotate(1)); a.add(d.rotate(-1));
|
|
a.add(d.rotate(3)); a.add(d.rotate(-3));
|
|
break;
|
|
case NE: case SW:
|
|
a.add(d.rotate(1));
|
|
a.add(d.rotate(2));
|
|
a.add(d.rotate(-1)); a.add(d.rotate(3));
|
|
break;
|
|
case NW: case SE:
|
|
a.add(d.rotate(-1));
|
|
a.add(d.rotate(-2));
|
|
a.add(d.rotate(1)); a.add(d.rotate(-3));
|
|
break;
|
|
case E: case W:
|
|
a.add(d.rotate(1)); a.add(d.rotate(-1));
|
|
a.add(d.rotate(2)); a.add(d.rotate(-2));
|
|
break;
|
|
}
|
|
alternatives.put(d, a);
|
|
}
|
|
}
|
|
return alternatives.get(direction);
|
|
}
|
|
|
|
/**
|
|
* Static quasi-constructor that can fail harmlessly.
|
|
*
|
|
* @param unit The {@code Unit} to be animated.
|
|
* @param tile The {@code Tile} where the animation occurs.
|
|
* @param dirn The {@code Direction} of the attack.
|
|
* @param base The base prefix for the animation resource.
|
|
* @param scale The gui scale.
|
|
* @return The animation found or null if none present.
|
|
*/
|
|
public static UnitImageAnimation build(Unit unit, Tile tile,
|
|
Direction dirn,
|
|
String base, float scale) {
|
|
for (Direction d : trialDirections(dirn)) {
|
|
String szaId = base + downCase(d.toString());
|
|
SimpleZippedAnimation sza = ImageLibrary.getSZA(szaId, scale);
|
|
if (sza != null) {
|
|
return new UnitImageAnimation(unit, tile, sza);
|
|
}
|
|
// Try the mirrored case
|
|
szaId = base + downCase(d.getEWMirroredDirection().toString());
|
|
sza = ImageLibrary.getSZA(szaId, scale);
|
|
if (sza != null) {
|
|
UnitImageAnimation ret = new UnitImageAnimation(unit, tile, sza);
|
|
ret.setMirrored(true);
|
|
return ret;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
|
|
// Implement Animation
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
public void executeWithLabel(JLabel unitLabel,
|
|
Animations.Procedure paintCallback) {
|
|
final ImageIcon icon = (ImageIcon)unitLabel.getIcon();
|
|
|
|
// Step through the animation, chaning the image
|
|
for (AnimationEvent event : animation) {
|
|
long time = System.nanoTime();
|
|
if (event instanceof ImageAnimationEvent) {
|
|
final ImageAnimationEvent ievent = (ImageAnimationEvent)event;
|
|
Image image = ievent.getImage();
|
|
if (mirror) {
|
|
// FIXME: Add mirroring functionality to SimpleZippedAnimation
|
|
image = createMirroredImage(image);
|
|
}
|
|
icon.setImage(image);
|
|
paintCallback.execute(); // paint now
|
|
|
|
// Time accounting
|
|
time = ievent.getDurationInMs()
|
|
- (System.nanoTime() - time) / 1000000;
|
|
if (time > 0) Utils.delay(time, "Animation delayed.");
|
|
}
|
|
}
|
|
}
|
|
}
|