使用数千种动画元素提高CSS和JavaScript的性能

时间:2018-10-06 09:40:40

标签: javascript svg css-animations phaser-framework

我正在尝试用数千个闪烁的星星构建夜空,以此作为我想制作的一款简单游戏的背景,但是我遇到了很多性能问题。我想让它以60fps的流畅速度移动,但距离它很远。

起初,我虽然使用了svg容器。这就是我所做的:

<html>
    <head>
         <meta charset="utf-8"/>
         <style>
             @keyframes star_blink {
                 100% {opacity: 0;}
             }
         </style>
    </head>
    <body>
        <svg id="canvas" width="1000" height="1000" style="background:black" />
        <script>

        const svgns = "http://www.w3.org/2000/svg";

        var svg = document.getElementById("canvas");

        var create_star = () => {
            var star_element = document.createElementNS(svgns, "rect");
            star_element.setAttributeNS(null, "width", Math.random() < 0.85 ? 1 : 2);
            star_element.setAttributeNS(null, "height", Math.random() < 0.85 ? 1 : 2);
            star_element.setAttributeNS(null, "x", Math.random() * 1000);
            star_element.setAttributeNS(null, "y", Math.random() * 1000);
            var max_opacity = Math.random() * 0.8;
            var min_opacity = Math.random() * max_opacity;
            var transition_time = Math.random() * 10;
            while (transition_time < 0.5) {transition_time = Math.random() * 10;}
            star_element.setAttributeNS(null, "style", "stroke:white; fill:white; opacity: " + max_opacity + "; animation: star_blink " + transition_time + "s infinite alternate;");
            svg.appendChild(star_element)
        }

        for (var i=0; i<10000; i++) {
            create_star();
        }

        </script>

    </body>
</html>

性能真的很差,我只能达到20fps,因此我想在其上添加更多对象是不可接受的。

然后我想到要使用phaserjs:

<html>
    <head>
         <meta charset="utf-8"/>
         <script src="https://cdnjs.cloudflare.com/ajax/libs/phaser-ce/2.11.1/phaser.js"></script>
         <script>
            var game = new Phaser.Game(1000, 1000, Phaser.WEBGL, 'phaser-example', { create: create, update: update });

            var stars = [];
            var planets = [];

            function random_rectangle_size() {
                var dice = Math.random();
                return dice < 0.7 ? 1 : dice < 0.9 ? 2 : dice < 0.98 ? 3 : 4;
            }

            class Star {
                constructor() {
                    this.blinking_time = Math.random() * 3000;
                    while(this.blinking_time < 500) {this.blinking_time = Math.random() * 3000}
                    this.posX = Math.random() * 1000
                    this.posY = Math.random() * 1000
                    this.graphics = game.add.graphics(this.posX, this.posY);
                    this.graphics.beginFill(0xFFFFFF, (Math.random() * 0.8 + 0.2) * 0.8);
                    this.graphics.drawRect(0, 0, random_rectangle_size(), random_rectangle_size());
                    this.graphics.endFill();

                    game.add.tween(this.graphics).to({alpha: Math.random() * 0.4}, this.blinking_time, Phaser.Easing.Linear.None, true, 0, -1, true)

                }
            }


            function create() {
                 for(var i=0; i<10000; i++) {
                     stars.push(new Star())
                 }
            }

            function update() {}

         </script>
    </head>
    <body>
    </body>
</html>

我在那里大约达到30fps。好一点,但离我的目标还很远。

是否可以做我想做的事?如何在这里提高性能?我应该放弃使用JavaScript和浏览器的想法,而使用传统的游戏引擎吗?

1 个答案:

答案 0 :(得分:2)

上面的评论中提到的答案,供将来的读者使用。

与在Pixi上构建的v2相比,Phaser v3具有自定义渲染器。 从版本3.12开始,对图形的渲染管道进行了大修,以便在单独渲染图形以及与渲染精灵混合时,更快,更高效。可以在Phaser v3.12和Phaser World issue 124

的变更日志中找到详细信息

可以在示例页面here

上看到渲染和补间许多图形对象的示例。