External Inputs

It is possible to have interaction between the game canvas and external HTML elements, as shown here.

StaticImageWithInputs.js

/* Author: Derek O Reilly, Dundalk Institute of Technology, Ireland. */

class StaticImageWithInputs extends GameObject
{
    /* Each gameObject MUST have a constructor() and a render() method.        */
    /* If the object animates, then it must also have an updateState() method. */

    constructor(image, x, y, width, height)
    {
        super(null); /* as this class extends from GameObject, you must always call super() */

        /* These variables depend on the object */
        this.image = image;
        this.width = width;
        this.height = height;
        this.x = x;
        this.y = y;
    }

    render()
    {
        ctx.drawImage(this.image, this.x, this.y, this.width, this.height);
    }

    setX(newX)
    {
        this.x = newX;
    }
    
    setY(newY)
    {
        this.y = newY;
    }
    
    setWidth(newWidth)
    {
        this.width = newWidth;
    }
    
    setHeight(newHeight)
    {
        this.height = newHeight;
    }
}

The class has four setter methods, one for each of x, y, width and height, as highlighted in the code above.
    setX(newX)
    {
        this.x = newX;
    }
    
    setY(newY)
    {
        this.y = newY;
    }
    
    setWidth(newWidth)
    {
        this.width = newWidth;
    }
    
    setHeight(newHeight)
    {
        this.height = newHeight;
    }

static_image_with_inputs.html

<!-- Author: Derek O Reilly, Dundalk Institute of Technology, Ireland. -->

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>GENIUS worked example</title>
        <link rel="shortcut icon" type="image/png" href="images/genius_icon.png"/>
        
        <!-- Always include the game stylesheet, the Game class, the GameObject class and index.js -->
        <!-- These four must be included in all games. This code never changes.                -->
        <link href="css/game.css" rel="stylesheet" type="text/css"/>
        <script src="js/CanvasGame.js" type="text/javascript"></script>
        <script src="js/GameObject.js" type="text/javascript"></script>
        <script src="js/index.js" type="text/javascript"></script>
        
        <!-- ***************************************************************************** -->
        <!-- *************** THE CODE BELOW CAN BE DIFFERENT FOR EACH GAME *************** -->
        
        <!-- Always include the game javascript that matches the html file name --> 
        <script src="js/static_image_with_inputs.js" type="text/javascript"></script>
        
        <!-- Include any classes that extend from GameObject that are used in this game -->
        <script src="js/StaticImageWithInputs.js" type="text/javascript"></script>
        
        <!-- ************************* END OF GAME SPECIFIC CODE ************************* -->
        <!-- ***************************************************************************** -->
    </head>

    <body>
        <div id="gameContainer"> <!-- having a container will allow us to have a game that includes elements that are outside of the canvas -->
            <canvas id="gameCanvas" tabindex="1"></canvas>

            <!-- ***************************************************************************** -->
            <!-- *************** THE CODE BELOW CAN BE DIFFERENT FOR EACH GAME *************** -->
            
            <br>
            <label for="x">X: </label><input type="range" min="0" max="490" value="125" id="x"><br>
            <label for="y">Y: </label><input type="range" min="0" max="490" value="125" id="y"><br>
            <label for="width">Width: </label><input type="range" min="10" max="500" value="250" id="width"><br>            
            <label for="height">Height: </label><input type="range" min="10" max="500" value="250" id="height">
            
            <!-- ************************* END OF GAME SPECIFIC CODE ************************* -->
            <!-- ***************************************************************************** -->
            
        </div>
    </body>
</html>

The various html input elements that accept the user input are all included inside the "gameContainer" div. This way, we can keep the game code separate to any other code that a developer might include on a webpage.

            <!-- ***************************************************************************** -->
            <!-- *************** THE CODE BELOW CAN BE DIFFERENT FOR EACH GAME *************** -->

            <br>
            <label for="x">X: </label><input type="range" min="0" max="490" value="125" id="x"><br>
            <label for="y">Y: </label><input type="range" min="0" max="490" value="125" id="y"><br>
            <label for="width">Width: </label><input type="range" min="10" max="500" value="250" id="width"><br>            
            <label for="height">Height: </label><input type="range" min="10" max="500" value="250" id="height">

            <!-- ************************* END OF GAME SPECIFIC CODE ************************* -->
            <!-- ***************************************************************************** -->

Note that the "onchange" functionality for the html input elements is not included in the HTML file. Instead, it will be included in the game's static_image_with_inputs.js file.

static_image_with_inputs.js

/* Author: Derek O Reilly, Dundalk Institute of Technology, Ireland.             */
/* There should always be a javaScript file with the same name as the html file. */
/* This file always holds the playGame function().                               */
/* It also holds game specific code, which will be different for each game       */





/******************** Declare game specific global data and functions *****************/
/* images must be declared as global, so that they will load before the game starts  */
let cityImage = new Image();
cityImage.src = "images/city.png";

/******************* END OF Declare game specific data and functions *****************/







/* Always have a playGame() function                                     */
/* However, the content of this function will be different for each game */
function playGame()
{
    /* We need to initialise the game objects outside of the Game class */
    /* This function does this initialisation.                          */
    /* This function will:                                              */
    /* 1. create the various game game gameObjects                   */
    /* 2. store the game gameObjects in an array                     */
    /* 3. create a new Game to display the game gameObjects          */
    /* 4. start the Game                                                */


    /* Create the various gameObjects for this game. */
    /* This is game specific code. It will be different for each game, as each game will have it own gameObjects */

    gameObjects[0] = new StaticImageWithInputs(cityImage, 0, 0, 250, 250);

    /* END OF game specific code. */


    /* Always create a game that uses the gameObject array */
    let game = new CanvasGame();

    /* Always play the game */
    game.start();
    
    
    /* If they are needed, then include any game-specific mouse and keyboard listners */
    /* set the initial x,y, width and height of the image */
    gameObjects[0].setX(document.getElementById("x").value);
    gameObjects[0].setY(document.getElementById("y").value);
    gameObjects[0].setWidth(document.getElementById("width").value);
    gameObjects[0].setHeight(document.getElementById("height").value);

    document.getElementById("x").addEventListener("change", function ()
    {
        gameObjects[0].setX(document.getElementById("x").value);
    });

    document.getElementById("y").addEventListener("change", function ()
    {
        gameObjects[0].setY(document.getElementById("y").value);
    });

    document.getElementById("width").addEventListener("change", function ()
    {
        gameObjects[0].setWidth(document.getElementById("width").value);
    });

    document.getElementById("height").addEventListener("change", function ()
    {
        gameObjects[0].setHeight(document.getElementById("height").value);
    });
}

The image's original position is set using the data from the four HTML input elements.

    gameObjects[0].setX(document.getElementById("x").value);
    gameObjects[0].setY(document.getElementById("y").value);
    gameObjects[0].setWidth(document.getElementById("width").value);
    gameObjects[0].setHeight(document.getElementById("height").value);

 

The "onchange" functionality for each of the four input elements is implemented in this file, as shown below.

    document.getElementById("x").addEventListener("change", function ()
    {
        gameObjects[0].setX(document.getElementById("x").value);
    });

    document.getElementById("y").addEventListener("change", function ()
    {
        gameObjects[0].setY(document.getElementById("y").value);
    });

    document.getElementById("width").addEventListener("change", function ()
    {
        gameObjects[0].setWidth(document.getElementById("width").value);
    });

    document.getElementById("height").addEventListener("change", function ()
    {
        gameObjects[0].setHeight(document.getElementById("height").value);
    });

Write code to allow the user to adjust the size of multiple blocks, as shown here.

Write code to generate a piece of block art, as shown here. Note that the user should be able to specify how many blocks they would like to have.

Write code to adjust the brightness of an image, as shown here.

Write code to adjust the brightness of the red, green and blue components of an image, as shown here.