package rabbitescape.render.gameloop;
import java.util.ArrayList;
import java.util.List;
import static rabbitescape.engine.CellularDirection.*;
import rabbitescape.engine.WaterRegion;
import rabbitescape.engine.World;
import rabbitescape.engine.util.CellDebugPrint;
import rabbitescape.engine.util.Dimension;
import rabbitescape.engine.util.LookupTable2D;
import rabbitescape.render.PolygonBuilder;
import rabbitescape.render.WaterRegionRenderer;
/**
* Manages animation of polygons for water.
*/
public class WaterAnimation
{
public final LookupTable2D<WaterRegionRenderer> lookupRenderer;
private int lastFramenumber = 10;
public final Dimension worldSize;
public WaterAnimation( World world )
{
worldSize = world.size;
lookupRenderer = new LookupTable2D<WaterRegionRenderer>( worldSize );
}
private WaterAnimation()
{
lookupRenderer = null;
worldSize = null;
}
public static WaterAnimation getDummyWaterAnimation()
{
return new WaterAnimation();
}
/**
* Animation step update. Several may have passed before this is called.
*/
public void update( int frameNumber )
{
if ( null == lookupRenderer )
{
return;
}
int interval = frameNumber - lastFramenumber;
interval = ( interval < 0 ) ? ( interval + 10 ) : ( interval );
lastFramenumber = frameNumber;
for ( int i = 0 ; i < interval ; i++ )
{
for( WaterRegionRenderer wrr: lookupRenderer )
{
wrr.setWaterHeight();
}
for( WaterRegionRenderer wrr: lookupRenderer )
{
wrr.removeHeightGaps();
}
}
}
public List<PolygonBuilder> calculatePolygons()
{
ArrayList<PolygonBuilder> polygons = new ArrayList<PolygonBuilder>();
for ( int y = 0; y < worldSize.height ; y++ )
{
PolygonBuilder p = new PolygonBuilder();
WaterRegionRenderer start = null;
for ( int x = 0; x < worldSize.width; x++ )
{
WaterRegionRenderer wrr = lookupRenderer.getItemAt( x, y );
if ( null == wrr || wrr.adjacentWaterIsFalling( HERE ) )
{
continue;
}
p.add( wrr.topVertex( LEFT ) );
if ( null == start )
{
start = wrr;
}
if ( !wrr.region.isConnected( RIGHT ) || wrr.adjacentIsNull( RIGHT ) || wrr.adjacentWaterIsFalling( RIGHT ) )
{
p.add( wrr.topVertex( RIGHT ) );
p.add( wrr.bottomVertex( RIGHT ) );
p.add( start.bottomVertex( LEFT ) );
start = null;
polygons.add( p );
p = new PolygonBuilder();
}
}
}
return polygons;
}
/**
* Game step. Usually ten animation steps per game step.
*/
public void step( World world )
{
if ( null == world || null == lookupRenderer )
{
return;
}
List<WaterRegionRenderer> currentRR = lookupRenderer.getListCopy();
for ( WaterRegion w: world.waterTable )
{
if ( w.getContents() == 0 )
{ // Empty regions do not need renderers.
continue;
}
WaterRegionRenderer r = lookupRenderer.getItemAt( w.x, w.y );
if ( null == r)
{ // Create renderer for region that does not have one
lookupRenderer.add( new WaterRegionRenderer( w, world, this ) );
}
else
{ // Remove renderers that are being used from temporary list.
currentRR.remove( r );
}
}
// Remove renderers that no longer have regions
lookupRenderer.removeAll( currentRR );
for( WaterRegionRenderer wrr: lookupRenderer )
{
wrr.setTargetWaterHeight();
}
}
public void debugPrint()
{
CellDebugPrint p = new CellDebugPrint();
for ( WaterRegionRenderer wrr: lookupRenderer )
{
wrr.debugCellPrint( p );
}
p.print();
}
}