Handle all sprite events at the end of each SpriteManager.tick() so
that observers can do things like remove sprites without unhappy side-effects. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@335 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: Sprite.java,v 1.18 2001/09/05 21:51:43 shaper Exp $
|
// $Id: Sprite.java,v 1.19 2001/09/07 23:01:53 shaper Exp $
|
||||||
|
|
||||||
package com.threerings.media.sprite;
|
package com.threerings.media.sprite;
|
||||||
|
|
||||||
@@ -335,7 +335,7 @@ public class Sprite
|
|||||||
{
|
{
|
||||||
if (!_path.hasNext()) {
|
if (!_path.hasNext()) {
|
||||||
// inform observers that we've finished our path
|
// inform observers that we've finished our path
|
||||||
notifyObservers(SpriteObserver.FINISHED_PATH, _path);
|
notifyObservers(SpriteEvent.FINISHED_PATH, _path);
|
||||||
// clear out our path and bail
|
// clear out our path and bail
|
||||||
stop();
|
stop();
|
||||||
return;
|
return;
|
||||||
@@ -343,7 +343,7 @@ public class Sprite
|
|||||||
|
|
||||||
if (_dest != null) {
|
if (_dest != null) {
|
||||||
// inform observers that we've finished a path node
|
// inform observers that we've finished a path node
|
||||||
notifyObservers(SpriteObserver.FINISHED_PATH_NODE, _dest);
|
notifyObservers(SpriteEvent.FINISHED_PATH_NODE, _dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
// grab the next node in our path
|
// grab the next node in our path
|
||||||
@@ -492,11 +492,8 @@ public class Sprite
|
|||||||
{
|
{
|
||||||
if (_observers == null) return;
|
if (_observers == null) return;
|
||||||
|
|
||||||
int size = _observers.size();
|
SpriteEvent evt = new SpriteEvent(this, eventCode, arg);
|
||||||
for (int ii = 0; ii < size; ii++) {
|
_spritemgr.notifySpriteObservers(_observers, evt);
|
||||||
SpriteObserver obs = (SpriteObserver)_observers.get(ii);
|
|
||||||
obs.spriteChanged(this, eventCode, arg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
//
|
||||||
|
// $Id: SpriteEvent.java,v 1.1 2001/09/07 23:01:53 shaper Exp $
|
||||||
|
|
||||||
|
package com.threerings.media.sprite;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A sprite event is sent to all sprite observers for a sprite
|
||||||
|
* whenever one of the various possible sprite events takes place.
|
||||||
|
*/
|
||||||
|
public class SpriteEvent
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create a sprite event.
|
||||||
|
*
|
||||||
|
* @param sprite the involved sprite.
|
||||||
|
* @param eventCode the event code.
|
||||||
|
* @param arg the event argument.
|
||||||
|
*/
|
||||||
|
public SpriteEvent (Sprite sprite, int eventCode, Object arg)
|
||||||
|
{
|
||||||
|
_sprite = sprite;
|
||||||
|
_eventCode = eventCode;
|
||||||
|
_arg = arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the sprite involved in the event.
|
||||||
|
*/
|
||||||
|
public Sprite getSprite ()
|
||||||
|
{
|
||||||
|
return _sprite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the event code for the event.
|
||||||
|
*/
|
||||||
|
public int getEventCode ()
|
||||||
|
{
|
||||||
|
return _eventCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the argument associated with the event.
|
||||||
|
*/
|
||||||
|
public Object getArgument ()
|
||||||
|
{
|
||||||
|
return _arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event code noting that the sprite completed a path node. The
|
||||||
|
* argument to the event is the {@link PathNode} completed.
|
||||||
|
*/
|
||||||
|
public static final int FINISHED_PATH_NODE = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event code noting that the sprite completed its entire path.
|
||||||
|
* The argument to the event is the {@link Path} completed.
|
||||||
|
*/
|
||||||
|
public static final int FINISHED_PATH = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event code noting that the sprite collided with another
|
||||||
|
* sprite. The argument to the event is the {@link Sprite} the
|
||||||
|
* observed sprite collided with.
|
||||||
|
*/
|
||||||
|
public static final int COLLIDED_SPRITE = 2;
|
||||||
|
|
||||||
|
/** The sprite associated with this event. */
|
||||||
|
protected Sprite _sprite;
|
||||||
|
|
||||||
|
/** The event code. */
|
||||||
|
protected int _eventCode;
|
||||||
|
|
||||||
|
/** The argument associated with this event. */
|
||||||
|
protected Object _arg;
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: SpriteManager.java,v 1.11 2001/09/05 00:40:33 shaper Exp $
|
// $Id: SpriteManager.java,v 1.12 2001/09/07 23:01:53 shaper Exp $
|
||||||
|
|
||||||
package com.threerings.media.sprite;
|
package com.threerings.media.sprite;
|
||||||
|
|
||||||
@@ -20,6 +20,7 @@ public class SpriteManager
|
|||||||
public SpriteManager ()
|
public SpriteManager ()
|
||||||
{
|
{
|
||||||
_sprites = new ArrayList();
|
_sprites = new ArrayList();
|
||||||
|
_notify = new ArrayList();
|
||||||
_dirty = new DirtyRectList();
|
_dirty = new DirtyRectList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,6 +164,14 @@ public class SpriteManager
|
|||||||
|
|
||||||
// notify sprite observers of any collisions
|
// notify sprite observers of any collisions
|
||||||
handleCollisions();
|
handleCollisions();
|
||||||
|
|
||||||
|
// notify sprite observers of any sprite events. note that we
|
||||||
|
// explicitly queue up events while ticking and checking for
|
||||||
|
// collisions, and we only notify observers once we're
|
||||||
|
// finished with all of those antics so that any actions the
|
||||||
|
// observers may take, such as sprite removal, won't screw us
|
||||||
|
// up elsewhere.
|
||||||
|
handleSpriteEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -175,9 +184,9 @@ public class SpriteManager
|
|||||||
int size = _sprites.size();
|
int size = _sprites.size();
|
||||||
for (int ii = 0; ii < size; ii++) {
|
for (int ii = 0; ii < size; ii++) {
|
||||||
Sprite sprite = (Sprite)_sprites.get(ii);
|
Sprite sprite = (Sprite)_sprites.get(ii);
|
||||||
sprite.tick();
|
sprite.tick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sort the sprite list in order of ascending x-coordinate.
|
* Sort the sprite list in order of ascending x-coordinate.
|
||||||
@@ -201,40 +210,23 @@ public class SpriteManager
|
|||||||
{
|
{
|
||||||
// gather a list of all sprite collisions
|
// gather a list of all sprite collisions
|
||||||
int size = _sprites.size();
|
int size = _sprites.size();
|
||||||
ArrayList collisions = new ArrayList();
|
|
||||||
for (int ii = 0; ii < size; ii++) {
|
for (int ii = 0; ii < size; ii++) {
|
||||||
Sprite sprite = (Sprite)_sprites.get(ii);
|
Sprite sprite = (Sprite)_sprites.get(ii);
|
||||||
checkCollisions(ii, size, sprite, collisions);
|
checkCollisions(ii, size, sprite);
|
||||||
}
|
|
||||||
|
|
||||||
// observers are notified of sprite collisions after all
|
|
||||||
// collision-detection is performed so that modifications to
|
|
||||||
// the sprite, e.g. location or velocity, won't impact the
|
|
||||||
// validity of our checking.
|
|
||||||
int csize = collisions.size();
|
|
||||||
for (int ii = 0; ii < csize; ii++) {
|
|
||||||
Tuple tup = (Tuple)collisions.get(ii);
|
|
||||||
Sprite a = (Sprite)tup.left, b = (Sprite)tup.right;
|
|
||||||
|
|
||||||
// inform sprite observers for both sprites of the collision
|
|
||||||
a.notifyObservers(SpriteObserver.COLLIDED_SPRITE, b);
|
|
||||||
b.notifyObservers(SpriteObserver.COLLIDED_SPRITE, a);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check a sprite for collision with any other sprites in the
|
* Check a sprite for collision with any other sprites in the
|
||||||
* sprite list. The sprites involved in a collision are added to
|
* sprite list and notify the sprite observers associated with any
|
||||||
* the <code>collisions</code> list of {@link Tuple} objects.
|
* sprites that do indeed collide.
|
||||||
*
|
*
|
||||||
* @param idx the starting sprite index.
|
* @param idx the starting sprite index.
|
||||||
* @param size the total number of sprites.
|
* @param size the total number of sprites.
|
||||||
* @param sprite the sprite to check against other sprites for
|
* @param sprite the sprite to check against other sprites for
|
||||||
* collisions.
|
* collisions.
|
||||||
* @param collisions the list of collisions gathered so far.
|
|
||||||
*/
|
*/
|
||||||
protected void checkCollisions (int idx, int size, Sprite sprite,
|
protected void checkCollisions (int idx, int size, Sprite sprite)
|
||||||
ArrayList collisions)
|
|
||||||
{
|
{
|
||||||
// TODO: make this handle quickly moving objects that may pass
|
// TODO: make this handle quickly moving objects that may pass
|
||||||
// through each other.
|
// through each other.
|
||||||
@@ -254,9 +246,6 @@ public class SpriteManager
|
|||||||
Sprite other = (Sprite)_sprites.get(ii);
|
Sprite other = (Sprite)_sprites.get(ii);
|
||||||
Rectangle obounds = other.getBounds();
|
Rectangle obounds = other.getBounds();
|
||||||
|
|
||||||
// Log.info("Checking collision [bounds=" + bounds +
|
|
||||||
// ", obounds=" + obounds + "].");
|
|
||||||
|
|
||||||
if (obounds.x > edgeX) {
|
if (obounds.x > edgeX) {
|
||||||
// since sprites are stored in the list sorted by
|
// since sprites are stored in the list sorted by
|
||||||
// ascending x-position, we know this sprite and any
|
// ascending x-position, we know this sprite and any
|
||||||
@@ -267,11 +256,47 @@ public class SpriteManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (obounds.intersects(bounds)) {
|
if (obounds.intersects(bounds)) {
|
||||||
collisions.add(new Tuple(sprite, other));
|
sprite.notifyObservers(SpriteEvent.COLLIDED_SPRITE, other);
|
||||||
|
other.notifyObservers(SpriteEvent.COLLIDED_SPRITE, sprite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify all sprite observers of any sprite events that took
|
||||||
|
* place during our most recent <code>tick()</code>.
|
||||||
|
*/
|
||||||
|
protected void handleSpriteEvents ()
|
||||||
|
{
|
||||||
|
int size = _notify.size();
|
||||||
|
for (int ii = 0; ii < size; ii++) {
|
||||||
|
Tuple tup = (Tuple)_notify.remove(0);
|
||||||
|
ArrayList observers = (ArrayList)tup.left;
|
||||||
|
SpriteEvent evt = (SpriteEvent)tup.right;
|
||||||
|
|
||||||
|
int osize = observers.size();
|
||||||
|
for (int jj = 0; jj < osize; jj++) {
|
||||||
|
SpriteObserver obs = (SpriteObserver)observers.get(jj);
|
||||||
|
obs.spriteChanged(evt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by {@link Sprite#notifyObservers} to note that the
|
||||||
|
* sprite's observers should be informed of a sprite event once
|
||||||
|
* the current <code>tick()</code> is complete.
|
||||||
|
*
|
||||||
|
* @param observers the list of sprite observers.
|
||||||
|
* @param event the sprite event to notify the observers of.
|
||||||
|
*/
|
||||||
|
protected void notifySpriteObservers (ArrayList observers,
|
||||||
|
SpriteEvent event)
|
||||||
|
{
|
||||||
|
// throw it on the list of events for later
|
||||||
|
_notify.add(new Tuple(observers, event));
|
||||||
|
}
|
||||||
|
|
||||||
/** The comparator used to sort sprites by horizontal position. */
|
/** The comparator used to sort sprites by horizontal position. */
|
||||||
protected static final Comparator SPRITE_COMP = new SpriteComparator();
|
protected static final Comparator SPRITE_COMP = new SpriteComparator();
|
||||||
|
|
||||||
@@ -281,6 +306,9 @@ public class SpriteManager
|
|||||||
/** The dirty rectangles created by sprites. */
|
/** The dirty rectangles created by sprites. */
|
||||||
protected DirtyRectList _dirty;
|
protected DirtyRectList _dirty;
|
||||||
|
|
||||||
|
/** The list of pending sprite notifications. */
|
||||||
|
protected ArrayList _notify;
|
||||||
|
|
||||||
protected static class SpriteComparator implements Comparator
|
protected static class SpriteComparator implements Comparator
|
||||||
{
|
{
|
||||||
public int compare (Object o1, Object o2)
|
public int compare (Object o1, Object o2)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: SpriteObserver.java,v 1.1 2001/09/05 00:40:33 shaper Exp $
|
// $Id: SpriteObserver.java,v 1.2 2001/09/07 23:01:53 shaper Exp $
|
||||||
|
|
||||||
package com.threerings.media.sprite;
|
package com.threerings.media.sprite;
|
||||||
|
|
||||||
@@ -16,27 +16,7 @@ public interface SpriteObserver
|
|||||||
* sprite.
|
* sprite.
|
||||||
*
|
*
|
||||||
* @param sprite the involved sprite.
|
* @param sprite the involved sprite.
|
||||||
* @param eventCode the type of sprite event.
|
* @param event the sprite event.
|
||||||
* @param arg the argument associated with the event.
|
|
||||||
*/
|
*/
|
||||||
public void spriteChanged (Sprite sprite, int eventCode, Object arg);
|
public void spriteChanged (SpriteEvent event);
|
||||||
|
|
||||||
/**
|
|
||||||
* Event code noting that the sprite completed a path node. The
|
|
||||||
* argument to the event is the {@link PathNode} completed.
|
|
||||||
*/
|
|
||||||
public static final int FINISHED_PATH_NODE = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Event code noting that the sprite completed its entire path.
|
|
||||||
* The argument to the event is the {@link Path} completed.
|
|
||||||
*/
|
|
||||||
public static final int FINISHED_PATH = 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Event code noting that the sprite collided with another
|
|
||||||
* sprite. The argument to the event is the {@link Sprite} the
|
|
||||||
* observed sprite collided with.
|
|
||||||
*/
|
|
||||||
public static final int COLLIDED_SPRITE = 2;
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user