不安定なフレーム処理を改造する【enchant.js】

enchant.jsではFPS(1秒間に画面を更新処理する回数)を好きなように設定できるようになっているのですが、これがどうも安定していないというのがずっと気になっていました。

パズルゲームなどを作っている段階では気にならなかったんですが、シューティングゲームを30FPSで作ってみるとどうも弾の動きが早くなったり遅くなったりしている。

気になりだしたら凄く気になるので改造を試みてみました。

requestAnimationFrame()が更新している

javascriptの知識のまったくない素人がenchant.jsの中身を読んでも全く理解できません(;´・ω・)

が、時間をかけてそれっぽいところをついに探し当てrequestAnimationFrame()という関数が画面の更新処理をしているということを突き止めました( `ー´)ノ

で、更新処理をしているであろう所を読んでみるとなんか変なんですよ。

         _requestNextFrame: function(delay) {
            if (!this.ready) {
                return;
            }
            if (this.fps >= 60 || delay <= 16) {
                this._calledTime = window.getTime();
                window.requestAnimationFrame(this._callTick);
            } else {
                setTimeout(function() {
                    var core = enchant.Core.instance;
                    core._calledTime = window.getTime();
                    window.requestAnimationFrame(core._callTick);
                }, Math.max(0, delay));
            }
        },

requestAnimationFrame()が更新処理をしてくれるはずだけどsetTimeout()も使っています。

多分これはrequestAnimationFrame()に対応していないブラウザに対応させるためにあるんだろうと思うんですが(ちゃんとわかっていない)、たぶんいらないんじゃね?(・∀・)

        _requestNextFrame: function() {
            if (!this.ready) {
                return;
            }
            this._calledTime = window.getTime();
            window.requestAnimationFrame(this._callTick);
        },

ってことでばっさりカット。

しかし、これだと60FPSになります(requestAnimationFrame()は60FPSで更新処理する)。なのでこの_requestNextFrame が呼ばれたときに好みのFPSになるように調整して必要な時だけ処理するようにします。

たとえば30FPSにしたい場合2回に1回処理するようにすれば処理が半分になり30FPSになります。

で、それを書く場所が _requestNextFrameのちょっとしたにあります。

         _tick: function(time) {
       this._requestNextFrame();//追加
            //
            //ここにFPSを調整する処理を書く
            //
            var e = new enchant.Event('enterframe');
            var now = window.getTime();
            var elapsed = e.elapsed = now - this.currentTime;
            this.currentTime = now;
            //略

なんか上でバッサリカットしたらここに_requestNextFrame()が来るようになりました。そしてその下にFPSを調整する処理を書きます(30FPSにしたいなら2回に1回処理するように書く)。変数を使ってゲームによって変更できるようにしておいた方が良いです(自分で考えてね(^_-)-☆)

あとついでにrequestAnimationFrameで検索すると以下のようなところがあります。

// define requestAnimationFrame
window.requestAnimationFrame =
    window.requestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    (function() {
        var lastTime = window.getTime();
        var frame = 1000 / 60;
        return function(func) {
            var _id = setTimeout(function() {
                lastTime = window.getTime();
                func(lastTime);
            }, Math.max(0, lastTime + frame - window.getTime()));//残ってる時間
            return _id;
        };
    }());

たぶんこれはrequestAnimationFrameに対応していないブラウザのための処置だと思うんですが、これ無しで動くのでこいつもバッサリカットしてやりましょう(・∀・)

まとめ

細かい説明はありませんが(説明できないんだよ(;^ω^))こんな感じで修正するとFPSが安定するようになりました。気になる方は試してみてください(改造は自己責任で!ちゃんとバックアップとっとけよ!)

同カテゴリー記事

当サイトのオリジナルゲーム(ランダム表示)

部屋に侵入してきた蚊と戦うカジュアルゲームです。現実同様好き放題飛び回る蚊をうまく叩い...
平面なルービックキューブみたいなゲーム。スライドさせて模様を完成させます。
ボタンを押して決められたパターンに電気をつけるパズルゲーム
マリオ風横スクロールアクションゲーム。地下から制限時間内に脱出しろ!

記事の感想・コメント

※コメントはまだありません※

コメントを残す

メールアドレスが公開されることはありません。

ゲームジャンルタグ

新着技術ブログ記事

新着開発日記