Question

This gives output:

Lee Xian Sheng label hit

function tick(event) {  
    for (var i = 0 ; i < allMyLabels.length; i++) {
        var pt = allMyLabels[i].globalToLocal(stage.mouseX, stage.mouseY);
        if (allMyLabels[i].hitTest(pt.x, pt.y)) { 
            log(allMyLabels[i].text + " label hit"); 
        }       
    }
    stage.update(event);    
}

When I take it out of the tick function, however, I get:

Uncaught TypeError: Cannot call method 'globalToLocal' of undefined

But, as you can see from the comment, allMyLabels[] is not empty, and has a createJS label in it...

cn_label = new createjs.Text(itemObj.cn_name, "14px Arial", "white");   
cn_label.y = -45;

//loop through all labels, check hittest for each
allMyLabels.push(cn_label);

HitTest function:

function hitTest() {
    for (var i = 0 ; i < allMyLabels.length; i++) {
        log("label: " + allMyLabels[i].text); //NOT undefined, gives: label: Lee Xian Sheng, as expected
        allMyLabels[i].addEventListener("mouseover", function() {
            var pt = allMyLabels[i].globalToLocal(stage.mouseX, stage.mouseY);
            if (allMyLabels[i].hitTest(pt.x, pt.y)) { 
                log(allMyLabels[i].text + " label hit"); 
            }
            stage.update();
        });
    }
}

When I start the game, I create my canvas, stage, objects and labels, then call function hitTest(), then add enableMouseOver(20) to stage.

        function init() {                               
            canvas = document.getElementById("demoCanvas"); 
            start();            
        }

        function start() {
            stage = new createjs.Stage("demoCanvas");
            stage.mouseMoveOutside = true;  

            //Create Objects
            drawMap();
            createInitialNPC();
            stage.enableMouseOver(20);  

            //Animation ticker
            createjs.Ticker.addEventListener("tick", tick);
            createjs.Ticker.setFPS(60);
            keyEvents();                
            stage.update();
        }

Why do I get this output?

Was it helpful?

Solution

Cause of issue

In you hitTest() function i has the value as of exit by loop when event is triggered. Thus it is length of allMyLabels which does not exist. (Last ++ makes it go over.) As a result we get allMyLabels[ number of allMyLabels ], and as index start at 0, that is a non existent element.

In short

If we have:

allMyLabels === [
      label[0],   // allMyLabels[0]
      label[1],   // allMyLabels[1]
      label[2]    // allMyLabels[2]
];

allMyLabels.length === 3
allMyLabels[3] === undefined

Solution

You would need to wrap it in to an anonymous function, or (as I prefer), use bind (note Polyfill section).

»Sample fiddle«

divs = document.getElementsByTagName('DIV');

function change_div(i, e) {
    divs[i].innerHTML = "Hello " + i + ", " + e.timeStamp;
}

function ok_one() {
    dl = divs.length;
    for (i = 0; i < dl; ++i) {
        divs[i].addEventListener("mouseover", change_div.bind(this, i));
        //                                                     |    |
        //                                                     |    +-- Current i
        //                                                     +------- Or null
    }
}

Using (anonymous) function wrap, (from what I have heard named functions leak in IE).

for (i = 0; i < dl; ++i) {
    divs[i].addEventListener("mouseover", (function(k) {
    //                                    |         |
    //                                    |         +---- Passed current i.
    //                                    +-------------- Wrap and execute.
    //                                              
    //                                              Name it "i" if you want
    //  +---- Return function having CURRENT environment, thus k === i.
    //  |
        return function(e) {
            divs[k].innerHTML = "Hello " + k + ", " + e.timeStamp;
        }
    })(i));
  // | |
  // | +----- Pass current loop i to function AND execute it NOW.
  // +------- Wrap end.
  //  
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top