Pulled out gobs of Sprite/Animation functionality into AbstractMedia.
Pulled out gobs of SpriteManager/AnimationManager functionality into AbstractMediaManager. The big change: sprites can have their render order fine-tuned like animations. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@1787 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -1,15 +1,11 @@
|
||||
//
|
||||
// $Id: Animation.java,v 1.8 2002/09/20 21:28:20 mdb Exp $
|
||||
// $Id: Animation.java,v 1.9 2002/10/08 21:03:37 ray Exp $
|
||||
|
||||
package com.threerings.media.animation;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
import com.threerings.media.AbstractMedia;
|
||||
import com.threerings.media.Log;
|
||||
|
||||
/**
|
||||
@@ -17,7 +13,7 @@ import com.threerings.media.Log;
|
||||
* provide animation functionality. It is generally used in conjunction
|
||||
* with an {@link AnimationManager}.
|
||||
*/
|
||||
public abstract class Animation
|
||||
public abstract class Animation extends AbstractMedia
|
||||
{
|
||||
/**
|
||||
* Constructs an animation.
|
||||
@@ -26,80 +22,7 @@ public abstract class Animation
|
||||
*/
|
||||
public Animation (Rectangle bounds)
|
||||
{
|
||||
_bounds = bounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the render order of this animation.
|
||||
*/
|
||||
public int getRenderOrder ()
|
||||
{
|
||||
return _renderOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the render order associated with this animation. Animations
|
||||
* can be rendered in two layers; those with negative render order and
|
||||
* those with positive render order. In the same layer, animations
|
||||
* will be rendered according to their render order's cardinal value
|
||||
* (least to greatest). Those with the same render order value will be
|
||||
* rendered in arbitrary order.
|
||||
*
|
||||
* <p> This must be set <em>before</em> the animation is handed to the
|
||||
* {@link AnimationManager} and must not change while the {@link
|
||||
* AnimationManager} is managing the animation. If you wish to change
|
||||
* the render order, remove the animation from the manager, change the
|
||||
* order and add it back again.
|
||||
*/
|
||||
public void setRenderOrder (int value)
|
||||
{
|
||||
_renderOrder = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the location at which this animation will be rendered.
|
||||
*/
|
||||
public void setLocation (int x, int y)
|
||||
{
|
||||
_bounds.x = x;
|
||||
_bounds.y = y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a rectangle containing all pixels rendered by this
|
||||
* animation.
|
||||
*/
|
||||
public Rectangle getBounds ()
|
||||
{
|
||||
return _bounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called periodically by the {@link AnimationManager} to give the
|
||||
* animation a chance to do its thing.
|
||||
*
|
||||
* @param tickStamp the system time for this tick.
|
||||
*/
|
||||
public abstract void tick (long tickStamp);
|
||||
|
||||
/**
|
||||
* Called by the {@link AnimationManager} to request that the
|
||||
* animation render itself with the given graphics context. The
|
||||
* animation may wish to inspect the clipping region that has been set
|
||||
* on the graphics context to render itself more efficiently. This
|
||||
* method will only be called after it has been established that this
|
||||
* animation's bounds intersect the clipping region.
|
||||
*/
|
||||
public abstract void paint (Graphics2D gfx);
|
||||
|
||||
/**
|
||||
* This is called if the animation manager is paused for some length
|
||||
* of time and then unpaused. Animations should adjust any time stamps
|
||||
* they are maintaining internally by the delta so that time maintains
|
||||
* the illusion of flowing smoothly forward.
|
||||
*/
|
||||
public void fastForward (long timeDelta)
|
||||
{
|
||||
super(bounds);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,14 +43,6 @@ public abstract class Animation
|
||||
_finished = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates the bounds of this animation.
|
||||
*/
|
||||
public void invalidate ()
|
||||
{
|
||||
_animmgr.getRegionManager().invalidateRegion(_bounds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the animation is finished and the animation manager has
|
||||
* removed it from service.
|
||||
@@ -142,76 +57,20 @@ public abstract class Animation
|
||||
*/
|
||||
public void addAnimationObserver (AnimationObserver obs)
|
||||
{
|
||||
// create the observer list if it doesn't yet exist
|
||||
if (_observers == null) {
|
||||
_observers = new ArrayList();
|
||||
}
|
||||
|
||||
// make sure each observer observes only once
|
||||
if (_observers.contains(obs)) {
|
||||
Log.info("Attempt to observe animation already observing " +
|
||||
"[anim=" + this + ", obs=" + obs + "].");
|
||||
return;
|
||||
}
|
||||
|
||||
// add the observer
|
||||
_observers.add(obs);
|
||||
addObserver(obs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies any animation observers that the given animation event has
|
||||
* occurred.
|
||||
*/
|
||||
public void notifyObservers (AnimationEvent e)
|
||||
public void notifyObservers (AnimationEvent event)
|
||||
{
|
||||
int size = (_observers == null) ? 0 : _observers.size();
|
||||
for (int ii = 0; ii < size; ii++) {
|
||||
((AnimationObserver)_observers.get(ii)).handleEvent(e);
|
||||
if (_observers != null) {
|
||||
_mgr.queueNotification(_observers, event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string representation of the animation.
|
||||
*/
|
||||
public String toString ()
|
||||
{
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("[");
|
||||
toString(buf);
|
||||
return buf.append("]").toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called automatically when an animation is added to an animation
|
||||
* manager for management.
|
||||
*/
|
||||
protected void setAnimationManager (AnimationManager animmgr)
|
||||
{
|
||||
_animmgr = animmgr;
|
||||
}
|
||||
|
||||
/**
|
||||
* This should be overridden by derived classes (which should be sure
|
||||
* to call <code>super.toString()</code>) to append the derived class
|
||||
* specific animation information to the string buffer.
|
||||
*/
|
||||
protected void toString (StringBuffer buf)
|
||||
{
|
||||
buf.append("bounds=").append(StringUtil.toString(_bounds));
|
||||
}
|
||||
|
||||
/** Our animation manager. */
|
||||
protected AnimationManager _animmgr;
|
||||
|
||||
/** Whether the animation is finished. */
|
||||
protected boolean _finished = false;
|
||||
|
||||
/** The animation bounds. */
|
||||
protected Rectangle _bounds;
|
||||
|
||||
/** The render order of this animation. */
|
||||
protected int _renderOrder;
|
||||
|
||||
/** The list of animation observers. */
|
||||
protected ArrayList _observers;
|
||||
}
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
//
|
||||
// $Id: AnimationManager.java,v 1.13 2002/09/20 21:28:20 mdb Exp $
|
||||
// $Id: AnimationManager.java,v 1.14 2002/10/08 21:03:37 ray Exp $
|
||||
|
||||
package com.threerings.media.animation;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Shape;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.samskivert.util.SortableArrayList;
|
||||
|
||||
import com.threerings.media.AbstractMediaManager;
|
||||
import com.threerings.media.Log;
|
||||
import com.threerings.media.MediaConstants;
|
||||
import com.threerings.media.RegionManager;
|
||||
|
||||
/**
|
||||
@@ -19,8 +16,7 @@ import com.threerings.media.RegionManager;
|
||||
* manager itself is ticked and generating events when animations finish
|
||||
* and suchlike.
|
||||
*/
|
||||
public class AnimationManager
|
||||
implements MediaConstants
|
||||
public class AnimationManager extends AbstractMediaManager
|
||||
{
|
||||
/**
|
||||
* Construct and initialize the animation manager which readies itself
|
||||
@@ -28,7 +24,7 @@ public class AnimationManager
|
||||
*/
|
||||
public AnimationManager (RegionManager remgr)
|
||||
{
|
||||
_remgr = remgr;
|
||||
super(remgr);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,14 +33,7 @@ public class AnimationManager
|
||||
*/
|
||||
public void registerAnimation (Animation anim)
|
||||
{
|
||||
if (_anims.contains(anim)) {
|
||||
Log.warning("Attempt to register animation more than once " +
|
||||
"[anim=" + anim + "].");
|
||||
return;
|
||||
}
|
||||
|
||||
anim.setAnimationManager(this);
|
||||
_anims.insertSorted(anim, RENDER_ORDER);
|
||||
insertMedia(anim);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,43 +44,17 @@ public class AnimationManager
|
||||
*/
|
||||
public void unregisterAnimation (Animation anim)
|
||||
{
|
||||
// un-register the animation
|
||||
if (!_anims.remove(anim)) {
|
||||
Log.warning("Attempt to un-register animation that isn't " +
|
||||
"registered [anim=" + anim + "].");
|
||||
return;
|
||||
}
|
||||
|
||||
// invalidate its bounds
|
||||
_remgr.invalidateRegion(anim.getBounds());
|
||||
removeMedia(anim);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides access to the region manager that the animation manager is
|
||||
* using to collect invalid regions every frame. This should generally
|
||||
* only be used by animations that want to invalidate themselves.
|
||||
*/
|
||||
public RegionManager getRegionManager ()
|
||||
// documentation inherited
|
||||
protected void tickAllMedia (long tickStamp)
|
||||
{
|
||||
return _remgr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles updating animations and generating associated events.
|
||||
*
|
||||
* @param tickStamp the system clock at the time of the tick.
|
||||
*/
|
||||
public void tick (long tickStamp)
|
||||
{
|
||||
// tick all of our animations
|
||||
int size = _anims.size();
|
||||
for (int ii = 0; ii < size; ii++) {
|
||||
((Animation)_anims.get(ii)).tick(tickStamp);
|
||||
}
|
||||
super.tickAllMedia(tickStamp);
|
||||
|
||||
// remove any finished animations
|
||||
for (int ii = size - 1; ii >= 0; ii--) {
|
||||
Animation anim = (Animation)_anims.get(ii);
|
||||
for (int ii=_media.size() - 1; ii >= 0; ii--) {
|
||||
Animation anim = (Animation)_media.get(ii);
|
||||
if (anim.isFinished()) {
|
||||
// let any animation observers know that we're done
|
||||
anim.notifyObservers(new AnimationCompletedEvent(anim));
|
||||
@@ -104,68 +67,12 @@ public class AnimationManager
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the animation manager is paused for some length of time, it
|
||||
* should be fast forwarded by the appropriate number of milliseconds.
|
||||
* This allows animations to smoothly pick up where they left off
|
||||
* rather than abruptly jumping into the future, thinking that some
|
||||
* outrageous amount of time passed since their last tick.
|
||||
*/
|
||||
public void fastForward (long timeDelta)
|
||||
// documentation inherited
|
||||
protected void dispatchEvent (ArrayList observers, Object event)
|
||||
{
|
||||
// fast forward all of our animations
|
||||
int size = _anims.size();
|
||||
for (int ii = 0; ii < size; ii++) {
|
||||
((Animation)_anims.get(ii)).fastForward(timeDelta);
|
||||
AnimationEvent aevt = (AnimationEvent) event;
|
||||
for (int ii=0, nn=observers.size(); ii < nn; ii++) {
|
||||
((AnimationObserver) observers.get(ii)).handleEvent(aevt);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders all registered animations in the given layer that intersect
|
||||
* the supplied clipping rectangle to the given graphics context.
|
||||
*
|
||||
* @param layer the layer to render; one of {@link #FRONT}, {@link
|
||||
* #BACK}, or {@link #ALL}. The front layer contains all animations
|
||||
* with a positive render order; the back layer contains all
|
||||
* animations with a negative render order; all, both.
|
||||
*/
|
||||
public void renderAnimations (Graphics2D gfx, int layer, Shape clip)
|
||||
{
|
||||
// now paint them
|
||||
int size = _anims.size();
|
||||
for (int ii = 0; ii < size; ii++) {
|
||||
Animation anim = (Animation)_anims.get(ii);
|
||||
int order = anim.getRenderOrder();
|
||||
try {
|
||||
if (((layer == ALL) ||
|
||||
(layer == FRONT && order >= 0) ||
|
||||
(layer == BACK && order < 0)) &&
|
||||
clip.intersects(anim.getBounds())) {
|
||||
anim.paint(gfx);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.warning("Failed to render animation " +
|
||||
"[anim=" + anim + ", e=" + e + "].");
|
||||
Log.logStackTrace(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Used to accumulate dirty regions. */
|
||||
protected RegionManager _remgr;
|
||||
|
||||
/** The list of animations. */
|
||||
protected SortableArrayList _anims = new SortableArrayList();
|
||||
|
||||
/** Used to sort animations prior to painting. */
|
||||
protected static final Comparator RENDER_ORDER = new Comparator() {
|
||||
public int compare (Object o1, Object o2) {
|
||||
return (((Animation)o1)._renderOrder -
|
||||
((Animation)o2)._renderOrder);
|
||||
}
|
||||
public boolean equals (Object obj) {
|
||||
return this == obj;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user