Monday 1 April 2013

Animated tiles & bigger sprites

I haven't really had much energy left to play with DuskZ for a while (with work and the android video editor prototype), but after some prompting from the graphics guy I thought i'd have a go at some low-hanging fruit. One thing I've noticed from my customer at work is that if they casually mention something more than twice, they're more than casually interested in it ...

Mostly based on this code idea I hacked up a very simple prototype of adding animated tiles to Dusk.

One issue I thought I might have is with trying to keep a global sync so that moving (which re-renders all the tiles currently) doesn't reset the animation. Solution? Well just leave one animator running and change the set of ImageView's it works with instead of creating a new animator every time.

i.e. piece of piss.

The graphics artist also thought that scaling the player sprites might be a bit of work, but that was just a 3 line change: delete the code that scaled the ImageView, and adjust the origin to suit the new size.

Obviously one cannot see the animation here, but it's flipping between the base water tile and the 'waterfall' tile, in a rather annoying way reminiscent of Geocities in the days of the flashing tag, although it's reliably keeping regular time. And z suddenly got a lot bigger. To do a better demo I would need to render with a separate water layer and have a better water animation.

This version of the animator class needs to be instantiated for each type of animated tile. e.g. one for water, one for fire, or whatever, but then it updates all the visible tiles at once.

public class TileAnimator extends Transition {

    Rectangle2D[] viewports;
    List<ImageView> nodes;

    public TileAnimator(List<ImageView> nodes, Duration duration, Rectangle2D[] images) {
        setCycleDuration(duration);
        this.viewports = images;
        this.nodes = nodes;
    }

    public void setNodes(List<ImageView> nodes) {
        this.nodes = nodes;
    }

    protected void interpolate(double d) {
        int index = Math.min(viewports.length - 1, (int) (d * viewports.length));

        for (ImageView node : nodes)
            node.setViewport(viewports[index]);
    }
}

JavaFX really does most of the work, all the animator is doing is changing the texture coordinates around. The hardest part, if you can call it that, will be defining and communicating the animation meta-data to the client code.

2 comments:

Unknown said...

Wow! o.O Your a Java genius NotZed! You called these features 'low hanging fruit' and implemented it all so quickly. I'm seriously amazed at what you can accomplish so quickly by changing a couple lines of code :D

You have now tackled everything on my list of improvements I'd like to see in Dusk. Congratulations! Thanks for working on this and noticing my casual mention of these features. I'm very excited/happy to see these features in Dusk! You have no clue how happy you just made me, LOL! Awesome :-]

It'll be my pleasure to make some water animation. I already planned to but now I'm motivated since you just added animation in Dusk! :D

Unknown said...

It's been a half year but I did come up with a pretty good water animation eventually. It's a 64x64 water animation with 15 frames and works with a beach that is about 20 tiles at 10 frames. There's quite a lot of tiles for this animation (250tiles to be exact) it matchs style nicely and would be quite awesome to see in-game. Here's the link http://duskrpg.blogspot.com/2013/09/quick-dusk-update-new-animated.html