Here is the basic sprite class.
import java.util.Vector;
import java.awt.*;
import java.applet.*;
public class Sprite extends Object
{
// Statics
public static final int UNMOVING = 0; // Never relocates
public static final int MOVING = 1; // Can relocate (move() function)
public static final int GETTABLE = 2; // Can be picked up
public static final int NOACTION = 0; // Unresponsive to mouse
public static final int ACTIVE = 1; // Responsive to mouse (act() function)
public static final int SINGLE = 0; // Single image file (furniture)
public static final int MULTIPLE = 1; // Multiple numbered files
public static final int AGIF = 2; // Animated Gif
public static final int NOANIM = -1; // No Animation
// Static-ish - set up at Constructor
private String spritename;
private String basefile;
private String suffix;
private String currimage;
private int filetype;
private int noframes;
private int movetype;
private int actiontype;
// Parametrable-Static defaulted at Constructor but alterable
private int scale;
private int priority;
private int frametimes[];
private boolean got;
private Vector images;
private Vector audioclips;
// For gettable sprites
public Vector validscenes;
public Vector positions;
// Immediate
public String scenename;
public int cursor;
public boolean cursoron;
private int frame;
private long prevtick;
private Rectangle extent;
// Maximum constructor for a Sprite
public Sprite(String spriteName, String sceneName, String fileName, int fileType,
int noOfFrames, int moveType, int actionType)
{
// text name of sprite
spritename = new String(spriteName);
// text name of 'home' scene
scenename = new String(sceneName);
// text name of image file(s)
basefile = new String(fileName);
int c = basefile.indexOf('.');
suffix = new String(basefile.substring(c));
basefile = new String(basefile.substring(0, c));
// file type single, multiple or animated gif
// (animated gif not yet implemented)
filetype = fileType;
// number of image frames in the sprite set
noframes = noOfFrames;
// movement type (can it relocate?)
movetype = moveType;
// action type (whether responsive to mouse)
actiontype = actionType;
// the images can be scaled for perpective etc.
scale = 100;
// priority determines which sprite is drawn first
priority = 1;
// enables variable speed animation
frametimes = new int[noOfFrames];
// set all the frame times to 'no animation'
setCommonTime(NOANIM);
// x pos, y pos, width, height
extent = new Rectangle(0, 0, 0, 0);
// for special cursor
cursoron = false;
// whether being carried
got = false;
// for Gettable sprites
validscenes = new Vector();
positions = new Vector();
// ?caches for images and audio clips
images = new Vector();
audioclips = new Vector();
// specify which sprite image to use
setFrame(0);
addCursor(Cursor.DEFAULT_CURSOR);
}
public void addAudio(int serial, AudioClip au)
{
audioclips.insertElementAt(au, serial);
}
public AudioClip getAudio(int serial)
{
AudioClip au = (AudioClip)audioclips.elementAt(serial);
return au;
}
public void addImage(int serial, Image im)
{
images.insertElementAt(im, serial);
}
public Image getImage(int serial)
{
Image im = (Image)images.elementAt(serial);
return im;
}
public Image getCurrentImage()
{
Image im = getImage(frame);
return im;
}
public void relocate(String sceneName)
{
scenename = sceneName;
}
// USUALLY OVERRIDDEN EXCEPT FOR NON-ANIMATED GETTABLE ITEMS
public void tick(long ticks, int mousex, int mousey)
{
prevtick = ticks;
if (got)
{
// displace Sprite from carrying cursor
//***perhaps make displacement parametrable***
setPosition(mousex+30, mousey+30);
}
}
// Usual call for animated sprites at tick()
public void increment(long ticks)
{
if ((ticks - prevtick) >= frametimes[frame])
{
setFrame(frame+1);
prevtick = ticks;
}
}
//*** rather suspicious of this ***
public int setPriority(int pr)
{
if (priority > 0)
priority = pr;
return priority;
}
public int setScale(int sc)
{
if ((sc > 0) && (sc <= 100))
scale = sc;
return scale;
}
// Set all the frame times to a single value
public void setCommonTime(int frt)
{
for(int ii = 0; ii < noframes; ii++)
{
frametimes[ii] = frt;
}
}
// Set the position
public void setPosition(int X, int Y)
{
extent.x = X;
extent.y = Y;
}
// Set the size
public void setSize(int X, int Y)
{
extent.width = X;
extent.height = Y;
}
// Get the extent
public Rectangle getExtent()
{
return extent;
}
// Set the current Frame
public void setFrame(int frameNo)
{
if (frameNo < 0)
{
frame = noframes-1;
}
else if (frameNo >= noframes)
{
frame = 0;
}
else
{
frame = frameNo;
}
//*** Not sure this is sensible if we're cacheing images ***
Integer x = new Integer(frame+1000);
String ser = new String(x.toString());
currimage = new String(basefile +
ser.substring(1) + suffix);
}
public int getFrame()
{
return frame;
}
public String getCurrentImageName()
{
return currimage;
}
public String getName()
{
return spritename;
}
public Vector getAllFilenames()
{
Vector vec = new Vector();
for (int ii = 0; ii < noframes; ii++)
{
Integer x = new Integer(ii+1000);
String ser = new String(x.toString());
String sb = new String(basefile +
ser.substring(1) + suffix);
vec.addElement(sb);
}
return vec;
}
public void addCursor(int c)
{
cursor = c;
cursoron = true;
}
public void removeCursor()
{
cursoron = false;
}
// All the Gettable stuff
public void getSprite()
{
if (movetype == GETTABLE)
{
got = true;
//*** Note when a sprite is being carried its image changes to image 1 ***
//*** I don't think there's any check on the range
setFrame(1);
}
}
public boolean isGettable()
{
if (movetype == GETTABLE)
{
return true;
}
return false;
}
public boolean isGot()
{
if (got)
return true;
return false;
}
// Overridden if a click is significant
public boolean hitBy(String hitter)
{
return false;
}
public boolean dropSprite(String Scenename)
{
if (got)
{
for(int ii = 0; ii < validscenes.size(); ii++)
{
String scene =
(String)validscenes.elementAt(ii);
if (scene.equals(Scenename))
{
got = false;
Point point =
(Point)positions.elementAt(ii);
// -1 means anywhere - inventory page etc.
if (point.x != -1)
setPosition(point.x, point.y);
setFrame(0);
return true;
}
}
}
return false;
}
public void addValidDrop(String scene, int xpos, int ypos)
{
validscenes.addElement(scene);
Point point = new Point(xpos, ypos);
positions.addElement(point);
}
public boolean isHit(int hitx, int hity)
{
if (extent.contains(hitx, hity))
{
return true;
}
return false;
}
// overriden for Sprites about which saving/restoring has
// some relevance other than position
public String saveMe()
{
return null;
}
public boolean restoreMe(String savestring)
{
return true;
}
// used by Sprites which saveMe()
public String getSavePrefix()
{
String saver = new String(spritename + "<");
return(saver);
}
public String gotSave()
{
if (this.isGot())
{
return ("[GOT]");
}
else
{
return ("[NOTGOT]");
}
}
//*** I wonder if this causes trouble on restore when it's got ***
//*** There is a situation where a gettable sprite is marooned on restore
public String posSave()
{
Integer X = new Integer(extent.x);
Integer Y = new Integer(extent.y);
String saver = new String("[X" + X.toString()
+ "Y" + Y.toString() + "]");
return saver;
}
public Point posRestore(String restoreString)
{
int X, Y;
X = 0;
Y = 0;
int start = restoreString.indexOf("[X");
int end = restoreString.indexOf("Y", start);
if ((start != -1)&&(end != -1))
{
String temp =
restoreString.substring(start+2, end);
try
{
X = Integer.parseInt(temp);
}
catch (NumberFormatException e)
{
X = 0;
}
start=end + 1;
end = restoreString.indexOf("]", start);
if (end != -1)
{
temp = restoreString.substring(start, end);
try
{
Y = Integer.parseInt(temp);
}
catch (NumberFormatException e)
{
Y = 0;
}
}
}
Point p = new Point(X, Y);
return p;
}
public String getRestoreContent(String restoreString)
{
String search = getSavePrefix();
int start = restoreString.indexOf(search);
if (start != -1)
{
start += search.length();
int end = restoreString.indexOf(">", start);
if (end != -1)
{
search = restoreString.substring(start, end);
return search;
}
}
return null;
}
}
There are definitely some areas for expansion, modification and improvement here, despite the fact that it largely works already. In particular, the areas marked with //*** will reward further study.
No comments:
Post a Comment