package rabbitescape.render.gameloop; import java.io.PrintStream; import rabbitescape.engine.Rabbit; import rabbitescape.engine.config.Config; import rabbitescape.engine.config.ConfigKeys; import rabbitescape.engine.config.ConfigTools; public class GameLoop { private static final long frame_time_ms = 70; private final Input input; private final Physics physics; private final Graphics graphics; private final WaterAnimation water; private boolean running; private long simulation_time; private long frame_start_time; private final Config config; private final PrintStream debugout; public GameLoop( Input input, Physics physics, WaterAnimation water, Graphics graphics, Config config, PrintStream debugout ) { this.input = input; this.physics = physics; this.water = water; this.graphics = graphics; this.config = config; this.debugout = debugout; this.running = true; simulation_time = -1; frame_start_time = -1; } public void run() { resetClock(); while( running ) { running = step(); printDebugOutput(); } input.dispose(); physics.dispose(); graphics.dispose(); } public void resetClock() { simulation_time = input.timeNow(); frame_start_time = simulation_time; } public boolean step() { input.waitMs( 0 ); // Check for interruptions or input simulation_time = physics.step( simulation_time, frame_start_time ); water.update( physics.frameNumber() ); graphics.draw( physics.frameNumber() ); frame_start_time = waitForNextFrame( frame_start_time ); if ( !physics.gameRunning() ) { pause(); resetClock(); } return physics.gameRunning() && running; } public void pleaseStop() { running = false; } public boolean isRunning() { return running; } private void pause() { graphics.rememberScrollPos(); while ( !physics.gameRunning() && running ) { input.waitMs( 100 ); graphics.drawIfScrolled( physics.frameNumber() ); } } private long waitForNextFrame( long frame_start_time ) { long how_long_we_took = input.timeNow() - frame_start_time; long wait_time = frame_time_ms - how_long_we_took; input.waitMs( wait_time ); return input.timeNow(); } private void printDebugOutput() { if ( physics.frameNumber() != 0 ) { // only want this once per world step, not once per anim frame return; } if ( ConfigTools.getBool( config, ConfigKeys.CFG_DEBUG_PRINT_STATES ) ) { for ( Rabbit rabbit : physics.world().rabbits ) { debugout.println( " " + rabbit.toString() + ":" + rabbit.state.name() + " onSlope:" + rabbit.onSlope ); } } } }