1.Window
Your program has precisely one window. The window has no title or any other decorations. To close the window, you can either stop the program or use keyboard shortcuts, for instance, Alt+F4 in Windows.
To create the window, you must create an object of Window class. You also should pass the width and height of the window as arguments. Example:
val wnd = Window(1027, 768)
2.Drawing
2.1.Turtle
Detailed API documentation.
The easiest way to write a program drawing something on a screen is turtle graphics. I saw a five-year-old kid doing it.
You command the imaginary robot called “turtle” using very simple commands: forward, turnLeft, turnRight, backward. The turtle moves drawing line on the screen. You also can use commands: penUp and penDown to move it without drawing.
Turtle graphics was originally created as part of Logo programming language in the 1967 year and accepted as a great way to learn Programming.
Using ToyGraphics you can combine good old turtle graphics with a modern programming language (Kotlin).
If you use turtle graphics you may skip “Coordinate system” and “Graphics” in this manual.
Turtle graphics is very easy to use but has its own limitations.
If you need to write a game or use a Cartesian coordinate system you have to use Graphics class.
To use turtle graphics you have to create an object of the Turtle class passing the window as an argument. Like this:
val turtle = Turtle(wnd)
You create several turtles and move them independently.
Here are some complete examples and results on the screen:
// Draws a square. For absolute beginners. package demos.turtle import com.anysolo.toyGraphics.* fun main() { val wnd = Window(800, 600) val turtle = Turtle(wnd) turtle.forward(100) turtle.turnRight(90.0) turtle.forward(100) turtle.turnRight(90.0) turtle.forward(100) turtle.turnRight(90.0) turtle.forward(100) turtle.turnRight(90.0) }

// Draw a square spiral using a loop
package demos.turtle
import com.anysolo.toyGraphics.*
fun main() {
val wnd = Window(1024, 768)
val turtle = Turtle(wnd)
var step = 10
repeat(50) {
turtle.forward(step)
turtle.turnRight(90.0)
step += 10
}
}

2.2.Coordinate system
ToyGraphics uses the usual type of coordinate system in Computer graphics. Y-axis goes from up to down. X-axis goes from left to right. Top left corner has coordinates 0,0
Here is an article: Coordinate System of a Screen
The unit of measure is a pixel. Display resolution at Wikipedia.
You specify a point by pair of integer numbers, Int type in Kotlin. If you calculate a coordinate using floating-point arithmetics (Double type in Kotlin) then you have to use roundToInt() to round a Double number to Int. Example:
val distance = 10000.0
val screenRatio = 10.0
val x = distance/screenRatio.roundToInt()
Look at the example below and you see how it works.
package demos import com.anysolo.toyGraphics.* fun main() { val wnd = Window(800, 600) val gc = Graphics(wnd) gc.color = Pal16.red gc.drawRect(0, 0, 50, 50, fill = true) gc.color = Pal16.blue gc.setStrokeWidth(5.0) gc.drawLine(25, 0, 25, wnd.height-1) gc.color = Pal16.green gc.setStrokeWidth(5.0) gc.drawLine(0, 25, wnd.width-1, 25) }

2.3.Graphics
Detailed API documentation.
Graphics class is like a pen you use to draw on the window using a Cartesian coordinate system. Thus, you have to read the Coordinate System.
You create an object of Graphics class passing the window as an argument and use its methods to do the drawing. Here is an example:
import com.anysolo.toyGraphics.* fun main() { val wnd = Window(500, 500) val gc = Graphics(wnd) gc.drawRect(50, 50, 100, 50) gc.color = Pal16.red gc.setStrokeWidth(2) gc.drawLine(50, 350, 400, 450) gc.color = Pal16.blue gc.setStrokeWidth(4) gc.drawOval(350, 300, 100, 50) gc.color = Pal16.green gc.setFontSize(32) gc.drawText(150, 200, "Some text") }
Read API documentation to learn more about Graphics methods.

2.4.Game graphics.
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) } }
3.Keyboard
You can use keyboard in two modes: simple mode and event mode. Simple mode is easier so better start from it. Event mode allows you to detect not only when a user pressed a key but also when they released a key.
We start from “simple mode” and then show how to use event mode.
Simple mode.
To work with keyboard you have to create an object of Keyboard class passing the window as the argument.
val keyboard = Keyboard(wnd)
Keyboard keeps a queue from information about all pressed keys. You can get information about one key which was pressed the first by calling getPressedKey method:
val key = keyboard.getPressedKey()
After you got the key it is erased from the keyboard queue. And next call of getPressedKey returns the key which was pressed after the previous one. If the keyboard queue is empty, meaning there are not pressed keys to process, getPressedKey returns null. Here is an example showing how you can process pressed keys from the keyboard:
import com.anysolo.toyGraphics.* fun main() { val wnd = Window(800, 600) val keyboard = Keyboard(wnd) while(true) { do { val key = keyboard.getPressedKey() if (key != null) { println(key) println("key: " + key.code) } } while(key != null) sleep(1) } }
To understand why you need the inner loop “do” try to change sleep(1) to sleep(10). If you press several keys you see how they processed by that loop when 10 seconds of sleep is finished.
getPressedKey() returns an object of class Key. This object contains all information about what key was pressed and which modifiers (Ctrl, Shift, Alt) was pressed with it. The most important piece of information is “code” property. It contains an Int representing code of the key. You can compare it to one of the known codes from KeyCodes.
Here is an example waiting for Escape key to be pressed. It also shows how you can check key modifiers like shift, alt or control.
package demos import com.anysolo.toyGraphics.* fun main() { val wnd = Window(800, 600) val keyboard = Keyboard(wnd) while(true) { do { val key = keyboard.getPressedKey() if (key != null) { println(key) println("key: " + key.code) if(key.code == KeyCodes.ESCAPE) println("Escape key. Does not matter shift or not shift") if(key.code == KeyCodes.ESCAPE && key.isShift) println("Escape key + shift") if(key.code == KeyCodes.ESCAPE && !key.isShift) println("Escape key. No shift") // An empty line before output from the next loop iteration println() } } while(key != null) sleep(1) } }
KeyCodes contains only special key codes, like function keys, arrow and so on. If you want to check if some alphabetical key was pressed you can do like this example shows you:
package demos import com.anysolo.toyGraphics.* fun main() { val wnd = Window(800, 600) val keyboard = Keyboard(wnd) while(true) { do { val key = keyboard.getPressedKey() if (key != null) { println(key) println("key: " + key.code) if(key.code == 'Q'.toInt()) println("'Q' key. Does not matter Alt or not Alt") if(key.code == 'Q'.toInt() && key.isAlt) println("'Q' key + Alt") if(key.code == 'Q'.toInt() && !key.isAlt) println("'Q' key. No Alt") // An empty line before output from the next loop iteration println() } } while(key != null) sleep(1) } }
Event mode
To use the keyboard in event mode you have to pass eventMode=true parameter to Keyboard object.
val keyboard = Keyboard(wnd, eventMode=true)
Instead of calling getPressedKey() function you should call getEvent().
val keyEvent = keyboard.getEvent()
If the keyboard queue is empty it returns null.
Below is a full example of detecting pressing and releasing.
import com.anysolo.toyGraphics.* fun main() { val wnd = Window(800, 600) val keyboard = Keyboard(wnd, eventMode=true) while(true) { do { val keyEvent = keyboard.getEvent() if (keyEvent != null) { println(keyEvent) // Some key was pressed if(keyEvent.isPressed) { if (keyEvent.code == 'Q'.toInt()) break if (keyEvent.code == KeyCodes.LEFT) println("Left is pressed") if (keyEvent.code == KeyCodes.RIGHT) println("Right is pressed") if (keyEvent.code == KeyCodes.ALT) println("ALT is pressed") if (keyEvent.code == KeyCodes.SHIFT) println("SHIFT is pressed") if (keyEvent.code == KeyCodes.CTRL) println("CTRL is pressed") } else { if (keyEvent.code == KeyCodes.LEFT) println("Left is released") if (keyEvent.code == KeyCodes.RIGHT) println("Right is released") if (keyEvent.code == KeyCodes.ALT) println("ALT is released") if (keyEvent.code == KeyCodes.SHIFT) println("SHIFT is released") if (keyEvent.code == KeyCodes.CTRL) println("CTRL is released") } println() } } while(keyEvent != null) sleep(100) } }
Read API documentation to find more details about Keyboard, Key and KeyCodes classes.
4.Images
What if you need to use more complex graphics than you can easily build using Graphics class methods? In this case, you can create or find on the Internet an image file, load it into an object of Image class and draw using method Graphics.drawImage(). Here is an example:
package demos import com.anysolo.toyGraphics.* fun main() { val wnd = Window(300, 200) val gc = Graphics(wnd) val image = Image("graphicsFiles/brick-wall.jpg") gc.drawImage(50, 35, image) }

Image class Image supports PNG, JPG and GIF files.
You can draw an image rotated to any degree. Be default it will be rotated around its top left corner, but you can specify the point you want to rotate your image around. Below you can see the example wich rotates UFO image around its center.
package com.anysolo.toyGraphics.samples import com.anysolo.toyGraphics.* fun main() { val wnd = Window(300, 300, background = Pal16.black, buffered = true) val image = Image("graphicsFiles/ufo-small.png") val x = wnd.width/2 - image.width/2 val y = wnd.height/2 - image.height/2 val maxAngle = Math.PI*2 var angle = 0.0 while(true) { Graphics(wnd).use {g -> g.clear() val anchorx = x + image.width/2 val anchory = y + image.height/2 g.drawImage(x, y, image, angle, anchorx, anchory) angle += maxAngle/360 if(angle > maxAngle) angle = 0.0 sleep(20) } } }
.