【问题标题】:Flipped SpriteSheet animation using EaselJS after preloading the image预加载图像后使用 EaselJS 翻转 SpriteSheet 动画
【发布时间】:2014-01-11 08:37:21
【问题描述】:

我正在尝试水平翻转 SpriteSheet 动画中的精灵。我从this example开始

我在创建 SpriteSheet

后立即添加了翻转帧
    var ss = new createjs.SpriteSheet(spriteSheet);

    createjs.SpriteSheetUtils.addFlippedFrames(ss, true, false, false);

    grant = new createjs.BitmapAnimation(ss);
...

我总是收到这个错误:

Uncaught TypeError: Cannot read property 'length' of null    (SpriteSheetUtils.js l.174)

我看到有人在这个github thread 中遇到了同样的问题 并使用预加载机制对其进行了修复。

该示例也使用了预加载,因此我尝试在资源加载后调用 addFlippedFrames,但仍然看到相同的错误。

有人知道吗? 如何使用 addFlippedFrames ?

编辑: 这是我尝试过的代码:

用我的 spritesheet 初始化舞台:

    spriteSheet = new createjs.SpriteSheet({
        "animations": {
            "none": [0, 0],
            "run": [0, 25],
            "jump": [26, 63]
        },
        "images": ["characters/grant/runningGrant.png"],
        "frames": {
            "height": h,
            "width": w,
            "regX": 0,
            "regY": 0,
            "count": 64
        }
    });



    sprite = new createjs.BitmapAnimation(spriteSheet);
    sprite.x = startPosition.x;
    sprite.y = startPosition.y;

// Add the sprite to the stage.
stage.addChild(this.sprite);

然后像这样使用预加载:

var manifest = [{
        src: "characters/grant/runningGrant.png",
        id: "grant"
    }
];

var loader = new createjs.LoadQueue(false);
loader.onFileLoad = handleFileLoad;
loader.onComplete = onResourcesLoaded;
loader.loadManifest(manifest);

和回调函数:

handleFileLoad = function(event) {
    assets.push(event.item);
};

onResourcesLoaded = function() {

    for (var i = 0; i < assets.length; i++) {
        var item = assets[i];
        var id = item.id;
        var result = loader.getResult(id);

        if (item.type == createjs.LoadQueue.IMAGE) {
            var bmp = new createjs.Bitmap(result);
                //does this Bitmap creation trigger the real bitmap loading ?
                //is this loading asynchrous which would explain my problem.
                //in this case, how can I manage the loading callback ?
        }
    }

    //I would expect here to have the image fully loaded but its not
    //A timeout of 2 seconds makes the addFlippedFrames works.
    setTimeout(function(){
            createjs.SpriteSheetUtils.addFlippedFrames(spriteSheet, true, false, false);
            sprite.gotoAndPlay("run_h"); //I think "run_h" is used to launch the flipped version of "run"
    }, 2000);
};

【问题讨论】:

  • 你能通过 jsfiddle 分享你的具体例子吗?我遇到了同样的问题,就我而言,问题是图像尚未加载。作为一个非常快速和肮脏的测试,您可以在执行 addFlippedFrames 之前使用 1 或 2 秒的超时(仅用于测试)
  • 是的,它在 2 秒超时后工作......:/
  • 我试图用我的例子创建一个 JSFiddle,但是得到了一个 DOM SECURITY 异常:/你可以在这里看到它:jsfiddle.net/2K6SX/5

标签: easeljs


【解决方案1】:

您的问题是,您创建了一个带有图像 url 的 SpriteSheet,这已经触发了加载过程,而 preload-js 队列实际上什么也没加载,因为图像的加载已经在进行中,所以“onComplete "-事件总是在图像实际加载之前触发 - 这是有道理的,因为不需要两次加载图像

我已经更新了你的 jsfiddle 并添加了一些 cmets:http://jsfiddle.net/K4TmS/1/(完整代码)

spriteSheet = new createjs.SpriteSheet({
            "animations": {
                "none": [0, 0],
                "run": [0, 25],
                "jump": [26, 63]
            },
            //this line in YOUR version triggered an own loading process, independent from the queue
            "images": [result],  
            "frames": {
                "height": 292.5,
                "width":165.75,
                "regX": 0,
                "regY": 0,
                "count": 64
            }
        });

// this was executed instantly, because the image was already in another loading progress, and therefore wasn't even added to the queue
loader.onComplete = onResourcesLoaded;

这里的参数可以忽略 DOM 安全错误 18(用于开发)Disable same origin policy in Chrome 但是对于生产,你应该只从同一个服务器加载 img,然后图像操作不会出错。

简而言之:您的问题是由于执行的顺序错误,请记住:如果您使用预加载:在其他所有操作之前进行预加载,并且在未完成预加载之前什么也不做. (加载图形/动画/指示器除外)。

【讨论】:

  • 似乎是一个很好的解释。我试试看,thx!关于从不同服务器加载,我只为 JSfiddle 示例执行此操作,因此在我的实际代码中不会出现问题;)
  • 是的,我猜是这样,只是想提一下,以防您或其他人偶然发现这个问题;)
【解决方案2】:

使用 scaleX 很容易做到

if(right == true)
    {
        //walking direction en sprite switch
        rogerWalk.scaleX = -1 * rogerWalk.scaleX;
        right = false;
    }

//我以前制作的代码(在这种情况下是罗杰向右走(标准精灵方向)

if(right == false)
    {
        rogerWalk.scaleX = -1 * rogerWalk.scaleX;
        right = true;

//这是在我的keyleft/keyright函数中

我知道帖子很旧,但仍然有人可以使用它:)

【讨论】:

  • 还可以考虑将rogerWalk.regX 设置为精灵的中心像素,以将反射保持在同一位置。
猜你喜欢
  • 2014-06-28
  • 2013-03-17
  • 2015-08-08
  • 1970-01-01
  • 2013-02-22
  • 2012-02-02
  • 1970-01-01
  • 2012-07-16
  • 1970-01-01
相关资源
最近更新 更多