package rabbitescape.render; import java.util.ArrayList; import java.util.List; import java.util.Locale; import rabbitescape.engine.*; import rabbitescape.engine.util.Util; public class SpriteAnimator { private final World world; private final AnimationCache animationCache; private static final String[] metal_block = new String[] { "metal_block_1", "metal_block_2", "metal_block_3", "metal_block_4", }; private static final String[] land_block = new String[] { "land_block_1", "land_block_2", "land_block_3", "land_block_4", }; private static final String[] land_rising_right = new String[] { "land_rising_right_1", "land_rising_right_2", "land_rising_right_3", "land_rising_right_4" }; private static final String[] land_rising_left = new String[] { "land_rising_left_1", "land_rising_left_2", "land_rising_left_3", "land_rising_left_4" }; private static final String bridge_rising_right = "bridge_rising_right"; private static final String bridge_rising_left = "bridge_rising_left"; public SpriteAnimator( World world, AnimationCache animationCache ) { this.world = world; this.animationCache = animationCache; } public List<Sprite> getSprites( int frameNum ) { List<Sprite> ret = new ArrayList<>(); for ( Block block : world.blockTable ) { addBlock( block, ret ); } for ( Thing thing : Util.filterOut( world.things, Fire.class ) ) { addThing( frameNum, thing, null, ret ); } for ( Rabbit rabbit : world.rabbits ) { addThing( frameNum, rabbit, null, ret ); } for ( Thing thing : Util.filterIn( world.things, Fire.class ) ) { addThing( frameNum, thing, null, ret ); } for ( Thing thing : world.changes.tokensAboutToAppear() ) { addThing( frameNum, thing, null, ret ); } // TODO: probably easier if we just had a rabbit entering animation if ( frameNum == 0 ) { for ( Thing thing : world.changes.rabbitsJustEntered() ) { addThing( -1, thing, "rabbit_entering", ret ); } } VoidMarker.mark( world, ret, world.voidStyle ); return ret; } private void addBlock( Block block, List<Sprite> ret ) { ret.add( new Sprite( bitmapNameForBlock( block ), null, block.x, block.y, 0, 0 ) ); } private void addThing( int frameNum, Thing thing, String soundEffectOverride, List<Sprite> ret ) { Frame frame = frameForThing( frameNum, thing ); String bitmapName = null; int offsetX = 0; int offsetY = 0; if ( frame != null ) { bitmapName = frame.name; offsetX = frame.offsetX; offsetY = frame.offsetY; } ret.add( new Sprite( bitmapName, soundEffectForFrame( soundEffectOverride, frame ), thing.x, thing.y, offsetX, offsetY ) ); } private String soundEffectForFrame( String soundEffectOverride, Frame frame ) { if ( soundEffectOverride != null ) { return soundEffectOverride; } if ( frame != null ) { return frame.soundEffect; } return null; } private Frame frameForThing( int frameNum, Thing thing ) { if ( frameNum == -1 ) { return null; } String frameName = thing.state.name().toLowerCase( Locale.ENGLISH ); Animation animation = animationCache.get( frameName ); if ( animation == null ) { System.out.println( "Missing animation for state " + thing.state ); return null; } return animation.get( frameNum ); } private String bitmapNameForBlock( Block block ) { switch ( block.material ) { case EARTH: switch ( block.shape ) { case FLAT: return land_block[block.variant]; case UP_RIGHT: return land_rising_right[block.variant]; case UP_LEFT: return land_rising_left[block.variant]; case BRIDGE_UP_RIGHT: return bridge_rising_right; case BRIDGE_UP_LEFT: return bridge_rising_left; } break; case METAL: switch ( block.shape ) { case FLAT: return metal_block[block.variant]; default: break; } break; } throw new RuntimeException("Unknown Block type: " + block.material + " " + block.shape); } }