0

我在 Easel.js 中使用 SpriteSheetBuilder 来动态创建精灵表。我遇到的问题是,在浏览器锁定之前,我只能在画布上绘制大约 5 或 6 个精灵实例。它会导致严重的 CPU 和内存问题。我无法确定为什么会发生这种情况。这一定是我的实现。我的精灵表由大约 100 帧组成,但我使用的每个图像只有 8kbs。

我正在制作的是康茄舞线动画。我将调用服务器以获取将使用 sprite builder 合成到舞者 sprite 上的面孔。非常感谢您对此问题的任何见解!这是我的代码。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>EaselJS Example: SpriteSheetBuilder</title>
    <script src="easeljs-0.8.2.min.js"></script>
    <style>
        #dancers img {
            display: none;
        }

        canvas {
            background: red;
            width: 100%;
        }

        button {
            width: 50px;
            height: 50px;
        }
    </style>

</head>

<body>

<div id="dancers">
    <img id="stage" src="stage.jpg">
    <img id="curtains" src="curtains.png">
    <img id="conga_1" src="conga_1.png">
    <img id="conga_2" src="conga_2.png">
    <img id="conga_3" src="conga_3.png">
    <img id="conga_4" src="conga_4.png">
    <img id="conga_5" src="conga_5.png">
    <img id="conga_6" src="conga_6.png">
    <img id="conga_7" src="conga_7.png">
    <img id="conga_8" src="conga_8.png">
    <img id="conga_9" src="conga_9.png">
    <img id="conga_10" src="conga_10.png">
    <img id="conga_11" src="conga_11.png">
    <img id="conga_12" src="conga_12.png">
    <img id="conga_13" src="conga_13.png">
    <img id="conga_14" src="conga_14.png">
    <img id="conga_15" src="conga_15.png">
    <img id="conga_16" src="conga_16.png">
    <img id="conga_17" src="conga_17.png">
    <img id="conga_18" src="conga_18.png">
    <img id="conga_19" src="conga_19.png">
    <img id="conga_20" src="conga_20.png">
    <img id="conga_21" src="conga_21.png">
    <img id="conga_22" src="conga_22.png">
    <img id="conga_23" src="conga_23.png">
    <img id="conga_24" src="conga_24.png">
    <img id="conga_25" src="conga_25.png">
    <img id="conga_26" src="conga_26.png">
    <img id="conga_27" src="conga_27.png">
    <img id="conga_28" src="conga_28.png">
    <img id="conga_29" src="conga_29.png">
    <img id="conga_30" src="conga_30.png">
    <img id="conga_31" src="conga_31.png">
    <img id="conga_32" src="conga_32.png">
    <img id="conga_33" src="conga_33.png">
    <img id="conga_34" src="conga_34.png">
    <img id="conga_35" src="conga_35.png">
    <img id="conga_36" src="conga_36.png">
    <img id="conga_37" src="conga_37.png">
    <img id="conga_38" src="conga_38.png">
    <img id="conga_39" src="conga_39.png">
    <img id="conga_40" src="conga_40.png">
    <img id="conga_41" src="conga_41.png">
    <img id="conga_42" src="conga_42.png">
    <img id="conga_43" src="conga_43.png">
    <img id="conga_44" src="conga_44.png">
    <img id="conga_45" src="conga_45.png">
    <img id="conga_46" src="conga_46.png">
    <img id="conga_47" src="conga_47.png">
    <img id="conga_48" src="conga_48.png">
    <img id="conga_49" src="conga_49.png">
    <img id="conga_50" src="conga_50.png">
    <img id="conga_51" src="conga_51.png">
    <img id="conga_52" src="conga_52.png">
    <img id="conga_53" src="conga_53.png">
    <img id="conga_54" src="conga_54.png">
    <img id="conga_55" src="conga_55.png">
    <img id="conga_56" src="conga_56.png">
    <img id="conga_57" src="conga_57.png">
    <img id="conga_58" src="conga_58.png">
    <img id="conga_59" src="conga_59.png">
    <img id="conga_60" src="conga_60.png">
    <img id="conga_61" src="conga_61.png">
    <img id="conga_62" src="conga_62.png">
    <img id="conga_63" src="conga_63.png">
    <img id="conga_64" src="conga_64.png">
    <img id="conga_65" src="conga_65.png">
    <img id="conga_66" src="conga_66.png">
    <img id="conga_67" src="conga_67.png">
    <img id="conga_68" src="conga_68.png">
    <img id="conga_69" src="conga_69.png">
    <img id="conga_70" src="conga_70.png">
    <img id="conga_71" src="conga_71.png">
    <img id="conga_72" src="conga_72.png">
    <img id="conga_73" src="conga_73.png">
    <img id="conga_74" src="conga_74.png">
    <img id="conga_75" src="conga_75.png">
    <img id="conga_76" src="conga_76.png">
    <img id="conga_77" src="conga_77.png">
    <img id="conga_78" src="conga_78.png">
    <img id="conga_79" src="conga_79.png">
    <img id="conga_80" src="conga_80.png">
    <img id="conga_81" src="conga_81.png">
    <img id="conga_82" src="conga_82.png">
    <img id="conga_83" src="conga_83.png">
    <img id="conga_84" src="conga_84.png">
    <img id="conga_85" src="conga_85.png">
    <img id="conga_86" src="conga_86.png">
    <img id="conga_87" src="conga_87.png">
    <img id="conga_88" src="conga_88.png">
    <img id="conga_89" src="conga_89.png">
    <img id="conga_90" src="conga_90.png">
    <img id="conga_91" src="conga_91.png">
    <img id="conga_92" src="conga_92.png">
    <img id="conga_93" src="conga_93.png">
    <img id="conga_94" src="conga_94.png">
    <img id="conga_95" src="conga_95.png">
    <img id="conga_96" src="conga_96.png">
    <img id="conga_97" src="conga_97.png">
    <img id="conga_98" src="conga_98.png">
    <img id="conga_99" src="conga_99.png">
    <img id="conga_100" src="conga_100.png">
    <img id="conga_101" src="conga_101.png">
    <img id="conga_102" src="conga_102.png">
    <img id="conga_103" src="conga_103.png">
    <img id="conga_104" src="conga_104.png">
    <img id="conga_105" src="conga_105.png">
    <img id="conga_106" src="conga_106.png">
    <img id="conga_107" src="conga_107.png">
    <img id="conga_108" src="conga_108.png">
</div>

<div>
    <canvas id="testCanvas" width="1920" height="1080"></canvas>
</div>


<button id="add_dancer" onclick="addDancer();">add dancer</button>


<script src="jjcoords.js"></script>
<script id="editable">
    var canvas = document.getElementById("testCanvas");
    var stage = new createjs.Stage(canvas);
    var containers = [];
    var congaDancers = [];
    var counter = 0;

    function init() {

        var stageImg = new createjs.Bitmap(document.getElementById('stage').src);
        stage.addChild(stageImg);

        buildSprite();

        var curtains = new createjs.Bitmap(document.getElementById('curtains').src);
        stage.addChild(curtains);

        createjs.Ticker.addEventListener("tick", tick);

    }


    function buildSprite() {

        var container = createFrame('ryan3.png', document.getElementById(coords[counter].id).src, coords[counter].x, coords[counter].y, coords[counter].scale, coords[counter].rotation);
        containers.push(container);


    }

    function createFrame(consumerImg, dancerFrame, x, y, scale, rot) {

        var bitmap;
        var container = new createjs.Container();
        var consumerFace = new Image();
        consumerFace.src = consumerImg;
        consumerFace.onload = function () {


            var dancer = new createjs.Bitmap(dancerFrame);
            dancer.scaleX = 1.5;
            dancer.scaleY = 1.5;
            dancer.regX = dancer.image.width / 2 | 0;
            dancer.regY = dancer.image.height / 2 | 0;
            dancer.x = 100;
            dancer.y = 100;

            bitmap = new createjs.Bitmap(consumerFace.src);

            bitmap.regX = bitmap.image.width / 2 | 0;
            bitmap.regY = bitmap.image.height / 2 | 0;
            bitmap.scaleX = scale;
            bitmap.scaleY = scale;
            bitmap.x = x;
            bitmap.y = y;
            bitmap.rotation = rot;
//            bitmap.alpha = .5;

            container.name = 'ryan' + counter;
            container.addChild(dancer, bitmap);
            container.x = 700;
            container.y = 250;
            counter++;
            if (counter < coords.length) {
                buildSprite();

            } else {
                spriteBuilder();
            }


        };

        return container;

    }


    function spriteBuilder() {

        var square = new createjs.Container();

//        stage.addChild(containers[107]);
//        containers[107].y = 500;
        // create the sprite sheet builder:
        var builder = new createjs.SpriteSheetBuilder();

        var frames = [];
        for (var j = 0; j < containers.length; j++) {

            index = builder.addFrame(containers[j], null, 1, function (target, data) {

            }, j);
            // save off the index of each frame in order to use when defining the animation:

            frames.push(index);
        }

        // create an animation named square that comprises all of the frames we just added:
        // we're also telling it to loop the animation and setting a frequency so it updates every 8 ticks:

        builder.addAnimation("square", frames, true, 1);


        // run the build operation, and grab the resulting sprite sheet:
        // we could also do this asynchronously with buildAsync(...)
        var spriteSheet = builder.build();

        var square2 = new createjs.Sprite(spriteSheet, "square");
        square2.scaleX = .6;
        square2.scaleY = .6;
        square2.x = 250;
        square2.y = 620;
        stage.addChild(square2);

        // add in the generated spritesheet image for demo purposes:
//            stage.addChild(new createjs.Bitmap(spriteSheet._images[0])).set({x: 75, y: 150});
        // we want to do some work before we update the canvas,
        // otherwise we could use Ticker.addEventListener("tick", stage);
        congaDancers.push(square2);
        console.log(congaDancers);

    }

    var xpos = 200;
    function addDancer() {
        counter = 0;
        containers = [];
        buildSprite();

        xpos = xpos + 200;
        congaDancers[congaDancers.length - 1].x = xpos;

    }


    function tick() {

        stage.update(event);
    }


    init();


</script>
</body>
</html>
4

1 回答 1

0

这实际上很简单。通过为每个舞者缓存 100 多张图像,您将在内存中生成大量图像/画布。这是每个舞者的 75,000,000 像素。

SpriteSheets 是缓存复杂内容的好方法。但是,绘制和交换这么多大纹理可能会产生不利影响,而不是提供任何好处。

有很多更好的方法可以做到这一点。

  1. 如果您真的想使用 SpriteSheets,请制作一个,并将自定义面添加到顶部。因此,创建一个包含舞者身体和面部精灵/位图的容器。您可以根据需要制作任意数量的这些图像,而不是为每个图像生成一组新的巨型图像。

  2. 与其使用 SpriteSheetBuilder 制作新的 SpriteSheet,不如生成一个使用您已经创建的所有图像的定义。SpriteSheet 支持多个图像,因此您应该能够将每个帧指向一个新图像。然后采取与之前相同的方法

  3. 这种艺术是从哪里来的?如果您使用身体部位图像制作动画,请考虑在 EaselJS 中执行此操作,而不是保存位图。重复使用的一堆小身体部位将更加高效

  4. 如果您从矢量开始,请考虑使用 Adob​​e Animate 来导出它们。这将生成您可以使用的可缩放矢量内容。诚然,画布上的一大堆矢量并不理想,但它不会像现在这样对你的记忆造成负担。

我还会考虑预加载图像以创造更好的体验。希望这可以帮助!

于 2016-10-28T16:53:19.350 回答