function gameLoop() {
    setTimeout(function onTick() {
        /*
         * First, check game state
         * - Is it ended?
         * - Is it paused?
         */
        if (isGameEnded()) {
            alert('Game over');
            return;
        }
        if (snake.pause) {
            /*
            * there's no need to keep re-rendering activity frame(s) when there's no change
            * so 'return' here
            * this loop needs to be triggered explicitly in keyboardControl function
            * when game is requested to resume
            */
            return;
        }

        /* Move the snake one step in its current direction */
        snake.move();

        /* Check if any food is eaten due to previous one step taken */
        const foodEaten = snakeEating();

        /*
         * If one or more food is eaten (foods' positions can be duplicated, so the snake 
         * is be able to eat more than one food in a row):
         * - apply the effect it has on snake
         * - replace the food eaten with a newly one generated at a random position
         */
        foods.forEach(f => {
            if (foodEaten.includes(f)) {
                f.takeEffect();
                f.new(generatedItemBox);
            }
        });

        /* re-position snake at canvas margin if it has almost fully gone outside of canvas */
        comebackIfSnakeGoOutsideCanvas()

        /* render updates above on canvas */
        renderActivityFrame();

        /* re-run this process after a period of time (based-on snake's speed) */
        gameLoop();
    }, snake.speed)
}
/**
 * main game function:
 * run continuously to perform game logic at each movement
 * - make the snake move on screen
 * - generate new random foods after snake eats one
 */
main game function:
run continuously to perform game logic at each movement
- make the snake move on screen
- generate new random foods after snake eats one
main game function : run continuously to perform game logic at each movement - make the snake move on screen - generate new random foods after snake eats one
function gameLoop() {
    setTimeout(function onTick() {
        if (isGameEnded()) {
            alert('Game over');
            return;
        }
        if (snake.pause) {
            return;
        }
        snake.move();
        const foodEaten = snakeEating();
        foods.forEach(f => {
            if (foodEaten.includes(f)) {
                f.takeEffect();
                f.new(generatedItemBox);
            }
        });
        comebackIfSnakeGoOutsideCanvas()
        renderActivityFrame();
        gameLoop();
    }, snake.speed)
}
function gameLoop ( ) { setTimeout ( function onTick ( ) { if ( isGameEnded ( ) ) { alert ( 'Game over' ) ; return ; } if ( snake . pause ) { return ; } snake . move ( ) ; const foodEaten = snakeEating ( ) ; foods . forEach ( f => { if ( foodEaten . includes ( f ) ) { f . takeEffect ( ) ; f . new ( generatedItemBox ) ; } } ) ; comebackIfSnakeGoOutsideCanvas ( ) renderActivityFrame ( ) ; gameLoop ( ) ; } , snake . speed ) }
main game function:
 run continuously to perform game logic at each movement
 - make the snake move on screen
 - generate new random foods after snake eats one
main game function : run continuously to perform game logic at each movement - make the snake move on screen - generate new random foods after snake eats one
/*
         * First, check game state
         * - Is it ended?
         * - Is it paused?
         */ /*
            * there's no need to keep re-rendering activity frame(s) when there's no change
            * so 'return' here
            * this loop needs to be triggered explicitly in keyboardControl function
            * when game is requested to resume
            */ /* Move the snake one step in its current direction */ /* Check if any food is eaten due to previous one step taken */ /*
         * If one or more food is eaten (foods' positions can be duplicated, so the snake 
         * is be able to eat more than one food in a row):
         * - apply the effect it has on snake
         * - replace the food eaten with a newly one generated at a random position
         */ /* re-position snake at canvas margin if it has almost fully gone outside of canvas */ /* render updates above on canvas */ /* re-run this process after a period of time (based-on snake's speed) */