Tic Tac Toe

Tic Tac Toe

Tic Tac Toe was a famous game long before the first computers appeared, it was expected to see it become one of the first game computerized.

For example OXO, an adaptation of the game was built in 1952, it appear to be one of the first video game ever made on computer.

The game is for two players, X and O, who take turns marking the spaces in a 3×3 grid. The player who succeeds in placing three of their marks in a horizontal, vertical, or diagonal row wins the game.

Disk (and souce code) :

oxo.disk.png (image png file to save and load directly in DiskOS) -not implemented yet

oxo.disk : link: http:// github (disk file) oxo.lua : link: http:// github (code source only)

Manual :

oxo_manual.pdf

Box cover (Front & Back) :

oxo_box_cover.jpg

1: Preparing our tools

Description:

Starting to build a game, we need to have a plan about how we will proceed, ce can describe all the features of the Tic Tac Toe game as follow. *

  • A board of 3 x 3 squares is displayed.

  • A cursor that point to the square to be marked with a O or X symbol.

  • Moving the cursor with the mouse hovering or the keyboard arrows.

  • Alternatively, player O and player X can mark a square with their symbol.

  • If three symbols are aligned then the game is won else it is a draw.

Code:

In liko-12, we can create a new file with the command new open the editor with the escape key to write the following code.

--TIC TAC TOE - JANUARY 1977 - 101 MAGAZINE

-- 2
function _init()
   color(8)
   print("Hello,World!",10,10)
end

And save a new file tictactoe.lk12 (tictactoe.disk).

Result:

From here we can use the command run to start the game, nothing should happen for now. (Escape key to leave the game loop.)

Steps:

  1. Create a new file and open the editor and write the title of the game as a comment.

  2. We add the title as a comment and add the function _init() which load first when we start the game.

  3. We choose a white color (8) with the function color() and use print(text, x, y) with x and y as coordinate of the screen.

  4. Save the new file.

Infos:

Notes: It take time and experience to be able to build a game design document, in the beginning we generally have vaguely an idea of the different features we need (a paddle moving, a mouse clicking an object, a score system) but often what happen is that we find an idea in the middle of the development and try to add it in our program. This programming improvisation can bring inexpected problems and bugs. Even if it appear less interesting than programming the game directly, having a global idea wrote down pointing where the game going can save lot of troubles later.

2: Initializing and drawing the game board

Description:

There is many way to start programming a game, we generally start by initializing the first datas we will need later in the program. That mean we save important values in variables (or sometimes when the value is not supposed to change we call it a constant) and give them meaningful names.*

We also can start to draw something right in the beginning, because for many persons, having a visual understanding of what happening is important. It help to go back and forth between the game logic and graphics. In particular in game development where the experience is both visual (video) and interactive (game). (it is also an auditory experience but we won't go there yet)

We could focus only on logic and wait the end to draw the game but the programming make generally more sense when we add a graphical element aswell as we add game logic. It is how we will proceed here, adding one logical layer and one graphical layer step by step alternatively until completion of the game.

Code:

--[...]

-- game datas

-- 1
function _init()

    -- 2
    board = {
        x = 192/2 - 90/2,
        y = 10,
        width = 90,
        height = 90
    }

    -- 10
    updateBoard = true
end

-- drawing functions

-- 3
function draw_board()

    -- 4
    clear(2)
    color(8)

    -- 5
    for i=0, board.height, board.height/3 do
        line(board.x - 1, board.y + i, board.x + board.width, board.y + i)
    end

    -- 6
    for i=0, board.width, board.width/3 do
        line(board.x + i, board.y , board.x + i, board.y + board.height)
    end
end

-- 7
function draw()
    draw_board()
end

-- game functions

-- 8
function _update(dt)

    -- 9
    if updateBoard then
        draw()
        updateBoard = false
    end
end

Result:

The board is drawn once when the game start. (command run)

Steps:

  1. We use the _init() function that start once we run the game (and we delete the previous introduction print code).

  2. We add a table variable board with the data concerning the game board measures. To get the x, the left coordinate of the board, we go from the middle of the screen (192/2) and we substract by half the size of the board (90/2).

  3. We then create a new function draw_board() that will be called when there is the need to draw the board game.

  4. We clear the screen with the color dark blue clear(2) and choose the color white (color(8)) before to draw the lines of the board.

  5. To draw the four horizontal lines, we loop four time by moving the index i to 1/3 of the board height, the first line is at 0 of the height, the fourth line is at 3/3 (or 1) of the height and are applied to the y coordinate of the line.

  6. To draw the four vertical lines, we do the same than step 5 but instead the index move on the width of the board and is applied to x.

  7. We then add the function draw_board() to a main function draw() that will contain all the drawing function call.

  8. We add the _update(dt) function that is essentially the main game loop.

  9. We don't need to call the drawing function every frame of the loop, only when there is a change. To say to the game there have been a change and it is now time to update the drawing we will use a flag variable, updateBoard, when true, the drawing functions are called.

  10. We add the flag variable set true to the end of the _init() function to call it once the game start. (Will draw once because updateBoard is true and then the updateBoard is switched to false so the update game loop ignore the draw function call)

Infos:

Notes: Giving a meaningful name to a variable is not important for the computer but much valuable for an human who read the code afterward (even the original author can forget what he meant then), it give an easiest way to understand how the program behave by a simple reading, for example, a variable velocity will be easier to grasp quickly than the letter v or a random variable name like e1e_T.

3: Defining squares and positions

Description:

Before to go further with the game display, we first need to clearly define in our game the different squares the player can play. We also need a way to save the game status, what the players have played and on which square. The first give us the limits of each square on the board axis that we will need to select the square to play, the second give a global overview of the game that we use to check the progress of the game and reach to a conclusion.

Code:

-- [...]

-- game datas

function _init()

    -- 1    
    squares = {}
    positions = {}

    -- 2
    set_squares()
end

-- setting functions

-- 2
function set_squares()

    -- 3
    squares.width = board.width/3
    squares.height = board.height/3

    -- 4
    id = 1

    -- 5
    for i = 0, 1, 1/3 do
        for j = 0, 1, 1/3 do

            -- 6
            if j < 1 and i < 1 then

                -- 7
                squares[id] = {x, y}

                -- 8
                squares[id].x = board.x + board.width * j
                squares[id].y = board.y + board.height * i

                -- 9
                positions[id] = ""

                -- 10
                id = id + 1
            end
        end
    end
end


-- [...]

Result:

Each square have an id number from 1 to 9, the square top left has an id of 1, the square down right has an id of 9. Each square are created and added to the table squares. Each square are also indexed by their id in the table positions and each are set to a default empty string "". When selected later, a square position will change to either "X" or "O" by using positions[id of the square].

Steps:

  1. We add in the _init() function the variables squares and positions with an empty table. These will contain the squares datas.

  2. We create a fucntion set_squares() and call it from the function _init() to be called once when the game start.

  3. One square is one third of the height of the board and one third of the width of the board, it is how we add to the table squares their width and height.

  4. We are going to loop nine time to create nine squares, each loop we will give an id from 1 to 9, we use for this index starting at 1 and incrementing by at 1 each loop. (see step 10)

  5. We doing now what is called a nested loop, the purpose of it is to build a grid of coordinate x/y, to do so we need to loop 3 times for x, and for each x loop, loop 3 times for y. We loop from 0 to 1 with a step of 1/3. We then have the value, 0, 1/3 and 2/3 for x, and 0, 1/3, 2/3 for y, we then can apply them to the height and width to get the 9 coordinates x,y up left of the 9 squares on the board.

  6. In fact, we loop 4x4 times because the loops take also the finale value of 3/3 = 1, but we don't want to create a square for this last value, so the trick here is to check if both loop values are less than 1 to create a new square.

  7. Each loop, we initialize a new square with the current id index and x and y variable in the table squares.

  8. x and y variables of the square current id index are given the value of the left x coordinate or top y coordinate of the board plus a portion of the board height of width.

  9. We then give to the square of current id index the default empty position with an empty string "" (no "X" or "O" on the square yet)

  10. And finally we increment the id index before the loop to end and restart to create the new square.

Infos:

4: Drawing the selection cursor

Description:

Now we have defined each square on our board, we can now create a cursor that will move on each square when we use the mouse or the keyboard.

The first step before to code is to open the sprite editor (Escape key and Icon top right) and create an arrow like on the image below. This arrow sprite must be on the first sprite (top left) of the spritesheet to have the id of 001.

Code:

-- [...]
-- game datas
function _init()
    -- [...]

    -- 1
    cursor = 1
end

-- drawing functions

-- 2
function draw_cursor()

    -- 3
    for id, square in pairs(squares) do
        if id == cursor then

            -- 4
            color(10)
            rect(square.x + (squares.width / 2) - 2, square.y - 2, 4, 4)
            Sprite(1, square.x + (squares.width / 2) - 4, square.y + 2)
        end
    end
end

-- 5
function draw()
    -- [...]
    draw_cursor()
end

-- [...]

Result:

A cursor is displayed on the current selected square. It will stay at 1 by default, after we will update the cursor position with mouse and keyboard input but for now it is possible to test the cursor on others squares by modifying manually the variable cursor (1 to 9) in the _init() function.

Steps:

  1. We add a variable cursor in the _init() function that will be the indicator of the selected square.

  2. We create a function draw_cursor() to update the cursor drawing when called.

  3. We loop through the squares table and check which square id is equal the the cursor position. (see infos)

  4. From this square x and y coordinates, we set the orange color color(10), draw a little rectangle rect(...) and add the Sprite(1,...) to draw an orange cursor to the top of the square.

  5. Finally we add the draw_cursor() function to the main function draw().

Infos:

In lua, we can use a table like an array (value with an index position) or like a map or dictionnary (with a key=value struture). To loop through a table with lua we can use the two functions pairs(table) or ipairs(table), the main difference between both is that using ipairs() will loop through an iterator (from 1) and ignore datas with a key. And pairs() is more adapted to return all the table datas in the form of key and value, and for datas without a key return an index position as a key.

t = {key='one', 20, [5]=1, 10, 30, [0]=2, 40}

for i,v in ipairs(t) do print(i,v) end
--[[
1    20
2    10
3    30
4    40
5    1
]]

for i,v in pairs(t) do print(i,v) end
--[[
1    20
2    10
3    30
4    40
0    2
5    1
key    one
]]

5:Using the mouse and keyboard inputs

Description:

At this point we want to be able to select a square with the mouse or the keyboard. What we need in the first case is a way to check what is the mouse position and compare it with the different position of the squares. In the second case with want to update the cursor position with the keyboard arrows.

Code:

--[...]

-- 1
function _init()
    winner = false
    --[...]
end

-- input functions

-- 2
function _mmove(x,y)

    -- 3
    if not winner then

        -- 4
        mouse_cursor(x, y)
    end
end

-- 4
function mouse_cursor(x, y)

    -- 5
    for id, square in ipairs(squares) do

        -- 6
        if x >= square.x and x <= square.x + squares.width
        and y >= square.y and y <= square.y + squares.height
        then

            -- 7
            cursor = id
            updateBoard = true
        end
    end
end


-- 8
function _kpress(key)

    -- 9
    if not winner then
        keyboard_cursor(key)
    end
end

-- 9
function keyboard_cursor(k)

    -- 10
    if k == "left" and cursor > 1 then
        cursor = cursor - 1
    elseif k == "right" and cursor < 9 then
        cursor = cursor + 1
    elseif k == "up" and cursor > 3 then
        cursor = cursor - 3
    elseif k == "down" and cursor < 7 then
        cursor = cursor + 3
    end

    -- 11
    updateBoard = true
end

--[...]

Result:

We can now move the cursor with the keyboard up, left, down and rigth or by simply hovering the squares with the mouse cursor. The square cursor is automatically updated with both inputs.

Steps:

  1. First we add a flag variable winner in the _init() function set to false, it will be useful to check after if the game is running (false, no winner) or not. And give different controls to the player depending the status of this flag.

  2. We add the _mmove(x, y) function which is the default function (an event listener) that is called each time the mouse is moving with x and y as the current position of the mouse cursor.

  3. We want to check if the game is running (if winner not false) to update the board cursor position.

  4. We create a new function called mouse_cursor() that will be used to check the position of the mouse cursor with the different squares of the board, we call the function from the _mmove() function passing the parameter x and y.

  5. We loop through the squares table, using the ipairs() to loop only through an iterator. (careful not to use pairs() to avoid height and width in the table, only loop square)

  6. We check if the x and y coordinates of the mouse cursor are hold inside one of the square four coordinates.

  7. When we find a square that match, we set the board cursor to the id of the square and set the flag updateBoard to true to call to redraw the game.

  8. We add the _kpress() function which is the default function (also an event listener) that is called each time a key from the keyboard is pressed (with the key parameter as which key have been pressed).

  9. We create a new function keyboad_cursor() that will check which key of the keyboad is pressed only if the game have no winner. (if winner not false)

  10. If the key is left or right, we simply move the cursor forward or backward if the limit of the square are not crossed (1 - 9), in the case of up and down arrow key, we jump by 3 cases (which is the lenght of a board row) and check to not go out of the limits board limit (3 - 7).

  11. We then set the flag updateBoard to true to update the game drawing.

Infos:

With Liko-12 (DiskOS) the differents input function are event listener that are called when the related input is used, here the different functions:

  • _mpress(...): This function is called when a mouse button is pressed.

  • _mmove(...) This function is called whenever the mouse gets moved.

  • _mrelease(...) This function is called when a mouse button is released.

  • _tpress(...) This function is called when the screen is touched.

  • _tmove(...) This function is called when a screen touch is moved.

  • _trelease(...) This function is called when a screen touch is released.

  • _kpress(...) This function is called when a keyboard key is pressed.

  • _krelease(...) This function is called when a keyboard key is released.

6: Inputs playing on the board

Description:

We have seen how to use mouse and keyboard to move on the board, what we want to do now is to actually play when the mouse is clicked or a specific keyboard key is pressed.

Code:

--[...]

-- game datas

-- 1
function _init()
    turn = "O"
--[...]
end

--[...]  

-- input functions

-- 2
function _mpress(x,y,b)
    if b == 1 and not winner then mouse_play(x,y) end
end

-- 3
function mouse_play(x,y)

    -- 4
    for id, square in ipairs(squares) do

        -- 5
        if x >= square.x and x <= square.x + squares.width
        and y >= square.y and y <= square.y + squares.height
        and positions[id] == ""
        then

            -- 6
            positions[id] = turn
            updateBoard = true

            -- 7
            winner = check_board()
            if not winner then
                end_turn()
            end
        end
    end
end

--[...]

function keyboard_cursor(k)
    --[...]

    -- 8
    if k == "x" or k =="c" or k == "v" then
        keyboard_play()
    end
end

-- 9
function keyboard_play()

    if positions[cursor] == "" then
        positions[cursor] = turn

        -- 10
        winner = check_board()
        if not winner then
            end_turn()
        end
    end
end
--[...]

Result:

Because the functions check_board() and end_turn() have not been defined yet, the game will crash when the inputs are used. The next section (7: checking the board and go to next turn) must be completed to have the program not returning an error.

Steps:

  1. We first add a variable turn to the _init() function that will keep track of which turn it is, "O" or "X". We set turn in the beginning with "O", which will be the first to play.

  2. We use the _mmpress() function to trigger when a mouse button is clicked, from there we check if the button left is clicked (if b == 1) and if the game have no winner, then we pass the x and y coordinates of the mouse to the function mouse_play.

  3. We create the function mouse_play() that is called when the mouse button is clicked.

  4. We loop through each square of the squares table with the ipairs() function.

  5. Before to play on the square we need to check which square the mouse click (check coordinates like with the mouse_cursor() function seen before) and if the square is not already a occupied position (must have an empty string "").

  6. If the check pass, we give to the position of the square the value of the current turn, "O" or "X" and we set the flag updateBoard to true to update the game drawing.

  7. We call the function check_board() that will return false or true and give it to the variable winner. If the winner flag is true, the game is finished and then the end_turn() function is called.

  8. In the keyboard_cursor() function created in the previous section, we add a new check which is to find out if the key "x", "c" or "v" are pressed. If yes, the keyboard_play function is called.

  9. We create the function keyboard_play() that will first check (similarly to step 6) if the position of the cursor is empty and if yes, will change the position with the current turn.

  10. This do the same that step 7. Also, the updateBoard = true have been already added to the keyboard_cursor() function previously so we don't need it in the keyboard_play function. (section 5, step 11)

7: checking the board and go to next turn

Description:

To complete the previous section setting the input to play on the board, we need to write an important behavior that is the board checking method, it is the moment the computer check all the possible position to win the game and conclude if the game is finished or if the player turn change and continue to play.

Code:

--[...]

-- game datas
function _init()

    -- 1
    checks = {
        {1,2,3},
        {4,5,6},
        {7,8,9},
        {1,4,7},
        {2,5,8},
        {3,6,9},
        {1,5,9},
        {3,5,7}
    }
    --[...]
end

-- setting functions

-- 2
function end_turn()
    if turn == "O" then
        turn = "X"
    else 
        turn = "O"
    end
end

--[...]

-- checking function

-- 3
function check_board()

    -- 4
    local count = 0

    -- 5
    for i, check in ipairs(checks) do
        for j, square in ipairs(check) do

            -- 6
            if positions[square] == turn then
                count = count + 1
            end
        end

        -- 7
        if count == 3 then
            return true
        end

        -- 8
        count = 0
    end

    -- 9
    for i, pos in ipairs(positions) do

        -- 10
        if pos == "" then
            count = count + 1
        end
    end

    -- 11
    if count == 0 then
        turn = ""
        return true
    else

        -- 12
        return false
    end
end

--[...]

Result:

Nothing visually new happen, but a lot happen behing the curtain to make the gameplay of the tic tac toe working. When the function check_board is called, the whole board positions are checked and the computer return a winner or change to the next turn.

Steps:

  1. We first initialize at the start of the game (function _init()) a table checks that contain all the three positions possibilities on the board that make a win. All the horizontal, vertical and diagonal position. Remember the square have id from 1 (up left) to 9 (down right).

  2. We create a function end_turn() that check what turn it is and switch to the opposite. (if turn is O then turn is X and vice versa)

  3. We create a function check_board() that will first check for a winner, then for a draw and will return false if nor winner nor draw is found.

  4. We set a local variable count that we will use for checking the positions.

  5. We first loop through all the victory position combination and for each combination we loop to the three square ids.

  6. What happen now is that we check if the square is marked with the current turn symbol ('O' or 'X') (positions[id of the square]), if yes, then we add 1 to the count.

  7. If it happen that the 3 id of the combination are marked by the same symbol, the count is equal to three, then the loop is ended and the function return true (that will be assigned to winner)

  8. If the count if less than 3, then the count is reset to 0 to be used in the next loop to check the next combination.

  9. If there is no winner found, the loop set count to 0 a last time and we can use it for a new loop, this time, all the positions.

  10. We check if the position of each square is empty (""), and if yes, add 1 to the count.

  11. Finally we check if count is equal to 0, which mean, if it's true, that there is no empty square anymore then the game is a draw and we return true to signal the game is finished.

  12. We return false only in the case there is no winner and there is still empty squares.

8: Drawing squares symbols and turn message

Description:

It is time to go back to the drawing of our game, lot is happening under the hood to make the game mechanic working but we need now to show an output to the player of what is happening when there is a square played with an input.

The player need to know two important things: 1) What is the status of the game, which turn is it to play, "O" or "X"? and 2) What is the result of one action, when I use the mouse or the keyboard, by displaying the square symbol where I want to play.

Code:

--[...]

-- drawing functions

-- 1
function draw_squares()

    for id, square in ipairs(squares) do

            -- 2
            color(1)
            rect(square.x + 1, square.y + 1, squares.width - 1, squares.height - 1)

        -- 3
        if positions[id] == "O" then
            color(13)
            circle_line(square.x + squares.width / 2, square.y + squares.height / 2, 10)

        -- 4
        elseif positions[id] == "X" then
            color(9)
            line(square.x + squares.width / 2 + 10, square.y + squares.height / 2 - 10, square.x + squares.width / 2 - 10, square.y + squares.height / 2 + 10)
            line(square.x + squares.width / 2 - 10, square.y + squares.height / 2 - 10, square.x + squares.width / 2 + 10, square.y + squares.height / 2 + 10)
        end
    end
end

-- 5
function clearMsg()
    rect(0, 110, 200, 20, 12)
end

-- 6
function draw_message()
    clearMsg()
    color(1)
    print("THIS IS THE TURN OF "..turn..".", 55, 118)
end

-- 7
function draw()
    draw_squares()
    draw_message()
    --[...]
end

--[...]

Result:

The game is now nearly complete and all the gaming display is functional.

Steps:

  1. We first create a draw_squares() function that start by looping through the square of the squares table.

  2. For each square we draw a black (color(1)) rectangle (rect()) that will serve as background.

  3. If the position of the current square is marked by the symbol O then a blue (color(13)) circle (circle_line()) is drawn to the center position of the square.

  4. If the position of the current square is marked by the symbol X then two red (color(9)) lines (line()) are drawn on the square. (The coordinates of the lines are deducted from the center)

  5. We create a function clearMsg() which draw to the bottom of the screen a green rectangle, it will serve as container for the messages and also a simple way to erase previous messages.

  6. We create a draw_message() function that start by calling the clearMsg() function, then display the current turn with the print(text, x, y) function with x and y for the coordinates where to display the text. (see notes 1 and 2)

  7. We call the two new drawing functions from the main function draw(), careful to call the draw_squares() function before the draw_cursor() to not hide the cursor behind the background.

Infos:

In the liko-12 (DiskOS) api, it is possible to draw different forms.

  • point(x, y, c)

    • Draws the given point (x,y).

  • line(x1, y1, x2, y2, c)

    • Draws line connecting the given points (x1,y1 and x2,y2)

  • circle(x, y, r, c)

    • Draws a circle at the given position (x,y) and radius (r).

  • circle_line(x, y, r, c)

    • Same as circle but draw only the outline of the circle.

  • rect(x, y, w, h, c)

    • Draws a rectangle at the given top left position (x,y), height and width (w,h).

  • rect_line(x, y, w, h, c)

    • Same as rect but draw only the outline of the rectangle.

Notes 1 : The color can be defined from the drawing function itself (parameter c above) or with the function color() called before, the print function need the color() function in any case.

Notes 2 : An operation on string that consist in combining together two values is called concatenation, with lua we use two dots ".." to concatenate two values in one string.

9: Game over and resetting the game

Description:

A game cannot be complete without a way to end it. We need to add a game over function that will act as a method to block the game when the board is finished with a winner or a draw and propose the player to play again.

Code:

--[...]

-- game datas

function _init()
    --[...]

    -- 1
    timer = 0
    time_max = 3
end

-- setting functions

-- 2
function reset_game()
    for i, pos in ipairs(positions) do
        positions[i] = ""
    end
    winner = false
    updateBoard = true
    timer = 0
    turn = "O"
end

--[...]

-- input functions

-- 3
function _mpress(x,y,b)
    --[...]

    --
    if winner and timer > time_max then reset_game() end
end

--[...]


-- 3
function _kpress(key)
    --[...]

    --
    if winner and timer > time_max then reset_game() end
end

--[...]

-- game functions

-- 4
function _update(dt)
    if winner then
        game_over()
        timer = timer + dt
    end
    --[...]
end

-- 5
function game_over()

    -- 6
    clearMsg()
    color(1)

    -- 7
    if turn == "" then
        print("DRAW!", 35, 118)
    else
        print(turn.." WON!", 30, 118)
    end

    -- 8
    if timer > time_max then
        print("PRESS A BUTTON TO START AGAIN.", 60, 118)
    else
        print("REPLAY IN".." "..(time_max-floor(timer)).."...", 60,118)
    end
end

--[...]

Result:

The game is now complete, we can play, win, lose, draw and restart the game.

Steps:

  1. We add one variable time and one constant time_max to the _init() function that load our datas at the beginning of the game. We will use them to give an amount of second before to be able to restart the game.

  2. We create a function called reset_game() that will be used to reset all our data to the starting default value, we need it to be able to restart the game and draw a new board by reseting all position with an empty string "".

  3. We add a check in the two function that listen the mouse click event and the keyboard key pressed event, if the game is finished (winner true) and the timer have reach the max_time, then the a click or a key pressed restart the game.

  4. To the main loop function _update(dt) we add a check on the winner variable, if the variable is true, the game is ended and we call the game_over() function, also the timer is incremented by the delta time. (see infos)

  5. We create a function game_over() which will be called each time the game finish. (winner = true) It's purpose is to draw a message with the final status of the game and to propose to start a new game.

  6. We erase the message box with the clearMSg() function and we set the color to black (color(1))

  7. If the turn is an empty string, it is a draw else we print the winner in the message box.

  8. While the timer has not reach the maximum, we display the seconds, then we display a message to propose to play again. (see infos)

Infos:

To know the time and the number of frame per second, we can use the delta time of the _update(dt) loop. One delta time is the time between two frame, two have one second/delta time give the number of frame per second.

We can do some tests with dt by creating a new program in liko-12 (DiskOS):

function _init()
    frame = 0
    time = 0
    total = 0
end

function _update(dt)

    time = time + dt
    frame = frame + 1

    if time >= 1 then
        total = total + 1
        frame = 0
        time = 0
    end

    clear(1)
    color(8)
    print(floor(total).."s", 10, 10)
    print(floor(1/dt).."fps", 10, 20)
    print((floor(time*100)/100).."dt in 1 sc", 10, 30)
    print(frame.."f in 1 s", 10, 40)
end

Last updated