javascript - 使用数千个动画元素提高 css 和 javascript 的性能

标签 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,所以如果我想在它上面添加更多移动的对象是 Not Acceptable 。

然后我想到了使用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和浏览器的想法,而使用传统的游戏引擎?

最佳答案

发布上面评论中提到的答案,供 future 的读者使用。

与基于 Pixi 构建的 v2 相比,Phaser v3 具有自定义渲染器。 从版本 3.12 开始,图形渲染管线进行了全面检查,以便在渲染图形时更快、更高效,无论是单独渲染还是与渲染 Sprite 混合渲染。详细信息可以在 Phaser v3.12 和 Phaser World 的更新日志中找到 issue 124

可以在示例页面上看到渲染和补间许多图形对象的示例 here

关于javascript - 使用数千个动画元素提高 css 和 javascript 的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52677706/

相关文章:

javascript - SVG不绘制图形

javascript - CSS 关键帧淡入

css - 这个动画的关键帧代码是什么样的?

javascript - 如何在 JavaScript 的客户端代码中获取其他国家/地区的当前日期时间?

javascript - Ramda 减少字符串来替换前一个

javascript - 获取宽度或高度 svg 矩形 javascript

html - SVG线条动画先擦再画

javascript - jquery next() 函数无法正常工作

javascript - svg 和 javascript : detect element intersection

javascript - NetInfo.addEventListener 在 react native 中不起作用