我正在尝试构建一个有数千颗闪烁星星的夜空作为我想制作的简单游戏的背景,但我遇到了很多性能问题。我想实现它以流畅的 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/