【Pixi.js】スプライトの配列管理

スプライトの配列管理 Pixi.js
スプライトの配列管理

はじめに

Pixi.jsについて学んだことの備忘録。
スプライトの配列管理について。

ここではPixi.jsのver4を使用しています。
最新版では書き方が全然違うため動かないため注意が必要です。

スプライトの配列管理

同じ画像のスプライトを配列に入れて管理できると便利かも。

5円玉をタップすると上に移動して消える、すべて消えると元に戻る。
そんなサンプルがこちら。

コードは下記のとおり。

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>スプライトの配列管理 Pixi.js</title>
    <script src="../../pixi.min.js"></script>
</head>

<body style="margin: 0; overflow: hidden;">
    <script>
        // Pixi.jsのアプリケーションを作成
        const app = new PIXI.Application({
            width: 360,                 // 画面の横幅
            height: 548,                // 画面の縦幅
            backgroundColor: 0xcccccc,  // 背景色を設定
        })

        // appをbodyに追加
        document.body.appendChild(app.view);

        // loaderでファイルを読み込む
        PIXI.loader
            .add('goen', 'goen.png')   // PNG画像
            .load(onAssetsLoaded);     // ロード後に実行される処理

        // ロード後に実行される処理
        function onAssetsLoaded(loader, resources) {
            // 画像を読み込み
            const texture = PIXI.Texture.from('goen');

            // 複数のスプライトを扱う
            const sprites = [];     // 管理用の配列
            const max = 5;          // スプライトの数

            // 複数のスプライトを作成
            createSprites();

            // スプライトを複数作成して配列に格納
            function createSprites() {
                for (let i = 0; i < max; i++) {
                    const ball = new PIXI.Sprite(texture);  // 定義
                    ball.x = 70 * i;                // 初期位置x
                    ball.y = 200;   // 初期位置y
                    ball.scale.x = 4;               // x方向に4倍の大きさ
                    ball.scale.y = 4;               // y方向に4倍の大きさ
                    ball.interactive = true;        // タップ可能にする
                    ball.buttonMode = true;         // PCでマウスカーソルのアイコンが変わる
                    ball.on('pointerdown', onTap);// タップでonTap関数を呼ぶ
                    app.stage.addChild(ball);       // 画面に表示
                    sprites.push(ball);             // 配列に追加
                }
            }

            // タップ時の動作を定義する関数
            function onTap(event) {
                // タップしたスプライトを取得
                const clickedSprite = event.target;

                // スプライトを上方向に移動させるアニメーション
                const moveSprite = () => {
                    clickedSprite.y -= 5;  // 5pxずつ上に移動
                    if (clickedSprite.y + clickedSprite.height < 0) {
                        // 画面外に出たら削除
                        app.stage.removeChild(clickedSprite);
                        clickedSprite.destroy();

                        // 配列からも削除
                        const index = sprites.indexOf(clickedSprite);
                        if (index !== -1) {
                            sprites.splice(index, 1);
                        }

                        // アニメーションを停止するために ticker から remove
                        app.ticker.remove(moveSprite);

                        // 配列が空になったらスプライト作成
                        if (sprites.length === 0) {
                            createSprites();
                        }
                    }
                };

                // 毎フレームごとに移動処理を行う
                app.ticker.add(moveSprite);
            }

        }
    </script>
</body>

</html>

配列管理のところを抜粋します。

0.配列の情報を定義する
スプライトを入れる器と、複製したい数を事前に決めます。

// 複数のスプライトを扱う
const sprites = [];     // 管理用の配列
const max = 5;          // スプライトの数

1.スプライトを定義して配列に追加する
for文でスプライト「ball」を複数定義、器「sprites」に追加します。
個別に操作したいので、タップ時にonTap関数を呼びます。

for (let i = 0; i < max; i++) {
    // ballの定義
    const ball = new PIXI.Sprite(texture);  // 定義
    ball.x = 70 * i;                // 初期位置x
    ball.y = 200;           // 初期位置y
    ball.scale.x = 4;               // x方向に4倍の大きさ
    ball.scale.y = 4;               // y方向に4倍の大きさ
    ball.interactive = true;        // タップ可能にする
    ball.buttonMode = true;         // PCでマウスカーソルのアイコンが変わる
    ball.on('pointerdown', onTap); // タップでonTap関数を呼ぶ
    app.stage.addChild(ball);       // 画面に表示

    // spritesに追加
    sprites.push(ball);             // 配列に追加
}

2.タップ時の動作を定義
onTap関数の引数eventを使うと、タップしたスプライトの情報を取得できます。
タップ後の動きは、「画面上部に移動して画面外で消える」としました。
moveSprite関数にその動きを記載しています。

// タップ時の動作を定義する関数
function onTap(event) {
    // タップしたスプライトを取得
    const clickedSprite = event.target;

    // スプライトを上方向に移動させるアニメーション
    const moveSprite = () => {
        clickedSprite.y -= 5;  // 5pxずつ上に移動
        if (clickedSprite.y + clickedSprite.height < 0) {
            // 画面外に出たら削除
            app.stage.removeChild(clickedSprite);
            clickedSprite.destroy();

            // 配列からも削除
            const index = sprites.indexOf(clickedSprite);
            if (index !== -1) {
                sprites.splice(index, 1);
            }

            // アニメーションを停止するために ticker から remove
            app.ticker.remove(moveSprite);

            // 配列が空になったらスプライト作成
            if (sprites.length === 0) {
                createSprites();
            }
        }
    };

    // 毎フレームごとに移動処理を行う
    app.ticker.add(moveSprite);
}

const moveSprite = () => {}は、アロー関数という記法みたいです。
():引数を入れるところ
=> :アロー(矢印)、関数名を省略して書ける
{}:実際の関数の中身

関数名を省略した関数をmoveSpriteに入れ、毎フレーム処理するイベントに追加・削除しています。
スプライトが画面外に移動したらsprites.splice(index, 1)で配列から削除。
(「index !== -1」で要素が配列にあるか確認してるけど、不要かも?)

配列が空かどうかはsprites.lengthで確認します。
空になったときにスプライト作成処理を呼ぶことで無限に遊べるね!

おわりに

スプライトを複製して配列で管理するとゲームっぽい!
色んな使い道がありそうなので、何か面白いことをしたいですね。

おわり

コメント

タイトルとURLをコピーしました