优化SVG游戏

时间:2010-10-30 18:33:46

标签: javascript jquery svg raphael

我使用Raphaël.js创建了我的第一个SVG游戏。

在Chrome中游戏感觉很快,但在IE等其他浏览器中(可以理解,因为它使用的是VML),Firefox,iPad Safari等等,有时感觉很慢。

我正在寻找有关如何优化代码以挤出绝对最佳性能的一些提示。我尽我所能来自己优化它,但我只是一个JS初学者。也可以随意提及是否应该使用我不使用的任何推荐的最佳实践。瓶颈可能在哪里?

您可以在jsfiddle上看到代码并尝试游戏。

3 个答案:

答案 0 :(得分:3)

减少方法调用

var left1 = a.attr('x'),
left2 = b.attr('x'),
right1 = a.attr('x') + a.attr('width'),
right2 = b.attr('x') + b.attr('width'),
top1 = a.attr('y'),
top2 = b.attr('y'),
bottom1 = a.attr('y') + a.attr('height'),
bottom2 = b.attr('y') + b.attr('height');

可以这样优化:

var left1 = a.attr('x'),
left2 = b.attr('x'),
right1 = left1 + a.attr('width'),
right2 = left2 + b.attr('width'),
top1 = a.attr('y'),
top2 = b.attr('y'),
bottom1 = top1 + a.attr('height'),
bottom2 = top2 + b.attr('height');

这为每hitDetection次呼叫节省了4次方法调用。同样适用于wallDetection以及其他功能。事实上,我也相信你可以删除宽度和高度调用,只是通过一个闭包缓存,因为它们在创建后非常静态,见下一个例子。

还有下一位:

var animateEnemies = function(enemy) {
    var enemyWidth = enemy.attr('width'),
    enemyHeight = enemy.attr('height'),
...

你设置敌人的宽度和高度一次,所以看起来很稳定,你可以删除.attr()查找并传递createEnemies调用的宽度和高度。

var animateEnemies = function(enemy , enemyWidth , enemyHeight) {
    var animationDuration = getRandomInt(1000, 3000) / difficulty;
    enemy.animate({
        x: getRandomInt(0, gameWidth - enemyWidth),
        y: getRandomInt(0, gameHeight - enemyHeight)
    }, animationDuration, "ease-in-out");
    // use setTimout instead of onAnimation callback, since it gave "too much recursion" in Firefox 3.6
    this.timeOut = setTimeout(function() {
        animateEnemies(enemy , enemyWidth , enemyHeight);
    }, animationDuration);
};

减少函数调用和缓存变量可以在旧版浏览器中提供很多帮助,除此之外,代码看起来非常整洁。

答案 1 :(得分:3)

我不想听起来令人沮丧,但我怀疑 IE 可以做得更好。 正如您所看到的,我创建的stripped down version仅包含动画(没有命中检测,游戏逻辑或mousemove处理程序),速度仍然是不可接受的。

对于 Firefox 我认为我发现how以避免迟缓:

var mouseMove = function(e) {

    // only do this if there's at least 20ms diff.
    var now = +new Date();
    if (now - mouseMove.last < 20)
        return;
    else 
       mouseMove.last = now;

    // ...
};

mouseMove.last = +new Date();   

答案 2 :(得分:1)

最大限度地减少DOM调用次数。