public void run()
	{
		int ticks=0;
		int frames=0;
		long start;
		long time;
		long end=System.nanoTime();
		long nextdraw=0;
		final long NSPT=NANOSECOND/this.ticksPerSecond;
		long endSecond=System.currentTimeMillis()+MILLISECOND;
		
		long ticktime=0;
		long drawtime=0;
		
		long avgDrawTime=0;
		boolean useAvgDrawTime=false;
		long avgTickTime=0;
		boolean useAvgTickTime=false;
		

		//try
		while(!isKilled())
		{
			while(running())
			{
				if(System.nanoTime()>=end)
				{
					start=System.nanoTime();
					engine().tick();
					ticks++;
					ticktime=System.nanoTime()-start;
					avgTickTime=(long)((avgTickTime*(ticks-1)+ticktime)*1.0/ticks+0.5);
					end=System.nanoTime()+(NSPT-ticktime);
				}
				
				if(System.nanoTime()+(useAvgDrawTime?avgDrawTime:0)<end-(useAvgTickTime?avgTickTime:0)||System.nanoTime()>nextdraw)
				{
					frames++;
					start=System.nanoTime();
					engine().redraw();
					drawtime=System.nanoTime()-start;
					avgDrawTime=(long)((avgDrawTime*(frames-1)+drawtime)*1.0/frames+0.5);
					nextdraw=System.nanoTime()+NANOSECOND/20;
				}
					
				/*while(System.nanoTime()<end)
				{
					Thread.yield();
				}*/
				
				if(System.currentTimeMillis()>=endSecond)
				{
					totalTicks=ticks;
					totalFrames=frames;
					ticks=0;
					frames=0;
					useAvgDrawTime=true;
					useAvgTickTime=true;
					//System.out.println("avgTickTime: "+avgTickTime*1.0/NANOSECOND);
					//System.out.println("avgDrawTime: "+avgDrawTime*1.0/NANOSECOND);
					endSecond=System.currentTimeMillis()+MILLISECOND;
				}
			}
		}
		/*catch(InterruptedException e)
		{
			e.printStackTrace();
			running=false;
		}*/
	}