MakeTiles: working on support for animated tiles
This commit is contained in:
parent
de82160792
commit
41c8d68717
2 changed files with 118 additions and 16 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Reference in a new issue