/**
* Copyright (C) 2002-2012 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 org.freecolandroid.repackaged.java.awt.Point;
import org.freecolandroid.repackaged.java.awt.Rectangle;
import org.freecolandroid.repackaged.javax.swing.JLabel;
import net.sf.freecol.client.FreeColClient;
import net.sf.freecol.client.gui.GUI;
import net.sf.freecol.client.gui.OutForAnimationCallback;
import net.sf.freecol.common.model.Tile;
import net.sf.freecol.common.model.Unit;
/**
* Class for the animation of units movement.
*/
final class UnitMoveAnimation {
/*
* Display delay between one frame and another, in milliseconds.
* 33ms == 30 fps
*/
private static final int ANIMATION_DELAY = 33;
private final Unit unit;
private final Tile sourceTile;
private final Tile destinationTile;
private GUI gui;
private FreeColClient freeColClient;
/**
* Constructor
*
* @param canvas The <code>Canvas</code> to draw the animation on.
* @param unit The <code>Unit</code> to be animated.
* @param sourceTile The <code>Tile</code> the unit is moving from.
* @param destinationTile The <code>Tile</code> the unit is moving to.
*/
public UnitMoveAnimation(FreeColClient freeColClient, GUI gui, Unit unit, Tile sourceTile,
Tile destinationTile) {
this.freeColClient = freeColClient;
this.gui = gui;
this.unit = unit;
this.sourceTile = sourceTile;
this.destinationTile = destinationTile;
}
/**
* Do the animation.
*/
public void animate() {
final int movementSpeed = Animations.getAnimationSpeed(freeColClient, unit);
final Point srcP = gui.getTilePosition(sourceTile);
final Point dstP = gui.getTilePosition(destinationTile);
if (srcP == null || dstP == null || movementSpeed <= 0) return;
float scale = gui.getMapScale();
final int movementRatio = (int)(Math.pow(2, movementSpeed + 1) * scale);
final Rectangle r1 = gui.getTileBounds(sourceTile);
final Rectangle r2 = gui.getTileBounds(destinationTile);
final Rectangle bounds = r1.union(r2);
gui.executeWithUnitOutForAnimation(unit, sourceTile,
new OutForAnimationCallback() {
public void executeWithUnitOutForAnimation(final JLabel unitLabel) {
final Point srcPoint
= gui.getMapViewer().getUnitLabelPositionInTile(unitLabel, srcP);
final Point dstPoint
= gui.getMapViewer().getUnitLabelPositionInTile(unitLabel, dstP);
final double xratio = gui.getMapViewer().getTileWidth()
/ gui.getMapViewer().getTileHeight();
final int stepX = (srcPoint.getX() == dstPoint.getX()) ? 0
: (srcPoint.getX() > dstPoint.getX()) ? -1 : 1;
final int stepY = (srcPoint.getY() == dstPoint.getY()) ? 0
: (srcPoint.getY() > dstPoint.getY()) ? -1 : 1;
// Painting the whole screen once to get rid of
// disposed dialog-boxes.
gui.paintImmediatelyCanvasInItsBounds();
int dropFrames = 0;
Point point = srcPoint;
while (!point.equals(dstPoint)) {
long time = System.currentTimeMillis();
point.x += stepX * xratio * movementRatio;
point.y += stepY * movementRatio;
if ((stepX < 0 && point.x < dstPoint.x)
|| (stepX > 0 && point.x > dstPoint.x)) {
point.x = dstPoint.x;
}
if ((stepY < 0 && point.y < dstPoint.y)
|| (stepY > 0 && point.y > dstPoint.y)) {
point.y = dstPoint.y;
}
if (dropFrames <= 0) {
unitLabel.setLocation(point);
gui.paintImmediatelyCanvasIn(bounds);
int timeTaken = (int)(System.currentTimeMillis()
- time);
final int waitTime = ANIMATION_DELAY - timeTaken;
if (waitTime > 0) {
try {
Thread.sleep(waitTime);
} catch (InterruptedException ex) {
//ignore
}
dropFrames = 0;
} else {
dropFrames = timeTaken / ANIMATION_DELAY - 1;
}
} else {
dropFrames--;
}
}
}
});
}
}