Now we are going to learn how to draw graphics when you are writing a game with some moving objects, like a Tenis, Arcanoid or Lode runner.

In such games, you have to redraw the window many times per second. One update of the window called “frame”. Frames per second or FPS means how many times you redraw the window during one second. Like with movies when you look at the game working with FPS >= 25 you see smooth motion.

There is a catch. If you try something straightforward like the example bellow you see annoying flickering.

// Flying object with flickering
// A wrong way to draw moving objects!

package demos
import com.anysolo.toyGraphics.*

fun main() {
    val wnd = Window(1920, 1080)
    val gc = Graphics(wnd)

    val objectSize = 50
    val y = wnd.height / 2 - objectSize/2
    var x = 0

    while(true) {
        gc.clear()
        gc.setStrokeWidth(6)
        gc.drawRect(x, y, objectSize, objectSize)

        x = if(x < wnd.width) x + 1 else 0
        sleep(5)
    }
}

To get rid of flickering you have to use the buffered mode of the window. When the window is in the buffered mode you do not drow directly on the window. Instead, you draw on the memory buffer. Then when you call close() method of Graphics class the memory buffer rendered on the window. The example below works without flickering.

// Flying object without flickering

package demos
import com.anysolo.toyGraphics.*

fun main() {
    val wnd = Window(1920, 1080, buffered = true)

    val objectSize = 50
    val y = wnd.height / 2 - objectSize/2
    var x = 0

    while(true) {
        // Start drawing into the buffer
        val gc = Graphics(wnd)

        gc.clear()
        gc.setStrokeWidth(6)
        gc.drawRect(x, y, objectSize, objectSize)

        // End the drawing and by closing Graphics
        gc.close()

        x = if(x < wnd.width) x + 1 else 0
        sleep(5)
    }
} 

Here is a better version using Kotlin use function instead of calling close() directly.

/* Flying a square using buffered window */

package demos
import com.anysolo.toyGraphics.*

fun main() {
    val wnd = Window(1920, 1080, buffered = true)

    val objectSize = 50
    val y = wnd.height / 2 - objectSize/2
    var x = 0

    while(true) {
        Graphics(wnd).use { gc ->
            gc.clear()
            gc.setStrokeWidth(6)
            gc.drawRect(x, y, objectSize, objectSize)
        }

        x = if(x < wnd.width) x + 1 else 0
        sleep(5)
    }
}