LoginSignup
0
0

More than 1 year has passed since last update.

Pixi.jsのAnimatedSpriteのコマ送り速度をAsepriteでのコマ送り速度と合わせる

Last updated at Posted at 2022-08-04

困っていたこと

Pixi.jsでは、AnimatedSpriteというオブジェクトを用いることで、簡単にアニメーションする画像を表示できます。
ドット絵制作ソフトの「Aseprite」から生成されたファイルからでも生成が可能でゲーム開発にとても便利です。
しかし、再生速度は無視されてしまい、60fpsで毎回画像が更新されてしまいます。
これを何とかしましょう。
今回の解決方法はコマ送りが等速の場合のみ有効です。違う場合はtickerを使う必要が出てくるでしょう。

下準備

sample
 ├img
 │ ├sample.aseprite
 │ ├(sample.json)
 │ └(sample.png)
 ├index.html
 └index.js

ファイル構成はこんな感じ。

json,pngファイルの生成

まず、表示したい画像のasepriteファイル(sample.aseprite)からjsonファイルとpngファイルを生成します。
このサイトの「Exportする」までをやれば大丈夫です。

ソースを書く

index.html
<html>
    <head>
        <meta charset="utf-8" />

        <title>pixi.js test</title>
        
        <link rel="stylesheet" href="index.css" />

        <!-- jQueryの読み込み -->
        <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>

        <!-- pixi.jsの本体の読み込み -->
        <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.0.1/pixi.min.js"></script>
    </head>
    <body>
        <main id="app">
            <!-- ここに表示される -->
        </main>

        <script type="text/javascript" src="index.js"></script>
    </body>
</html>
index.js(修正前)
window.addEventListener('load', () => {
    app = new PIXI.Application({
        width: 600,
        height: 600,
        backgroundColor: 0x1099bb,
    }); // global

    $('#app').append(app.view);

    app.loader.add('Piyo', './img/sample.json');
    app.loader.load(setup);
});

function setup() {
    let textures = app.loader.resources.Piyo.textures;
    let textureArray = Object.keys(textures).map(id => textures[id]);
    
    let sprite = new PIXI.AnimatedSprite(textureArray);
    app.stage.addChild(sprite);
    
    sprite.play();
}

この状態だと、画像は60fpsで毎回画像が更新されてしまいます。

解決方法

これを解消するためには、まず、元の再生速度を取得する必要があります。
Asepriteでの再生速度は、jsonファイルにちゃんと記録されています。

sample.json(例)
{ "frames": {
    "sample 0.aseprite": {
    "frame": { "x": 0, "y": 0, "w": 32, "h": 32 },
    "rotated": false,
    "trimmed": false,
    "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
    "sourceSize": { "w": 32, "h": 32 },
    "duration": 100 // ←これ。単位はms
   },
   ...
}

次にsprite.animationSpeedをいい感じにいじる必要があります。
これは、値が1のとき1フレームに1回、0.1のとき10フレームに1回と、間隔フレーム数の逆数を指定する必要があります。
このdurationの値をtとすると、60*(t/1000)が間隔フレーム数です。
よって、約分して指定するのは、50/(3*t)となります。
修正後のコードは、

index.js(修正後)
...
function setup() {
    let textures = app.loader.resources.Piyo.textures;
    let textureArray = Object.keys(textures).map(id => textures[id]);

    $.ajaxSetup({async: false});
    $.getJSON('./img/sample.json', (jsonData) => {
        textureArraySpeed = 50 / (3 * jsonData.frames['sample 0.aseprite'].duration);
    });
    $.ajaxSetup({async: true});

    let sprite = new PIXI.AnimatedSprite(textureArray);
    app.stage.addChild(sprite);

    sprite.animationSpeed = textureArraySpeed;
    
    sprite.play();
}

となります。
以上!!

0
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
0
0