MakeTiles: working on support for animated tiles

This commit is contained in:
Jason Long 2014-06-19 14:08:41 -04:00
parent de82160792
commit 41c8d68717
2 changed files with 118 additions and 16 deletions

View file

@ -9,7 +9,7 @@ import static micropolisj.XML_Helper.*;
class Animation extends MakeTiles.TileImage
{
static final int DEFAULT_DURATION = 125;
List<AnimationFrame> frames = new ArrayList<AnimationFrame>();
List<Frame> frames = new ArrayList<Frame>();
public static Animation load(File aniFile)
throws IOException
@ -20,6 +20,11 @@ class Animation extends MakeTiles.TileImage
return self;
}
public void addFrame(Frame f)
{
frames.add(f);
}
void load(InputStream inStream)
throws IOException
{
@ -42,8 +47,8 @@ class Animation extends MakeTiles.TileImage
int duration = tmp != null ? Integer.parseInt(tmp) : DEFAULT_DURATION;
tmp = in.getElementText();
frames.add(
new AnimationFrame(
addFrame(
new Frame(
MakeTiles.parseFrameSpec(tmp),
duration
));
@ -63,12 +68,12 @@ class Animation extends MakeTiles.TileImage
}
}
static class AnimationFrame
static class Frame
{
MakeTiles.TileImage frame;
int duration;
public AnimationFrame(MakeTiles.TileImage frame, int duration)
public Frame(MakeTiles.TileImage frame, int duration)
{
this.frame = frame;
this.duration = duration;
@ -76,9 +81,22 @@ class Animation extends MakeTiles.TileImage
}
@Override
void drawTo(Graphics2D gr, int destX, int destY, int srcX, int srcY)
public void drawTo(Graphics2D gr, int destX, int destY, int srcX, int srcY)
{
if (frames.isEmpty()) { return; }
frames.get(0).frame.drawTo(gr, destX, destY, srcX, srcY);
}
@Override
public int getFrameEndTime(int frameTime)
{
int t = 0;
for (int i = 0; i < frames.size(); i++) {
t += frames.get(i).duration;
if (frameTime < t) {
return t;
}
}
return -1;
}
}

View file

@ -93,9 +93,33 @@ public class MakeTiles
continue;
}
TileImageSprite dest = new TileImageSprite();
dest.offsetY = nextOffsetY;
nextOffsetY += TILE_SIZE;
TileImage dest;
if (ref.getFrameEndTime(0) > 0) {
Animation ani = new Animation();
int t = 0;
int n = ref.getFrameEndTime(t);
while (n > 0) {
TileImageSprite s = new TileImageSprite();
s.offsetY = nextOffsetY;
nextOffsetY += TILE_SIZE;
Animation.Frame f = new Animation.Frame(s, n-t);
ani.addFrame(f);
t = n;
n = ref.getFrameEndTime(t);
}
dest = ani;
}
else {
TileImageSprite s = new TileImageSprite();
s.offsetY = nextOffsetY;
nextOffsetY += TILE_SIZE;
dest = s;
}
TileMapping m = new TileMapping(tileName, ref, dest);
mappings.add(m);
@ -107,8 +131,19 @@ public class MakeTiles
for (TileMapping m : mappings) {
TileImageSprite sprite = (TileImageSprite) m.dest;
m.ref.drawTo(gr, sprite.offsetX, sprite.offsetY, 0, 0);
assert (m.dest instanceof Animation) || (m.dest instanceof TileImageSprite);
if (m.dest instanceof Animation) {
Animation ani = (Animation) m.dest;
for (Animation.Frame f : ani.frames) {
TileImageSprite s = (TileImageSprite) f.frame;
m.ref.drawTo(gr, s.offsetX, s.offsetY, 0, 0);
}
}
else {
TileImageSprite sprite = (TileImageSprite) m.dest;
m.ref.drawTo(gr, sprite.offsetX, sprite.offsetY, 0, 0);
}
}
// make parent directories if necessary
@ -139,7 +174,20 @@ public class MakeTiles
out.writeStartElement("tile");
out.writeAttribute("name", m.tileName);
{ //assume it is a simple sprite
assert (m.dest instanceof Animation) || (m.dest instanceof TileImageSprite);
if (m.dest instanceof Animation) {
Animation ani = (Animation) m.dest;
out.writeStartElement("animation");
for (Animation.Frame f : ani.frames) {
TileImageSprite s = (TileImageSprite) f.frame;
out.writeStartElement("frame");
out.writeAttribute("offsetY", Integer.toString(s.offsetY / TILE_SIZE));
out.writeEndElement();
}
out.writeEndElement();
}
else { //assume it is a simple sprite
TileImageSprite s = (TileImageSprite ) m.dest;
out.writeStartElement("image");
@ -162,7 +210,12 @@ public class MakeTiles
static abstract class TileImage
{
abstract void drawTo(Graphics2D gr, int destX, int destY, int srcX, int srcY);
public abstract void drawTo(Graphics2D gr, int destX, int destY, int srcX, int srcY);
/**
* @return the end-time of the animation frame identified by frameTime;
* -1 if not an animation, or if frameTime is past the end of the animation
*/
public abstract int getFrameEndTime(int frameTime);
}
static class TileImageLayer extends TileImage
@ -171,13 +224,34 @@ public class MakeTiles
TileImage above;
@Override
void drawTo(Graphics2D gr, int destX, int destY, int srcX, int srcY)
public void drawTo(Graphics2D gr, int destX, int destY, int srcX, int srcY)
{
if (below != null) {
below.drawTo(gr, destX, destY, srcX, srcY);
}
above.drawTo(gr, destX, destY, srcX, srcY);
}
@Override
public int getFrameEndTime(int frameTime)
{
if (below == null) {
return above.getFrameEndTime(frameTime);
}
int belowEnd = below.getFrameEndTime(frameTime);
int aboveEnd = above.getFrameEndTime(frameTime);
if (belowEnd < 0) {
return aboveEnd;
}
else if (aboveEnd < 0 || belowEnd < aboveEnd) {
return belowEnd;
}
else {
return aboveEnd;
}
}
}
static class TileImageSprite extends TileImage
@ -187,10 +261,15 @@ public class MakeTiles
int offsetY;
@Override
void drawTo(Graphics2D gr, int destX, int destY, int srcX, int srcY)
public void drawTo(Graphics2D gr, int destX, int destY, int srcX, int srcY)
{
source.drawTo(gr, destX, destY, srcX+offsetX, srcY+offsetY);
}
@Override
public int getFrameEndTime(int frameTime) {
return source.getFrameEndTime(frameTime);
}
}
static class SourceImage extends TileImage
@ -206,7 +285,7 @@ public class MakeTiles
}
@Override
void drawTo(Graphics2D gr, int destX, int destY, int srcX, int srcY)
public void drawTo(Graphics2D gr, int destX, int destY, int srcX, int srcY)
{
srcX = srcX * basisSize / STD_SIZE;
srcY = srcY * basisSize / STD_SIZE;
@ -219,6 +298,11 @@ public class MakeTiles
srcX+basisSize, srcY+basisSize,
null);
}
@Override
public int getFrameEndTime(int frameTime) {
return -1;
}
}
static TileImage parseFrameSpec(TileSpec spec)