createJS命中测试在tick事件中起作用,但不起作用

时间:2014-02-18 02:59:05

标签: javascript html5 html5-canvas hittest createjs

这给出了输出:

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);    
}

然而,当我从勾选功能中取出时,我得到:

Uncaught TypeError: Cannot call method 'globalToLocal' of undefined

但是,正如您从评论中看到的那样,allMyLabels[]不是空的,并且其中有一个createJS标签......

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 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();
        });
    }
}

当我开始游戏时,我创建我的画布,舞台,对象和标签,然后调用函数hitTest(),然后将enableMouseOver(20)添加到舞台。

        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();
        }

为什么我得到这个输出?

1 个答案:

答案 0 :(得分:1)

问题原因

在你身上hitTest()函数i具有触发事件时循环退出的值。因此,allMyLabels的长度不存在。 (上一个++使其 over 。)因此,我们得到allMyLabels[ number of allMyLabels ],并且索引从0开始,这是一个不存在的元素。< / p>

简而言之

如果我们有:

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

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

解决方案

您需要将其包装到匿名函数中,或者(根据我的喜好),使用bind(注意Polyfill部分)。

»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
    }
}

使用(匿名)函数换行,(从我所听到的命名函数泄漏到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.
  //  
}