LoginSignup
1
0

More than 5 years have passed since last update.

Cocos2d-JS + CocosStudio アニメをスムーズにする

Posted at

一カ所直すだけ

 最初に断っておきますが、CocosStudio で編集したアニメに対してだけの効果があります。普通の Action 等には影響ありません。CocosStudio 自体、もう開発停止になっているらしいので需要があるかどうかわかりませんが…。
 Cocos2d-JS の ActionTimeline クラスの step() 関数内にある、

ActionTimeline.js
    this._currentFrame = Math.floor(this._time / this._frameInternal);

または、古いバージョンだと

ActionTimeline.js
    this._currentFrame = (this._time / this._frameInternal) | 0;

のようになっている行があると思います。
 これは、小数点以下を切り捨てているわけですが、これを

ActionTimeline.js
    this._currentFrame = this._time / this._frameInternal;

として、小数点以下を捨てないようにしてみてください。世界が変わると思います。

スムーズになる理由

 そもそも、なぜ小数点以下を切り捨てているのかといいますと、単に元ソースである C++ ソースで _currentFrame が int 型だからです。それをベタ移植した結果かと思われます。
 それで、_currentFrame はフレーム番号ですから、本来は
0, 1, 2, 3, 4, 5, ...
と順番に増えていって欲しい訳ですが、JavaScript は小数計算の精度が低いため、この Cocos2d-JS で行っているような計算方法だと
0, 1, 1.9999, 3, 4, 4.9999, ....
のような値になってしまいます。それで、小数以下を切り捨ててしまうと
0, 1, 1, 3, 4, 4, ....
になってしまい、飛び飛びのフレームが表示されていたことになるわけです。
 だから、もし整数にしたいなら

ActionTimeline.js
    this._currentFrame = Math.round(this._time / this._frameInternal);

とすべきなのです。
 ただ、この _currentFrame を引数として渡している関数を調べたところ特に _currentFrame が整数である必要はなく、1.5 を指定すればフレーム#1と#2の間をちゃんと補間するようになっていたので、わざわざ丸める必要もなかったわけです。
 なので、先に示したように

ActionTimeline.js
    this._currentFrame = this._time / this._frameInternal;

にするだけで、スムーズに再生されるようになるというものでした。

以上。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0