private void gameLoop() {
        final double TIME_BETWEEN_UPDATES = 1000 / UPDATES_PER_SECOND;
        final int MAX_UPDATES_BEFORE_RENDER = 5;
        double lastUpdateTime = System.currentTimeMillis();
        double lastRenderTime;

        final double TARGET_FPS = 60;
        final double TARGET_TIME_BETWEEN_RENDERS = 1000 / TARGET_FPS;

        int lastSecondTime = (int) (lastUpdateTime / 1000);

        while (isRunning) {
            double now = System.currentTimeMillis();
            int updateCount = 0;

            if (!isPaused) {
                while (now - lastUpdateTime > TIME_BETWEEN_UPDATES && updateCount < MAX_UPDATES_BEFORE_RENDER) {
                    updateGame(now - lastUpdateTime);
                    lastUpdateTime += TIME_BETWEEN_UPDATES;
                    updateCount++;
                }

                if (now - lastUpdateTime > TIME_BETWEEN_UPDATES) {
                    lastUpdateTime = now - TIME_BETWEEN_UPDATES;
                }

                repaint();
                lastRenderTime = now;

                int thisSecond = (int) (lastUpdateTime / 1000);
                if (thisSecond > lastSecondTime) {
                    //System.out.println("NEW SECOND " + thisSecond + " " + frameCount);
                    //fps = frameCount;
                    //frameCount = 0;
                    lastSecondTime = thisSecond;
                }
                while (now - lastRenderTime < TARGET_TIME_BETWEEN_RENDERS && now - lastUpdateTime < TIME_BETWEEN_UPDATES) {
                    Thread.yield();
                    try {
                        Thread.sleep(1);
                    } catch (Exception e) {
                    }
                    now = System.currentTimeMillis();
                }
            }
        }
    }