Procházet zdrojové kódy

more stable game tick, bugfixes

Kajetan Johannes Hammerle před 4 roky
rodič
revize
2b198a9157

+ 34 - 13
manifest.mf

@@ -2,35 +2,56 @@ package me.hammerle.snuviengine;
 
 import me.hammerle.snuviengine.api.Engine;
 import me.hammerle.snuviengine.api.IGame;
-import me.hammerle.snuviengine.api.KeyBinding;
-import me.hammerle.snuviengine.api.KeyHandler;
 import me.hammerle.snuviengine.api.Renderer;
-import static org.lwjgl.glfw.GLFW.*;
 
 public class Game implements IGame
 {
-    public final static KeyBinding UP = KeyHandler.register(GLFW_KEY_UP);
-    public final static KeyBinding DOWN = KeyHandler.register(GLFW_KEY_DOWN);
-    public final static KeyBinding LEFT = KeyHandler.register(GLFW_KEY_LEFT);
-    public final static KeyBinding RIGHT = KeyHandler.register(GLFW_KEY_RIGHT);
+    private float oldX = 0;
+    private float oldY = 0;
+    private float x = 0;
+    private float y = 0;
     
-    public Game()
-    {
-    }
+    private float power = 10;
+    private final float size = 20;
 
     @Override
     public void tick()
     {        
-       
+        oldX = x;
+        oldY = y;
+        
+        x += power;
+        y += power;
+        
+        if(y > 300 || y < 0)
+        {
+            power = -power;
+        }
     }
     
     @Override
     public void renderTick(Renderer r, float lag)
     { 
-        float y = 30;
+        r.setMixColorEnabled(false);
+     
+        r.translateTo(0.0f, 0.0f);
+        r.updateMatrix();
+        
+        //lag = 0;
+        float ix = oldX + (x - oldX) * lag;
+        float iy = oldY + (y - oldY) * lag;
+        
+        r.setTextureEnabled(false);
+        r.getColorRenderer().drawRectangle(ix, iy, ix + size, iy + size, 0xFF0000FF);
+        
+        
+        float y = 200;
         r.setColorEnabled(true);
         r.setTextureEnabled(true);
-        y = r.getFontRenderer().drawString(30, y, true, String.format("FPS %.1f", Engine.getFramesPerSecond()));
+        y = r.getFontRenderer().drawString(30, y, true, String.format("FPS: %.1f", Engine.getFramesPerSecond()));
+        y = r.getFontRenderer().drawString(30, y, true, String.format("Nanos Per Tick: %d", Engine.getNanosPerTick()));
+        y = r.getFontRenderer().drawString(30, y, true, String.format("TPS: %.1f", Engine.getTicksPerSecond()));
+        y = r.getFontRenderer().drawString(30, y, true, String.format("Lag: %.1f", lag));
     }
 
     @Override

+ 1 - 0
src/me/hammerle/snuviengine/Main.java

@@ -10,6 +10,7 @@ public class Main
         
         Engine.setNanosPerTick(50_000_000);
         Engine.setMaxFramesPerSecond(60);
+        Engine.setRenderTicksPerSecond(true);
         
         Game game = new Game();
         Engine.start(game);

+ 56 - 45
src/me/hammerle/snuviengine/api/Engine.java

@@ -11,10 +11,9 @@ public class Engine
 {
     private static long window;
     
-    private static long fpsLimit = -1;
-    private static long sleep = 0;
     private static long nanosPerTick = 10_000_000;
     private static final int MAX_TICKS_PER_FRAME = 20;
+    private static long nanosPerFrame = 1000000000l / 60l;
     
     private static Timer fpsTimer;
     private static Timer tpsTimer;
@@ -102,16 +101,9 @@ public class Engine
     {
         if(nanos < 0)
         {
-            sleep += nanos;
             return;
         }
         
-        if(sleep < 0)
-        {
-            sleep += nanos / 4;
-            nanos = (nanos * 3) / 4;
-        }
-        
         long end = System.nanoTime() + nanos - 10000;
         try
         {
@@ -129,52 +121,71 @@ public class Engine
 
     private static void loop(IGame game)
     {
-        fpsTimer.update();
-        tpsTimer.update();
+        long newTime = glfwGetTimerValue();
+        long oldTime;
         long lag = 0;
-        
+        long frameLag = 0;
+        long lastFrame = 0;
+
         while(!glfwWindowShouldClose(window))
         {
-            glfwSwapBuffers(window);
-            
-            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-            
-            if(fpsLimit > 0)
-            {
-                sleep(fpsLimit - fpsTimer.getCurrentTime());
-            }
-            fpsTimer.update();
-            lag += fpsTimer.getTime();
+            oldTime = newTime;
+            newTime = glfwGetTimerValue();
+            lag += newTime - oldTime;
+            frameLag += newTime - oldTime;
 
-            int ticksPerFrame = 0;
-            while(lag >= nanosPerTick)
+            if(lag >= nanosPerTick || frameLag >= nanosPerFrame)
             {
-                lag -= nanosPerTick;
-                
-                tpsTimer.update();
-                
-                KeyHandler.tick();
-                game.tick();
+                int ticksPerFrame = 0;
+                while(lag >= nanosPerTick)
+                {
+                    lag -= nanosPerTick;
+
+                    tpsTimer.update();
+                    KeyHandler.tick();
+                    game.tick();
                 
-                ticksPerFrame++;
-                if(ticksPerFrame >= MAX_TICKS_PER_FRAME)
+                    ticksPerFrame++;  
+
+                    if(ticksPerFrame >= MAX_TICKS_PER_FRAME)
+                    {
+                        long skip = lag / nanosPerTick;
+                        lag -= skip * nanosPerTick;
+                        if(skip > 0)
+                        {
+                            System.out.println("skipped " + skip + " game ticks " + lag);
+                        }
+                        break;
+                    }
+                }
+
+                if(frameLag >= nanosPerFrame)
                 {
-                    long skip = lag / nanosPerTick;
-                    lag -= skip * nanosPerTick;
-                    if(skip > 0)
+                    frameLag -= nanosPerFrame;
+                    // make sure no frames are rendered immediately after each other
+                    // this happens if the game tick takes too long
+                    if(lastFrame + nanosPerFrame - 1000000 < glfwGetTimerValue())
                     {
-                        System.out.println("skipped " + skip + " game ticks " + lag);
+                        lastFrame = glfwGetTimerValue();
+
+                        game.renderTick(renderer, (float) lag / nanosPerTick);
+                        tpsTimer.draw(renderer);
+                        fpsTimer.draw(renderer);
+                        fpsTimer.update();   
+                        
+                        glfwSwapBuffers(window);
+                        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                     }
-                    break;
                 }
-            }
-            
-            game.renderTick(renderer, (float) lag / nanosPerTick);
-            
-            tpsTimer.draw(renderer);
-            fpsTimer.draw(renderer);
 
-            glfwPollEvents();
+                glfwPollEvents();
+            }
+            else
+            {
+                // wait until next frame
+                long waitingTime = Math.min(nanosPerFrame - frameLag, nanosPerTick - lag);
+                sleep(waitingTime);
+            }
         }
         game.onStop();
     }
@@ -207,7 +218,7 @@ public class Engine
     
     public static void setMaxFramesPerSecond(int max)
     {
-        fpsLimit = 1_000_000_000 / max;
+        nanosPerFrame = 1_000_000_000 / max;
     }
     
     public static void setRenderFramesPerSecond(boolean active)

+ 11 - 1
src/me/hammerle/snuviengine/api/FontRenderer.java

@@ -222,6 +222,7 @@ public class FontRenderer
     
     public Rectangle getSize(String s)
     {
+        int longestLine = 0;
         int length = 0;
         int counter = 1;
         for(int i = 0; i < s.length(); i++)
@@ -230,6 +231,11 @@ public class FontRenderer
             {
                 case '\n':
                     counter++;
+                    if(length > longestLine)
+                    {
+                        longestLine = length;
+                    }
+                    length = 0;
                     break;
                 case COLOR_CHAR:
                     i++;
@@ -238,7 +244,11 @@ public class FontRenderer
                     length++;
             }
         }
-        return new Rectangle(FONT_SIZE * length, (FONT_SIZE + LINE_STEP) * counter);
+        if(length > longestLine)
+        {
+            longestLine = length;
+        }
+        return new Rectangle(FONT_SIZE * longestLine, (FONT_SIZE + LINE_STEP) * counter);
     }
     
     public Rectangle getSize(int w, int h)

+ 1 - 0
src/me/hammerle/snuviengine/api/TextureRenderer.java

@@ -91,6 +91,7 @@ public class TextureRenderer
     public void clear()
     {
         triangles = 0;
+        buffer.clear();
         built = false;
     }