More work on character components.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@579 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
//
|
||||
// $Id: CharacterComponent.java,v 1.1 2001/10/26 01:17:21 shaper Exp $
|
||||
// $Id: CharacterComponent.java,v 1.2 2001/10/30 16:16:01 shaper Exp $
|
||||
|
||||
package com.threerings.cast;
|
||||
|
||||
import com.threerings.media.sprite.MultiFrameImage;
|
||||
import com.threerings.media.sprite.Sprite;
|
||||
|
||||
/**
|
||||
* The character component represents a single component that can be
|
||||
@@ -17,14 +18,16 @@ public class CharacterComponent
|
||||
/**
|
||||
* Constructs a character component.
|
||||
*/
|
||||
public CharacterComponent (ComponentType type, int cid,
|
||||
ComponentFrames frames)
|
||||
public CharacterComponent (
|
||||
ComponentType type, ComponentClass cclass, int cid,
|
||||
ComponentFrames frames)
|
||||
{
|
||||
_type = type;
|
||||
_cclass = cclass;
|
||||
_cid = cid;
|
||||
_frames = frames;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the unique component identifier.
|
||||
*/
|
||||
@@ -42,20 +45,28 @@ public class CharacterComponent
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link ComponentType} object describing the base
|
||||
* component type information associated with this component.
|
||||
* Returns the component type associated with this component.
|
||||
*/
|
||||
public ComponentType getType ()
|
||||
{
|
||||
return _type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the component class associated with this component.
|
||||
*/
|
||||
public ComponentClass getComponentClass ()
|
||||
{
|
||||
return _cclass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this character component.
|
||||
*/
|
||||
public String toString ()
|
||||
{
|
||||
return "[cid=" + _cid + ", type=" + _type + "]";
|
||||
return "[cid=" + _cid + ", clid=" + _cclass.clid +
|
||||
", type=" + _type + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,6 +81,15 @@ public class CharacterComponent
|
||||
|
||||
/** The walking animations in each orientation. */
|
||||
public MultiFrameImage walk[];
|
||||
|
||||
/**
|
||||
* Constructs a component frames object.
|
||||
*/
|
||||
public ComponentFrames ()
|
||||
{
|
||||
stand = new MultiFrameImage[Sprite.NUM_DIRECTIONS];
|
||||
walk = new MultiFrameImage[Sprite.NUM_DIRECTIONS];
|
||||
}
|
||||
}
|
||||
|
||||
/** The unique character component identifier. */
|
||||
@@ -78,6 +98,9 @@ public class CharacterComponent
|
||||
/** The animation frames. */
|
||||
protected ComponentFrames _frames;
|
||||
|
||||
/** The component class. */
|
||||
protected ComponentClass _cclass;
|
||||
|
||||
/** The character component type. */
|
||||
protected ComponentType _type;
|
||||
}
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
//
|
||||
// $Id: CharacterDescriptor.java,v 1.1 2001/10/26 01:17:21 shaper Exp $
|
||||
// $Id: CharacterDescriptor.java,v 1.2 2001/10/30 16:16:01 shaper Exp $
|
||||
|
||||
package com.threerings.cast;
|
||||
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
/**
|
||||
* The character descriptor object contains all necessary information
|
||||
* on the character components that are composited together to create
|
||||
* a character image.
|
||||
* The character descriptor object details the components that are
|
||||
* pieced together to create a single character image.
|
||||
*/
|
||||
public class CharacterDescriptor
|
||||
{
|
||||
/**
|
||||
* Constructs the character descriptor.
|
||||
*/
|
||||
public CharacterDescriptor (int components[])
|
||||
public CharacterDescriptor (ComponentType type, int components[])
|
||||
{
|
||||
_type = type;
|
||||
_components = components;
|
||||
}
|
||||
|
||||
@@ -29,16 +29,28 @@ public class CharacterDescriptor
|
||||
return _components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link ComponentType} of the character's components.
|
||||
*/
|
||||
public ComponentType getType ()
|
||||
{
|
||||
return _type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this character descriptor.
|
||||
*/
|
||||
public String toString ()
|
||||
{
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("[").append(StringUtil.toString(_components));
|
||||
buf.append("[type=").append(_type);
|
||||
buf.append(StringUtil.toString(_components));
|
||||
return buf.append("]").toString();
|
||||
}
|
||||
|
||||
/** The array of component identifiers. */
|
||||
protected int _components[];
|
||||
|
||||
/** The component type of the character's components. */
|
||||
protected ComponentType _type;
|
||||
}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
//
|
||||
// $Id: CharacterManager.java,v 1.5 2001/10/26 01:17:21 shaper Exp $
|
||||
// $Id: CharacterManager.java,v 1.6 2001/10/30 16:16:01 shaper Exp $
|
||||
|
||||
package com.threerings.cast;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
import com.threerings.media.tile.TileManager;
|
||||
import com.samskivert.util.CollectionUtil;
|
||||
|
||||
import com.threerings.cast.Log;
|
||||
import com.threerings.cast.TileUtil;
|
||||
import com.threerings.cast.CharacterComponent.ComponentFrames;
|
||||
|
||||
/**
|
||||
* The character manager provides facilities for constructing sprites
|
||||
@@ -20,11 +19,13 @@ public class CharacterManager
|
||||
/**
|
||||
* Constructs the character manager.
|
||||
*/
|
||||
public CharacterManager (TileManager tilemgr, ComponentRepository repo)
|
||||
public CharacterManager (ComponentRepository repo)
|
||||
{
|
||||
// save off our objects
|
||||
_tilemgr = tilemgr;
|
||||
// keep this around
|
||||
_repo = repo;
|
||||
|
||||
// determine component class render order
|
||||
_renderRank = getRenderRank();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -36,51 +37,81 @@ public class CharacterManager
|
||||
*/
|
||||
public CharacterSprite getCharacter (CharacterDescriptor desc)
|
||||
{
|
||||
// get the list of component ids
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
// get the array of component ids of each class
|
||||
int components[] = desc.getComponents();
|
||||
|
||||
// TODO: here is where we'd iterate through all components
|
||||
// building up the full composite image of the sprite in each
|
||||
// orientation, standing and walking. we punt for now, but
|
||||
// we'll revisit this soon enough.
|
||||
if (components.length == 0 || components.length > 1) {
|
||||
if (components.length == 0) {
|
||||
Log.warning("Invalid number of components " +
|
||||
" [size=" + components.length + "].");
|
||||
"[size=" + components.length + "].");
|
||||
return null;
|
||||
}
|
||||
|
||||
CharacterComponent comp;
|
||||
try {
|
||||
// as noted above, no compositing for now. note that when
|
||||
// we do composite, we probably will want to make sure all
|
||||
// components share a compatible component type.
|
||||
comp = _repo.getComponent(components[0]);
|
||||
} catch (Exception e) {
|
||||
Log.warning("Exception retrieving character component " +
|
||||
"[e=" + e + "].");
|
||||
// create the composite character image
|
||||
ComponentFrames frames = createCompositeFrames(desc);
|
||||
if (frames == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// instantiate the character sprite
|
||||
CharacterSprite sprite;
|
||||
try {
|
||||
sprite = (CharacterSprite)_charClass.newInstance();
|
||||
} catch (Exception e) {
|
||||
Log.warning("Failed to instantiate character sprite " +
|
||||
"[e=" + e + "].");
|
||||
Log.logStackTrace(e);
|
||||
CharacterSprite sprite = createSprite();
|
||||
if (sprite == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// populate the character sprite with its attributes
|
||||
ComponentType ctype = comp.getType();
|
||||
sprite.setFrames(comp.getFrames());
|
||||
ComponentType ctype = desc.getType();
|
||||
sprite.setFrames(frames);
|
||||
sprite.setFrameRate(ctype.fps);
|
||||
sprite.setOrigin(ctype.origin.x, ctype.origin.y);
|
||||
|
||||
long end = System.currentTimeMillis();
|
||||
Log.info("Generated character sprite [ms=" + (end - start) + "].");
|
||||
|
||||
return sprite;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator over the {@link ComponentType} objects
|
||||
* representing all available character component type
|
||||
* identifiers.
|
||||
*/
|
||||
public Iterator enumerateComponentTypes ()
|
||||
{
|
||||
return _repo.enumerateComponentTypes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator over the <code>Integer</code> objects
|
||||
* representing all available character component identifiers for
|
||||
* the given character component type identifier.
|
||||
*/
|
||||
public Iterator enumerateComponentsByType (int ctid)
|
||||
{
|
||||
return _repo.enumerateComponentsByType(ctid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator over the {@link ComponentClass} objects
|
||||
* representing all available character component class
|
||||
* identifiers.
|
||||
*/
|
||||
public Iterator enumerateComponentClasses ()
|
||||
{
|
||||
return _repo.enumerateComponentClasses();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator over the <code>Integer</code> objects
|
||||
* representing all available character component identifiers for
|
||||
* the given character component type and class identifiers.
|
||||
*/
|
||||
public Iterator enumerateComponentsByClass (int ctid, int clid)
|
||||
{
|
||||
return _repo.enumerateComponentsByClass(ctid, clid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instructs the character manager to construct instances of this
|
||||
* derived class of <code>CharacterSprite</code>.
|
||||
@@ -99,8 +130,77 @@ public class CharacterManager
|
||||
_charClass = charClass;
|
||||
}
|
||||
|
||||
/** The tile manager. */
|
||||
protected TileManager _tilemgr;
|
||||
/**
|
||||
* Returns a {@link CharacterComponent.ComponentFrames} object
|
||||
* containing the fully composited images detailed in the given
|
||||
* character descriptor.
|
||||
*/
|
||||
protected ComponentFrames createCompositeFrames (CharacterDescriptor desc)
|
||||
{
|
||||
int components[] = desc.getComponents();
|
||||
ComponentFrames frames = null;
|
||||
|
||||
for (int ii = 0; ii < _renderRank.length; ii++) {
|
||||
try {
|
||||
int clidx = _renderRank[ii].clid;
|
||||
|
||||
// get the component to render
|
||||
CharacterComponent c = _repo.getComponent(components[clidx]);
|
||||
|
||||
// TODO: fix this to deal with frames of varying dimensions
|
||||
if (frames == null) {
|
||||
int fcount = desc.getType().frameCount;
|
||||
frames = TileUtil.createBlankFrames(c.getFrames(), fcount);
|
||||
}
|
||||
|
||||
// render the frames onto the composite frames
|
||||
TileUtil.compositeFrames(frames, c.getFrames());
|
||||
|
||||
} catch (NoSuchComponentException nsce) {
|
||||
Log.warning("Exception compositing character components " +
|
||||
"[nsce=" + nsce + "].");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link CharacterSprite} of the character class
|
||||
* specified for use by this character manager.
|
||||
*/
|
||||
protected CharacterSprite createSprite ()
|
||||
{
|
||||
try {
|
||||
return (CharacterSprite)_charClass.newInstance();
|
||||
} catch (Exception e) {
|
||||
Log.warning("Failed to instantiate character sprite " +
|
||||
"[e=" + e + "].");
|
||||
Log.logStackTrace(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of {@link ComponentClass} objects sorted into
|
||||
* the appropriate rendering order as specified by each component
|
||||
* class object.
|
||||
*/
|
||||
protected ComponentClass[] getRenderRank ()
|
||||
{
|
||||
ArrayList classes = new ArrayList();
|
||||
CollectionUtil.addAll(classes, _repo.enumerateComponentClasses());
|
||||
|
||||
ComponentClass rank[] = new ComponentClass[classes.size()];
|
||||
classes.toArray(rank);
|
||||
Arrays.sort(rank, ComponentClass.RENDER_COMP);
|
||||
|
||||
return rank;
|
||||
}
|
||||
|
||||
/** The order in which to render component classes. */
|
||||
protected ComponentClass _renderRank[];
|
||||
|
||||
/** The component repository. */
|
||||
protected ComponentRepository _repo;
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
//
|
||||
// $Id: ComponentClass.java,v 1.1 2001/10/30 16:16:01 shaper Exp $
|
||||
|
||||
package com.threerings.cast;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* The component class object denotes the particular class of
|
||||
* components that a {@link CharacterComponent} object belongs to.
|
||||
* Examples of feasible component classes might include "Hat", "Head",
|
||||
* or "Feet".
|
||||
*/
|
||||
public class ComponentClass
|
||||
{
|
||||
/** The comparator used to sort component class objects in render
|
||||
* priority order. */
|
||||
public static final Comparator RENDER_COMP = new RenderComparator();
|
||||
|
||||
/** The unique component class identifier. */
|
||||
public int clid;
|
||||
|
||||
/** The component class name. */
|
||||
public String name;
|
||||
|
||||
/** The render priority. */
|
||||
public int render;
|
||||
|
||||
/**
|
||||
* Returns a string representation of this component class.
|
||||
*/
|
||||
public String toString ()
|
||||
{
|
||||
return "[clid=" + clid + ", name=" + name + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* The comparator used to sort component class objects in render
|
||||
* priority order so that compositing components into a single
|
||||
* character image can be done in the proper order.
|
||||
*/
|
||||
protected static class RenderComparator implements Comparator
|
||||
{
|
||||
// documentation inherited
|
||||
public int compare (Object a, Object b)
|
||||
{
|
||||
if (!(a instanceof ComponentClass) ||
|
||||
!(b instanceof ComponentClass)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ComponentClass ca = (ComponentClass)a;
|
||||
ComponentClass cb = (ComponentClass)b;
|
||||
|
||||
if (ca.render < cb.render) {
|
||||
return -1;
|
||||
} else if (ca.render == cb.render) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public boolean equals (Object obj)
|
||||
{
|
||||
return (obj == this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: ComponentRepository.java,v 1.1 2001/10/26 01:17:21 shaper Exp $
|
||||
// $Id: ComponentRepository.java,v 1.2 2001/10/30 16:16:01 shaper Exp $
|
||||
|
||||
package com.threerings.cast;
|
||||
|
||||
@@ -17,20 +17,31 @@ public interface ComponentRepository
|
||||
* unique component identifier.
|
||||
*/
|
||||
public CharacterComponent getComponent (int cid)
|
||||
throws NoSuchComponentException, NoSuchComponentTypeException;
|
||||
throws NoSuchComponentException;
|
||||
|
||||
/**
|
||||
* Returns an iterator over the {@link ComponentType} objects
|
||||
* representing all available character component types.
|
||||
*/
|
||||
public Iterator enumerateComponentTypes ();
|
||||
|
||||
/**
|
||||
* Returns an iterator over the <code>Integer</code> objects
|
||||
* representing all available character component identifiers for
|
||||
* the given character component type identifier.
|
||||
*/
|
||||
public Iterator enumerateComponents (int ctid)
|
||||
throws NoSuchComponentTypeException;
|
||||
public Iterator enumerateComponentsByType (int ctid);
|
||||
|
||||
/**
|
||||
* Returns an iterator over the {@link ComponentClass} objects
|
||||
* representing all available character component classes.
|
||||
*/
|
||||
public Iterator enumerateComponentClasses ();
|
||||
|
||||
/**
|
||||
* Returns an iterator over the <code>Integer</code> objects
|
||||
* representing all available character component type
|
||||
* identifiers.
|
||||
* representing all available character component identifiers for
|
||||
* the given character component type and class identifiers.
|
||||
*/
|
||||
public Iterator enumerateComponentTypes ();
|
||||
public Iterator enumerateComponentsByClass (int ctid, int clid);
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
//
|
||||
// $Id: NoSuchComponentTypeException.java,v 1.1 2001/10/26 01:17:21 shaper Exp $
|
||||
|
||||
package com.threerings.cast;
|
||||
|
||||
/**
|
||||
* Thrown when an attempt is made to reference a non-existent
|
||||
* component type in the component repository.
|
||||
*/
|
||||
public class NoSuchComponentTypeException extends Exception
|
||||
{
|
||||
public NoSuchComponentTypeException (int ctid)
|
||||
{
|
||||
super("No such component type [ctid=" + ctid + "]");
|
||||
_ctid = ctid;
|
||||
}
|
||||
|
||||
public int getTypeId ()
|
||||
{
|
||||
return _ctid;
|
||||
}
|
||||
|
||||
protected int _ctid;
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
//
|
||||
// $Id: TileUtil.java,v 1.2 2001/10/26 01:40:22 mdb Exp $
|
||||
// $Id: TileUtil.java,v 1.3 2001/10/30 16:16:01 shaper Exp $
|
||||
|
||||
package com.threerings.cast;
|
||||
|
||||
import java.awt.Image;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import com.threerings.media.sprite.*;
|
||||
import com.threerings.media.tile.*;
|
||||
@@ -16,6 +17,46 @@ import com.threerings.cast.CharacterComponent.ComponentFrames;
|
||||
*/
|
||||
public class TileUtil
|
||||
{
|
||||
/**
|
||||
* Renders each of the given <code>src</code> component frames
|
||||
* into the corresponding frames of <code>dest</code>.
|
||||
*/
|
||||
public static void compositeFrames (
|
||||
ComponentFrames dest, ComponentFrames src)
|
||||
{
|
||||
for (int ii = 0; ii < Sprite.NUM_DIRECTIONS; ii++) {
|
||||
// composite the standing frames
|
||||
compositeFrames(dest.stand[ii], src.stand[ii]);
|
||||
|
||||
// composite the walking frames
|
||||
compositeFrames(dest.walk[ii], src.walk[ii]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs and returns a new {@link
|
||||
* CharacterComponent.ComponentFrames} object with empty images
|
||||
* for all of its frames.
|
||||
*/
|
||||
public static ComponentFrames createBlankFrames (
|
||||
ComponentFrames src, int frameCount)
|
||||
{
|
||||
ComponentFrames frames = new ComponentFrames();
|
||||
|
||||
// for now, just use the first frame from the source image to
|
||||
// get the width and height for all of the blank frames
|
||||
Image img = src.walk[0].getFrame(0);
|
||||
int wid = img.getWidth(null), hei = img.getHeight(null);
|
||||
|
||||
// allocate the blank frame images
|
||||
for (int ii = 0; ii < Sprite.NUM_DIRECTIONS; ii++) {
|
||||
frames.stand[ii] = new BlankFrameImage(wid, hei, 1);
|
||||
frames.walk[ii] = new BlankFrameImage(wid, hei, frameCount);
|
||||
}
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link CharacterComponent.ComponentFrames} object
|
||||
* containing the frames of animation used to render the sprite while
|
||||
@@ -33,8 +74,6 @@ public class TileUtil
|
||||
TileManager tilemgr, int tsid, int frameCount)
|
||||
{
|
||||
ComponentFrames frames = new ComponentFrames();
|
||||
frames.walk = new MultiFrameImage[Sprite.NUM_DIRECTIONS];
|
||||
frames.stand = new MultiFrameImage[Sprite.NUM_DIRECTIONS];
|
||||
|
||||
try {
|
||||
for (int ii = 0; ii < Sprite.NUM_DIRECTIONS; ii++) {
|
||||
@@ -63,4 +102,61 @@ public class TileUtil
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders each of the given <code>src</code> frames into the
|
||||
* corresponding frames of <code>dest</code>.
|
||||
*/
|
||||
protected static void compositeFrames (
|
||||
MultiFrameImage dest, MultiFrameImage src)
|
||||
{
|
||||
int dsize = dest.getFrameCount(), ssize = src.getFrameCount();
|
||||
if (dsize != ssize) {
|
||||
Log.warning("Can't composite multi frame images " +
|
||||
"with differing frame counts " +
|
||||
"[dest=" + dsize + ", src=" + ssize + "].");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int ii = 0; ii < dsize; ii++) {
|
||||
Image dimg = dest.getFrame(ii);
|
||||
Image simg = src.getFrame(ii);
|
||||
dimg.getGraphics().drawImage(simg, 0, 0, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An implementation of the {@link MultiFrameImage} interface that
|
||||
* initializes itself to contain a specified number of blank
|
||||
* frames of the requested dimensions.
|
||||
*/
|
||||
protected static class BlankFrameImage implements MultiFrameImage
|
||||
{
|
||||
/**
|
||||
* Constructs a blank frame image.
|
||||
*/
|
||||
public BlankFrameImage (int width, int height, int frameCount)
|
||||
{
|
||||
_imgs = new Image[frameCount];
|
||||
for (int ii = 0; ii < frameCount; ii++) {
|
||||
_imgs[ii] = new BufferedImage(
|
||||
width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int getFrameCount ()
|
||||
{
|
||||
return _imgs.length;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public Image getFrame (int index)
|
||||
{
|
||||
return _imgs[index];
|
||||
}
|
||||
|
||||
/** The frame images. */
|
||||
protected Image _imgs[];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
//
|
||||
// $Id: BuilderPanel.java,v 1.1 2001/10/30 16:16:01 shaper Exp $
|
||||
|
||||
package com.threerings.cast.builder;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import com.samskivert.swing.*;
|
||||
|
||||
import com.threerings.cast.*;
|
||||
|
||||
/**
|
||||
* The builder panel presents the user with an overview of a
|
||||
* composited character and facilities for altering the individual
|
||||
* components that comprise the character's display image.
|
||||
*/
|
||||
public class BuilderPanel extends JPanel implements ActionListener
|
||||
{
|
||||
/**
|
||||
* Constructs the builder panel.
|
||||
*/
|
||||
public BuilderPanel (CharacterManager charmgr)
|
||||
{
|
||||
_charmgr = charmgr;
|
||||
|
||||
setLayout(new VGroupLayout());
|
||||
|
||||
// give ourselves a wee bit of a border
|
||||
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
||||
|
||||
GroupLayout gl = new HGroupLayout(GroupLayout.STRETCH);
|
||||
gl.setOffAxisPolicy(GroupLayout.STRETCH);
|
||||
|
||||
// create the component selection and sprite display panels
|
||||
JPanel sub = new JPanel(gl);
|
||||
ComponentType ctype = getComponentType();
|
||||
sub.add(_comppanel = new ComponentPanel(_charmgr, ctype));
|
||||
sub.add(_spritepanel = new SpritePanel());
|
||||
|
||||
add(sub);
|
||||
|
||||
// create the "OK" button
|
||||
JButton ok = new JButton("OK");
|
||||
ok.addActionListener(this);
|
||||
ok.setActionCommand("ok");
|
||||
add(ok);
|
||||
}
|
||||
|
||||
public void actionPerformed (ActionEvent e)
|
||||
{
|
||||
String cmd = e.getActionCommand();
|
||||
if (cmd.equals("ok")) {
|
||||
CharacterDescriptor desc = _comppanel.getDescriptor();
|
||||
CharacterSprite sprite = _charmgr.getCharacter(desc);
|
||||
_spritepanel.setSprite(sprite);
|
||||
} else {
|
||||
Log.warning("Unknown action command [cmd=" + cmd + "].");
|
||||
}
|
||||
}
|
||||
|
||||
protected ComponentType getComponentType ()
|
||||
{
|
||||
ComponentType ctype = null;
|
||||
Iterator types = _charmgr.enumerateComponentTypes();
|
||||
// for now, fixedly choose the first component type
|
||||
// TODO: fix this hack
|
||||
return (ComponentType)types.next();
|
||||
}
|
||||
|
||||
/** The component panel that displays components available for
|
||||
* selection. */
|
||||
protected ComponentPanel _comppanel;
|
||||
|
||||
/** The sprite panel that displays the composited character sprite. */
|
||||
protected SpritePanel _spritepanel;
|
||||
|
||||
/** The character manager. */
|
||||
protected CharacterManager _charmgr;
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
//
|
||||
// $Id: ComponentEditor.java,v 1.1 2001/10/30 16:16:01 shaper Exp $
|
||||
|
||||
package com.threerings.cast.builder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import com.samskivert.swing.*;
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
import com.threerings.cast.Log;
|
||||
import com.threerings.cast.ComponentClass;
|
||||
|
||||
/**
|
||||
* The component editor displays a label and a slider that allow the
|
||||
* user to select the desired component from a list of components of
|
||||
* the same class.
|
||||
*/
|
||||
public class ComponentEditor extends JPanel implements ChangeListener
|
||||
{
|
||||
/**
|
||||
* Constructs a component editor.
|
||||
*/
|
||||
public ComponentEditor (ComponentClass cclass, List components)
|
||||
{
|
||||
_components = components;
|
||||
|
||||
// Log.info("Creating editor [class=" + cclass +
|
||||
// ", components=" + StringUtil.toString(components) + "].");
|
||||
|
||||
GroupLayout gl = new VGroupLayout(GroupLayout.STRETCH);
|
||||
gl.setOffAxisPolicy(GroupLayout.STRETCH);
|
||||
setLayout(gl);
|
||||
|
||||
gl = new HGroupLayout();
|
||||
gl.setJustification(GroupLayout.LEFT);
|
||||
JPanel sub = new JPanel(gl);
|
||||
|
||||
sub.add(new JLabel(cclass.name + ": "));
|
||||
sub.add(_clabel = new JLabel("0"));
|
||||
|
||||
add(sub);
|
||||
|
||||
int max = components.size() - 1;
|
||||
_slider = new JSlider(JSlider.HORIZONTAL, 0, max, 0);
|
||||
_slider.setSnapToTicks(true);
|
||||
_slider.addChangeListener(this);
|
||||
add(_slider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the selected component id.
|
||||
*/
|
||||
public int getSelectedComponent ()
|
||||
{
|
||||
int idx = _slider.getModel().getValue();
|
||||
return ((Integer)_components.get(idx)).intValue();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void stateChanged (ChangeEvent e)
|
||||
{
|
||||
JSlider source = (JSlider)e.getSource();
|
||||
if (!source.getValueIsAdjusting()) {
|
||||
_clabel.setText(Integer.toString(source.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
/** The components selectable via this editor. */
|
||||
protected List _components;
|
||||
|
||||
/** The slider allowing the user to select a component. */
|
||||
protected JSlider _slider;
|
||||
|
||||
/** The label denoting the currently selected component index. */
|
||||
protected JLabel _clabel;
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
//
|
||||
// $Id: ComponentPanel.java,v 1.1 2001/10/30 16:16:01 shaper Exp $
|
||||
|
||||
package com.threerings.cast.builder;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
|
||||
import com.samskivert.swing.*;
|
||||
import com.samskivert.util.*;
|
||||
|
||||
import com.threerings.cast.Log;
|
||||
import com.threerings.cast.*;
|
||||
|
||||
/**
|
||||
* The component panel displays the available components for a
|
||||
* particular component type, allows the user to choose a set of
|
||||
* components for compositing, and makes available a {@link
|
||||
* CharacterDescriptor} suitable for passing to {@link
|
||||
* CharacterManager#getCharacter} to create a character built from the
|
||||
* chosen components.
|
||||
*/
|
||||
public class ComponentPanel extends JPanel
|
||||
{
|
||||
/**
|
||||
* Constructs the component panel.
|
||||
*/
|
||||
public ComponentPanel (CharacterManager charmgr, ComponentType type)
|
||||
{
|
||||
// save off references
|
||||
_type = type;
|
||||
|
||||
// retrieve component classes and relevant components
|
||||
gatherComponentInfo(charmgr);
|
||||
|
||||
GroupLayout gl = new VGroupLayout(GroupLayout.STRETCH);
|
||||
gl.setOffAxisPolicy(GroupLayout.STRETCH);
|
||||
setLayout(gl);
|
||||
|
||||
// set up a border
|
||||
setBorder(BorderFactory.createEtchedBorder());
|
||||
|
||||
// add the component editors to the panel
|
||||
addComponentEditors();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link CharacterDescriptor} detailing the selected
|
||||
* character components.
|
||||
*/
|
||||
public CharacterDescriptor getDescriptor ()
|
||||
{
|
||||
int size = _classes.size();
|
||||
int comps[] = new int[size];
|
||||
for (int ii = 0; ii < size; ii++) {
|
||||
ComponentClass cclass = (ComponentClass)_classes.get(ii);
|
||||
ComponentEditor ce = (ComponentEditor)_editors.get(ii);
|
||||
comps[cclass.clid] = ce.getSelectedComponent();
|
||||
}
|
||||
|
||||
return new CharacterDescriptor(_type, comps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gathers component information from the character manager for
|
||||
* later use when creating the editor components and the resulting
|
||||
* character descriptor.
|
||||
*/
|
||||
protected void gatherComponentInfo (CharacterManager charmgr)
|
||||
{
|
||||
// get the list of all component classes
|
||||
CollectionUtil.addAll(_classes, charmgr.enumerateComponentClasses());
|
||||
|
||||
for (int ii = 0; ii < _classes.size(); ii++) {
|
||||
// get the list of components available for this class
|
||||
int ctid = _type.ctid;
|
||||
int clid = ((ComponentClass)_classes.get(ii)).clid;
|
||||
Iterator comps = charmgr.enumerateComponentsByClass(ctid, clid);
|
||||
|
||||
while (comps.hasNext()) {
|
||||
Integer cid = (Integer)comps.next();
|
||||
|
||||
ArrayList clist = (ArrayList)_classinfo.get(clid);
|
||||
if (clist == null) {
|
||||
_classinfo.put(clid, clist = new ArrayList());
|
||||
}
|
||||
|
||||
clist.add(cid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds editor user interface elements for each component class to
|
||||
* allow the user to select the desired component.
|
||||
*/
|
||||
protected void addComponentEditors ()
|
||||
{
|
||||
int size = _classes.size();
|
||||
for (int ii = 0; ii < size; ii++) {
|
||||
ComponentClass cclass = (ComponentClass)_classes.get(ii);
|
||||
List components = (List)_classinfo.get(cclass.clid);
|
||||
|
||||
// create the component editor
|
||||
ComponentEditor e = new ComponentEditor(cclass, components);
|
||||
_editors.add(e);
|
||||
|
||||
// add it to the panel
|
||||
add(e);
|
||||
}
|
||||
}
|
||||
|
||||
/** The component type associated with the character components. */
|
||||
protected ComponentType _type;
|
||||
|
||||
/** The list of all available component classes. */
|
||||
protected ArrayList _classes = new ArrayList();
|
||||
|
||||
/** The list of component editors for each component class. */
|
||||
protected ArrayList _editors = new ArrayList();
|
||||
|
||||
/** The hashtable of available component ids for each class. */
|
||||
protected HashIntMap _classinfo = new HashIntMap();
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
//
|
||||
// $Id: SpritePanel.java,v 1.1 2001/10/30 16:16:01 shaper Exp $
|
||||
|
||||
package com.threerings.cast.builder;
|
||||
|
||||
import java.awt.*;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.border.BevelBorder;
|
||||
|
||||
import com.threerings.media.sprite.*;
|
||||
|
||||
import com.threerings.cast.Log;
|
||||
import com.threerings.cast.CharacterSprite;
|
||||
|
||||
/**
|
||||
* The sprite panel displays a character sprite centered in the panel
|
||||
* suitable for user perusal.
|
||||
*/
|
||||
public class SpritePanel extends AnimatedPanel
|
||||
{
|
||||
/**
|
||||
* Constructs the sprite panel.
|
||||
*/
|
||||
public SpritePanel ()
|
||||
{
|
||||
// create and save off references to our managers
|
||||
_spritemgr = new SpriteManager();
|
||||
_animmgr = new AnimationManager(_spritemgr, this);
|
||||
|
||||
// create a visually pleasing border
|
||||
setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the sprite to be displayed.
|
||||
*/
|
||||
public void setSprite (CharacterSprite sprite)
|
||||
{
|
||||
_sprite = sprite;
|
||||
_sprite.setOrientation(Sprite.DIR_SOUTHWEST);
|
||||
centerSprite();
|
||||
repaint();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected void render (Graphics g)
|
||||
{
|
||||
Graphics2D gfx = (Graphics2D)g;
|
||||
|
||||
// clear the background
|
||||
gfx.setColor(Color.lightGray);
|
||||
Dimension d = getSize();
|
||||
gfx.fillRect(0, 0, d.width - 1, d.height - 1);
|
||||
|
||||
if (_sprite != null) {
|
||||
// render the sprite
|
||||
_sprite.paint((Graphics2D)g);
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void setBounds (Rectangle r)
|
||||
{
|
||||
super.setBounds(r);
|
||||
centerSprite();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the sprite's location to render it centered within the panel.
|
||||
*/
|
||||
protected void centerSprite ()
|
||||
{
|
||||
if (_sprite != null) {
|
||||
Dimension d = getSize();
|
||||
int swid = _sprite.getWidth(), shei = _sprite.getHeight();
|
||||
int x = d.width / 2, y = (d.height + shei) / 2;
|
||||
_sprite.setLocation(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
/** The sprite displayed by the panel. */
|
||||
protected Sprite _sprite;
|
||||
|
||||
/** The animation manager. */
|
||||
protected AnimationManager _animmgr;
|
||||
|
||||
/** The sprite manager. */
|
||||
protected SpriteManager _spritemgr;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: XMLComponentParser.java,v 1.1 2001/10/26 01:17:21 shaper Exp $
|
||||
// $Id: XMLComponentParser.java,v 1.2 2001/10/30 16:16:01 shaper Exp $
|
||||
|
||||
package com.threerings.cast;
|
||||
|
||||
@@ -10,8 +10,16 @@ import org.xml.sax.*;
|
||||
|
||||
import com.samskivert.util.HashIntMap;
|
||||
import com.samskivert.util.StringUtil;
|
||||
import com.samskivert.util.Tuple;
|
||||
import com.samskivert.xml.SimpleParser;
|
||||
|
||||
/**
|
||||
* Parses an XML character component description file and populates
|
||||
* hashtables with component type, component class, and specific
|
||||
* component information. Does not currently perform validation on
|
||||
* the input XML stream, though the parsing code assumes the XML
|
||||
* document is well-formed.
|
||||
*/
|
||||
public class XMLComponentParser extends SimpleParser
|
||||
{
|
||||
// documentation inherited
|
||||
@@ -28,31 +36,52 @@ public class XMLComponentParser extends SimpleParser
|
||||
ct.fps = parseInt(attributes.getValue("fps"));
|
||||
parsePoint(attributes.getValue("origin"), ct.origin);
|
||||
|
||||
Log.info("Parsed component type [ct=" + ct + "].");
|
||||
|
||||
// save the component type
|
||||
_types.put(ct.ctid, ct);
|
||||
|
||||
} else if (qName.equals("class")) {
|
||||
// save off the component class info
|
||||
ComponentClass cclass = new ComponentClass();
|
||||
cclass.clid = parseInt(attributes.getValue("clid"));
|
||||
cclass.name = attributes.getValue("name");
|
||||
cclass.render = parseInt(attributes.getValue("render"));
|
||||
_classes.put(cclass.clid, cclass);
|
||||
|
||||
} else if (qName.equals("component")) {
|
||||
// save off the component info
|
||||
// retrieve the component attributes
|
||||
int cid = parseInt(attributes.getValue("cid"));
|
||||
int ctid = parseInt(attributes.getValue("ctid"));
|
||||
_components.put(cid, new Integer(ctid));
|
||||
int clid = parseInt(attributes.getValue("clid"));
|
||||
|
||||
// output a warning if the component references valid
|
||||
// attributes
|
||||
if (_types.get(ctid) == null) {
|
||||
Log.warning("Component references non-existent type " +
|
||||
"[cid=" + cid + ", ctid=" + ctid + "].");
|
||||
}
|
||||
if (_classes.get(clid) == null) {
|
||||
Log.warning("Component references non-existent class " +
|
||||
"[cid=" + cid + ", clid=" + clid + "].");
|
||||
}
|
||||
|
||||
// save off the component information
|
||||
_components.put(cid, new Tuple(
|
||||
new Integer(ctid), new Integer(clid)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the component descriptions in the given file into {@link
|
||||
* ComponentType} and {@link CharacterComponent} objects in the
|
||||
* given hashtables, respectively, keyed on the type and component
|
||||
* unique id, also respectively.
|
||||
* Loads the component descriptions in the given file into the
|
||||
* given component data hashtables.
|
||||
*/
|
||||
public void loadComponents (
|
||||
String file, HashIntMap types, HashIntMap components)
|
||||
String file, HashIntMap types, HashIntMap classes,
|
||||
HashIntMap components)
|
||||
throws IOException
|
||||
{
|
||||
// save off hashtables for reference while parsing
|
||||
_types = types;
|
||||
_classes = classes;
|
||||
_components = components;
|
||||
|
||||
parseFile(file);
|
||||
@@ -77,4 +106,7 @@ public class XMLComponentParser extends SimpleParser
|
||||
|
||||
/** The hashtable of character components gathered while parsing. */
|
||||
protected HashIntMap _components;
|
||||
|
||||
/** The hashtable of component classes gathered while parsing. */
|
||||
protected HashIntMap _classes;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
//
|
||||
// $Id: XMLComponentRepository.java,v 1.1 2001/10/26 01:17:22 shaper Exp $
|
||||
// $Id: XMLComponentRepository.java,v 1.2 2001/10/30 16:16:01 shaper Exp $
|
||||
|
||||
package com.threerings.miso.scene.xml;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.samskivert.util.Config;
|
||||
import com.samskivert.util.HashIntMap;
|
||||
import com.samskivert.util.Tuple;
|
||||
|
||||
import com.threerings.cast.*;
|
||||
import com.threerings.cast.CharacterComponent.ComponentFrames;
|
||||
@@ -35,8 +37,8 @@ public class XMLFileComponentRepository implements ComponentRepository
|
||||
// load component types and components
|
||||
String file = config.getValue(COMPFILE_KEY, DEFAULT_COMPFILE);
|
||||
try {
|
||||
new XMLComponentParser().loadComponents(
|
||||
file, _types, _components);
|
||||
XMLComponentParser p = new XMLComponentParser();
|
||||
p.loadComponents(file, _types, _classes, _components);
|
||||
} catch (IOException ioe) {
|
||||
Log.warning("Exception loading component descriptions " +
|
||||
"[ioe=" + ioe + "].");
|
||||
@@ -45,59 +47,77 @@ public class XMLFileComponentRepository implements ComponentRepository
|
||||
|
||||
// documentation inherited
|
||||
public CharacterComponent getComponent (int cid)
|
||||
throws NoSuchComponentException, NoSuchComponentTypeException
|
||||
throws NoSuchComponentException
|
||||
{
|
||||
// get the component type id
|
||||
Integer ctid = (Integer)_components.get(cid);
|
||||
if (ctid == null) {
|
||||
// get the component information
|
||||
Tuple cinfo = (Tuple)_components.get(cid);
|
||||
if (cinfo == null) {
|
||||
throw new NoSuchComponentException(cid);
|
||||
}
|
||||
|
||||
// get the component type
|
||||
ComponentType type = (ComponentType)_types.get(ctid.intValue());
|
||||
if (type == null) {
|
||||
throw new NoSuchComponentTypeException(ctid.intValue());
|
||||
}
|
||||
int ctid = ((Integer)cinfo.left).intValue();
|
||||
ComponentType type = (ComponentType)_types.get(ctid);
|
||||
|
||||
// get the component class
|
||||
int clid = ((Integer)cinfo.right).intValue();
|
||||
ComponentClass cclass = (ComponentClass)_classes.get(clid);
|
||||
|
||||
// get the character animation images
|
||||
ComponentFrames frames = TileUtil.getComponentFrames(
|
||||
_tilemgr, cid, type.frameCount);
|
||||
|
||||
// create the component
|
||||
return new CharacterComponent(type, cid, frames);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public Iterator enumerateComponents (int ctid)
|
||||
throws NoSuchComponentTypeException
|
||||
{
|
||||
return new ComponentTypeIterator(ctid);
|
||||
return new CharacterComponent(type, cclass, cid, frames);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public Iterator enumerateComponentTypes ()
|
||||
{
|
||||
return _types.keys();
|
||||
return Collections.unmodifiableMap(_types).values().iterator();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public Iterator enumerateComponentsByType (int ctid)
|
||||
{
|
||||
return new ComponentIterator(ctid);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public Iterator enumerateComponentClasses ()
|
||||
{
|
||||
return Collections.unmodifiableMap(_classes).values().iterator();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public Iterator enumerateComponentsByClass (int ctid, int clid)
|
||||
{
|
||||
return new ComponentIterator(ctid, clid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates over all components of a specified component type in
|
||||
* the component hashtable.
|
||||
* Iterates over all components of a specified component type, and
|
||||
* optionally a specified component class, in the component
|
||||
* hashtable.
|
||||
*/
|
||||
protected class ComponentTypeIterator implements Iterator
|
||||
protected class ComponentIterator implements Iterator
|
||||
{
|
||||
public ComponentTypeIterator (int ctid)
|
||||
throws NoSuchComponentTypeException
|
||||
/**
|
||||
* Constructs an iterator that iterates over all components of
|
||||
* the specified component type.
|
||||
*/
|
||||
public ComponentIterator (int ctid)
|
||||
{
|
||||
_ctid = ctid;
|
||||
_iter = _components.keys();
|
||||
advance();
|
||||
init(ctid, -1);
|
||||
}
|
||||
|
||||
// make sure we have at least one component of the
|
||||
// specified type
|
||||
if (_next == null) {
|
||||
throw new NoSuchComponentTypeException(ctid);
|
||||
}
|
||||
/**
|
||||
* Constructs an iterator that iterates over all components of
|
||||
* the specified component type and class.
|
||||
*/
|
||||
public ComponentIterator (int ctid, int clid)
|
||||
{
|
||||
init(ctid, clid);
|
||||
}
|
||||
|
||||
public boolean hasNext ()
|
||||
@@ -117,12 +137,25 @@ public class XMLFileComponentRepository implements ComponentRepository
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
protected void init (int ctid, int clid)
|
||||
{
|
||||
_ctid = ctid;
|
||||
_clid = clid;
|
||||
_iter = _components.keys();
|
||||
advance();
|
||||
}
|
||||
|
||||
protected void advance ()
|
||||
{
|
||||
while (_iter.hasNext()) {
|
||||
CharacterComponent c = (CharacterComponent)_iter.next();
|
||||
if (c.getType().ctid == _ctid) {
|
||||
_next = c;
|
||||
Integer cid = (Integer)_iter.next();
|
||||
|
||||
Tuple c = (Tuple)_components.get(cid);
|
||||
int ctid = ((Integer)c.left).intValue();
|
||||
int clid = ((Integer)c.right).intValue();
|
||||
if (ctid == _ctid &&
|
||||
(_clid == -1 || (clid == _clid))) {
|
||||
_next = cid;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -132,11 +165,15 @@ public class XMLFileComponentRepository implements ComponentRepository
|
||||
/** The component type id we're enumerating over. */
|
||||
protected int _ctid;
|
||||
|
||||
/** The component class id required for inclusion in the
|
||||
* iterator, or -1 for all classes. */
|
||||
protected int _clid;
|
||||
|
||||
/** The next character component of the component type id
|
||||
* associated with this iterator, or null if no more exist. */
|
||||
protected Object _next;
|
||||
|
||||
/** Iterator over the components in the repository. */
|
||||
/** The iterator over all components in the repository. */
|
||||
protected Iterator _iter;
|
||||
}
|
||||
|
||||
@@ -151,6 +188,9 @@ public class XMLFileComponentRepository implements ComponentRepository
|
||||
/** The hashtable of component types. */
|
||||
protected HashIntMap _types = new HashIntMap();
|
||||
|
||||
/** The hashtable of component classes. */
|
||||
protected HashIntMap _classes = new HashIntMap();
|
||||
|
||||
/** The hashtable of character components. */
|
||||
protected HashIntMap _components = new HashIntMap();
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: DirtyItemList.java,v 1.4 2001/10/26 01:17:21 shaper Exp $
|
||||
// $Id: DirtyItemList.java,v 1.5 2001/10/30 16:16:01 shaper Exp $
|
||||
|
||||
package com.threerings.miso.scene;
|
||||
|
||||
@@ -142,7 +142,9 @@ public class DirtyItemList extends ArrayList
|
||||
|
||||
public String toString ()
|
||||
{
|
||||
return "[obj=" + obj + ", ox=" + ox + ", oy=" + oy + "]";
|
||||
return "[obj=" + obj + ", ox=" + ox + ", oy=" + oy +
|
||||
", lx=" + lx + ", ly=" + ly + ", rx=" + rx +
|
||||
", ry=" + ry + "]";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,28 +165,36 @@ public class DirtyItemList extends ArrayList
|
||||
DirtyItem db = (DirtyItem)b;
|
||||
|
||||
if (da.ox == db.ox &&
|
||||
da.oy == db.oy &&
|
||||
(da.obj instanceof MisoCharacterSprite) &&
|
||||
(db.obj instanceof MisoCharacterSprite)) {
|
||||
// we're comparing two sprites co-existing on the same
|
||||
// tile, so study their fine coordinates to determine
|
||||
// rendering order
|
||||
MisoCharacterSprite as = (MisoCharacterSprite)da.obj;
|
||||
MisoCharacterSprite bs = (MisoCharacterSprite)db.obj;
|
||||
da.oy == db.oy) {
|
||||
|
||||
int ahei = as.getFineX() + as.getFineY();
|
||||
int bhei = bs.getFineX() + bs.getFineY();
|
||||
if (da.equals(db)) {
|
||||
// render level is equal if we're the same sprite
|
||||
// or an object at the same location
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ahei < bhei) {
|
||||
// item b is in front of item a
|
||||
return -1;
|
||||
} else if (ahei > bhei) {
|
||||
// item a is in front of item b
|
||||
return 1;
|
||||
} else {
|
||||
// if they're at the same vertical row of
|
||||
// intra-tile tiles, just use something consistent
|
||||
return as.hashCode() - bs.hashCode();
|
||||
if ((da.obj instanceof MisoCharacterSprite) &&
|
||||
(db.obj instanceof MisoCharacterSprite)) {
|
||||
// we're comparing two sprites co-existing on the same
|
||||
// tile, so study their fine coordinates to determine
|
||||
// rendering order
|
||||
MisoCharacterSprite as = (MisoCharacterSprite)da.obj;
|
||||
MisoCharacterSprite bs = (MisoCharacterSprite)db.obj;
|
||||
|
||||
int ahei = as.getFineX() + as.getFineY();
|
||||
int bhei = bs.getFineX() + bs.getFineY();
|
||||
|
||||
if (ahei < bhei) {
|
||||
// item b is in front of item a
|
||||
return -1;
|
||||
} else if (ahei > bhei) {
|
||||
// item a is in front of item b
|
||||
return 1;
|
||||
} else {
|
||||
// if they're at the same vertical row of
|
||||
// intra-tile tiles, just use something consistent
|
||||
return as.hashCode() - bs.hashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,10 +202,10 @@ public class DirtyItemList extends ArrayList
|
||||
da.ry > db.oy) {
|
||||
// item a is in front of item b
|
||||
return 1;
|
||||
} else {
|
||||
// item b is in front of item a
|
||||
return -1;
|
||||
}
|
||||
|
||||
// item b is in front of item a
|
||||
return -1;
|
||||
}
|
||||
|
||||
public boolean equals (Object obj)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: MisoUtil.java,v 1.10 2001/10/26 01:17:22 shaper Exp $
|
||||
// $Id: MisoUtil.java,v 1.11 2001/10/30 16:16:01 shaper Exp $
|
||||
|
||||
package com.threerings.miso.util;
|
||||
|
||||
@@ -43,6 +43,41 @@ public class MisoUtil
|
||||
config.bindProperties(CONFIG_KEY, "rsrc/config/miso/miso");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>Config</code> object that contains
|
||||
* configuration parameters for miso.
|
||||
*/
|
||||
public static Config createConfig ()
|
||||
{
|
||||
return createConfig(null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>Config</code> object that contains
|
||||
* configuration parameters for miso. If <code>key</code> and
|
||||
* <code>path</code> are non-<code>null</code>, the properties in
|
||||
* the given file will additionally be bound to the specified
|
||||
* config key namespace.
|
||||
*/
|
||||
public static Config createConfig (String key, String path)
|
||||
{
|
||||
Config config = new Config();
|
||||
try {
|
||||
// load the miso config info
|
||||
bindProperties(config);
|
||||
|
||||
if (key != null && path != null) {
|
||||
// load the application-specific config info
|
||||
config.bindProperties(key, path);
|
||||
}
|
||||
|
||||
} catch (IOException ioe) {
|
||||
Log.warning("Error loading config information [e=" + ioe + "].");
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>CharacterManager</code> object.
|
||||
*
|
||||
@@ -57,7 +92,7 @@ public class MisoUtil
|
||||
{
|
||||
XMLFileComponentRepository crepo =
|
||||
new XMLFileComponentRepository(config, tilemgr);
|
||||
CharacterManager charmgr = new CharacterManager(tilemgr, crepo);
|
||||
CharacterManager charmgr = new CharacterManager(crepo);
|
||||
charmgr.setCharacterClass(MisoCharacterSprite.class);
|
||||
return charmgr;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
//
|
||||
// $Id: TestApp.java,v 1.1 2001/10/30 16:16:01 shaper Exp $
|
||||
|
||||
package com.threerings.cast.builder.test;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.swing.JFrame;
|
||||
|
||||
import com.samskivert.util.Config;
|
||||
import com.samskivert.swing.util.SwingUtil;
|
||||
|
||||
import com.threerings.cast.Log;
|
||||
import com.threerings.cast.CharacterManager;
|
||||
import com.threerings.media.tile.TileManager;
|
||||
|
||||
import com.threerings.miso.util.MisoContext;
|
||||
import com.threerings.miso.util.MisoUtil;
|
||||
|
||||
public class TestApp
|
||||
{
|
||||
public TestApp (String[] args)
|
||||
{
|
||||
_frame = new TestFrame();
|
||||
_frame.setSize(800, 600);
|
||||
SwingUtil.centerWindow(_frame);
|
||||
|
||||
// create the handles on our various services
|
||||
_config = MisoUtil.createConfig();
|
||||
_tilemgr = MisoUtil.createTileManager(_config, _frame);
|
||||
|
||||
CharacterManager charmgr =
|
||||
MisoUtil.createCharacterManager(_config, _tilemgr);
|
||||
|
||||
// create the context object
|
||||
_ctx = new TestContextImpl();
|
||||
|
||||
// initialize the frame
|
||||
((TestFrame)_frame).init(charmgr);
|
||||
}
|
||||
|
||||
public void run ()
|
||||
{
|
||||
_frame.pack();
|
||||
_frame.show();
|
||||
}
|
||||
|
||||
public static void main (String[] args)
|
||||
{
|
||||
TestApp app = new TestApp(args);
|
||||
app.run();
|
||||
}
|
||||
|
||||
protected class TestContextImpl implements MisoContext
|
||||
{
|
||||
public Config getConfig ()
|
||||
{
|
||||
return _config;
|
||||
}
|
||||
|
||||
public TileManager getTileManager ()
|
||||
{
|
||||
return _tilemgr;
|
||||
}
|
||||
}
|
||||
|
||||
/** The test frame. */
|
||||
protected JFrame _frame;
|
||||
|
||||
/** The test context. */
|
||||
protected MisoContext _ctx;
|
||||
|
||||
/** The config object. */
|
||||
protected Config _config;
|
||||
|
||||
/** The tile manager object. */
|
||||
protected TileManager _tilemgr;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// $Id: TestFrame.java,v 1.1 2001/10/30 16:16:01 shaper Exp $
|
||||
|
||||
package com.threerings.cast.builder.test;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
|
||||
import com.threerings.cast.CharacterManager;
|
||||
import com.threerings.cast.builder.BuilderPanel;
|
||||
|
||||
public class TestFrame extends JFrame
|
||||
{
|
||||
public TestFrame ()
|
||||
{
|
||||
super("Character Builder");
|
||||
|
||||
setResizable(false);
|
||||
setDefaultCloseOperation(EXIT_ON_CLOSE);
|
||||
}
|
||||
|
||||
public void init (CharacterManager charmgr)
|
||||
{
|
||||
getContentPane().add(new BuilderPanel(charmgr));
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: ViewerApp.java,v 1.9 2001/10/17 22:16:04 shaper Exp $
|
||||
// $Id: ViewerApp.java,v 1.10 2001/10/30 16:16:01 shaper Exp $
|
||||
|
||||
package com.threerings.miso.viewer;
|
||||
|
||||
@@ -32,7 +32,8 @@ public class ViewerApp
|
||||
SwingUtil.centerWindow(_frame);
|
||||
|
||||
// create the handles on our various services
|
||||
_config = createConfig();
|
||||
_config = MisoUtil.createConfig(
|
||||
ViewerModel.CONFIG_KEY, "rsrc/config/miso/viewer");
|
||||
_model = createModel(_config, args);
|
||||
_tilemgr = MisoUtil.createTileManager(_config, _frame);
|
||||
_screpo = MisoUtil.createSceneRepository(_config, _tilemgr);
|
||||
@@ -44,28 +45,6 @@ public class ViewerApp
|
||||
((ViewerFrame)_frame).init(_ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the config object that contains configuration parameters
|
||||
* for the application and other utilized packages.
|
||||
*/
|
||||
protected Config createConfig ()
|
||||
{
|
||||
Config config = new Config();
|
||||
try {
|
||||
// load the miso config info
|
||||
MisoUtil.bindProperties(config);
|
||||
|
||||
// load the viewer-specific config info
|
||||
config.bindProperties(
|
||||
ViewerModel.CONFIG_KEY, "rsrc/config/miso/viewer");
|
||||
|
||||
} catch (IOException ioe) {
|
||||
Log.warning("Error loading config information [e=" + ioe + "].");
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
protected ViewerModel createModel (Config config, String args[])
|
||||
{
|
||||
ViewerModel model = new ViewerModel(config);
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
//
|
||||
// $Id: ViewerSceneViewPanel.java,v 1.24 2001/10/27 01:35:21 shaper Exp $
|
||||
// $Id: ViewerSceneViewPanel.java,v 1.25 2001/10/30 16:16:01 shaper Exp $
|
||||
|
||||
package com.threerings.miso.viewer;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import com.samskivert.util.CollectionUtil;
|
||||
import com.samskivert.util.Config;
|
||||
|
||||
import com.threerings.cast.*;
|
||||
@@ -47,8 +50,12 @@ public class ViewerSceneViewPanel extends SceneViewPanel
|
||||
CharacterManager charmgr = MisoUtil.createCharacterManager(
|
||||
ctx.getConfig(), ctx.getTileManager());
|
||||
|
||||
// create the character descriptors
|
||||
_descUser = createCharacterDescriptor(charmgr);
|
||||
_descDecoy = createCharacterDescriptor(charmgr);
|
||||
|
||||
// create the manipulable sprite
|
||||
_sprite = createSprite(spritemgr, charmgr, TSID_CHAR_USER);
|
||||
_sprite = createSprite(spritemgr, charmgr, _descUser);
|
||||
|
||||
// create the decoy sprites
|
||||
createDecoys(spritemgr, charmgr);
|
||||
@@ -67,10 +74,9 @@ public class ViewerSceneViewPanel extends SceneViewPanel
|
||||
* Creates a new sprite.
|
||||
*/
|
||||
protected MisoCharacterSprite createSprite (
|
||||
SpriteManager spritemgr, CharacterManager charmgr, int tsid)
|
||||
SpriteManager spritemgr, CharacterManager charmgr,
|
||||
CharacterDescriptor desc)
|
||||
{
|
||||
int dummy[] = { tsid };
|
||||
CharacterDescriptor desc = new CharacterDescriptor(dummy);
|
||||
MisoCharacterSprite s =
|
||||
(MisoCharacterSprite)charmgr.getCharacter(desc);
|
||||
if (s != null) {
|
||||
@@ -91,7 +97,7 @@ public class ViewerSceneViewPanel extends SceneViewPanel
|
||||
{
|
||||
_decoys = new MisoCharacterSprite[NUM_DECOYS];
|
||||
for (int ii = 0; ii < NUM_DECOYS; ii++) {
|
||||
_decoys[ii] = createSprite(spritemgr, charmgr, TSID_CHAR);
|
||||
_decoys[ii] = createSprite(spritemgr, charmgr, _descDecoy);
|
||||
if (_decoys[ii] != null) {
|
||||
createRandomPath(_decoys[ii]);
|
||||
}
|
||||
@@ -179,6 +185,42 @@ public class ViewerSceneViewPanel extends SceneViewPanel
|
||||
} while (!createPath(s, x, y));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link CharacterDescriptor} suitable for use in
|
||||
* creating character sprites via {@link
|
||||
* CharacterManager#getCharacter}.
|
||||
*/
|
||||
protected CharacterDescriptor
|
||||
createCharacterDescriptor (CharacterManager charmgr)
|
||||
{
|
||||
// get the base component type (always the first type for now).
|
||||
// TODO: change this to retrieve component type by name
|
||||
Iterator iter = charmgr.enumerateComponentTypes();
|
||||
ComponentType ctype = (ComponentType)iter.next();
|
||||
|
||||
// get all available classes
|
||||
ArrayList classes = new ArrayList();
|
||||
CollectionUtil.addAll(classes, charmgr.enumerateComponentClasses());
|
||||
|
||||
// select the components
|
||||
int size = classes.size();
|
||||
int components[] = new int[size];
|
||||
for (int ii = 0; ii < size; ii++) {
|
||||
ComponentClass cclass = (ComponentClass)classes.get(ii);
|
||||
|
||||
// get the components available for this class
|
||||
ArrayList choices = new ArrayList();
|
||||
iter = charmgr.enumerateComponentsByClass(ctype.ctid, cclass.clid);
|
||||
CollectionUtil.addAll(choices, iter);
|
||||
|
||||
// choose a random component
|
||||
int idx = RandomUtil.getInt(choices.size());
|
||||
components[cclass.clid] = ((Integer)choices.get(idx)).intValue();
|
||||
}
|
||||
|
||||
return new CharacterDescriptor(ctype, components);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void handleEvent (SpriteEvent event)
|
||||
{
|
||||
@@ -193,13 +235,13 @@ public class ViewerSceneViewPanel extends SceneViewPanel
|
||||
}
|
||||
|
||||
/** The number of decoy characters milling about. */
|
||||
protected static final int NUM_DECOYS = 2;
|
||||
protected static final int NUM_DECOYS = 10;
|
||||
|
||||
/** The tileset id for the decoy character tiles. */
|
||||
protected static final int TSID_CHAR = 1011;
|
||||
/** The character descriptor for the user character. */
|
||||
protected CharacterDescriptor _descUser;
|
||||
|
||||
/** The tileset id for the user character tiles. */
|
||||
protected static final int TSID_CHAR_USER = 1012;
|
||||
/** The character descriptor for the decoy characters. */
|
||||
protected CharacterDescriptor _descDecoy;
|
||||
|
||||
/** The animation manager. */
|
||||
protected AnimationManager _animmgr;
|
||||
|
||||
Reference in New Issue
Block a user