Moron Test – Scene Specific Actions

We need some different looks here…

Tutorial

We’re finally at the point where we can begin to do specific actions – hide icons, move icons, unhide icons, etc. When we left off with version 4, we had our test completed for each scene level, but what about all the different extra actions? How do we manage those?

We need to create and call a function that is set to specific actions in a scene. We’ll use main as our key and declare a function that passes the icon, i values. That way for a scene level we can set specific actions.

//in the scenes.js file
//Within every scene object
//create a main: function(icon, i){}
//even if we're not doing anything other than core logic

var scene = [

    //level 0 
    {
        //for brevity I've removed all the icon obj
        //key and value pairs
        icons: [{}, {}, {},{}],
        answer: [2],
        instructions: ["Click the big red ghost to continue."],

        //here is our new main key with the function in which
        //we can declare scene specific actions
        main: function (icon, i) {}
    },
]

//in the moron.js file
//we need to call this new scene[level].main(icon, i)
//for each correct click in the runScene(icon, i) function

function runScene(icon, i) {
    var clicksNeeded = scene[level].answer.length
    //test 1 scene not yet complete
    if (clickCount < clicksNeeded) {
        //test 2 is icon clicked correct
        if (i === scene[level].answer[clickCount]) {
            clickCount++
            //runs scene specific actions in response to clicks
            scene[level].main(icon, i)
            //test 3 if scene complete
            if (clickCount === clicksNeeded) {
                level++
                start()
            }
        } else {
            console.log(fail)
            clearIcons()
        }
    }
}

With a scene[level].main(icon, i) function we can write actions specific to all clicks or even specific numbered clicks. First we start with actions for all clicks.

//example main function events for every icon clicked
main: function (icon, i) {
            //selects the instruction h2
            var instructions = document.querySelector(".instructions h2")

            //changes instruction to value from this level's instructions array
            //based on click count
            instructions.textContent = this.instructions[clickCount]

            //adds the hidden class to every clicked icon
            icon.classList.add("hidden")
        }

If I want to write events to specific click count numbers 1, 2, or 3 for example. I need to add some logic to test for these in my new scene[level].main(icon, i) function. We could test clickCount values using an if statement, but it’s much easier to read syntax if we use a switch statement. For example:

//in the scenes.js file
//this switch removes instructions after the first click
//then rearranges icons in the second click
main: function (icon, i) {
            switch (clickCount) {
                case 1:
                    //calls changeInstr and addes empty string from instructions
                    changeInstr(this.instructions[clickCount])
                    break
                case 2:
                    //uses the style method and the position values
                    //to move each icon based on its index value
                    icons[0].style.left = "71%"
                    icons[0].style.top = "27%"
                    icons[1].style.left = "20%"
                    icons[1].style.top = "60%"
                    icons[2].style.left = "20%"
                    icons[2].style.top = "27%"
                    icons[3].style.left = "50%"
                    icons[3].style.top = "55%"
                    break
            }
        }

//in the moron.js file
//BIG NOTE WE NEED TO ALSO CHANGE HOW icons to the global scope
//
//declare icons as a global variable with no value
var icons
//
//iconListener() functions' reset icons variable
function iconListener() {
    //no longer declares var icons, just resets icons value
    icons = document.querySelectorAll("i")

    Array.prototype.forEach.call(icons, function (icon, i) {
        icon.addEventListener("click", function () {
            runScene(icon, i)
        })
    })
}

Problem Set

  • Create a main function in every scene level object.
    • In this function scene specific events can be called
  • Call the main function for correct clicks in your runScene core logic
  • Write events in each scene main function
    • events that are called for every click, or
    • events that are called for specific clicks

Blog Question

How does the new scene[level].main function access the values of icon and i? How are those values passed from the moment created in the event listener to the scene level object’s main function? FYI this is an example of “closure.” Closure is the passing of variable values from an “outer” function to an “inner” function.

Leave a comment

Your email address will not be published. Required fields are marked *