RPGツクールMVでWindow_Selectableの使い方まとめ

この記事では、RPGツクールMVのWindow_Selectableクラスの使い方をまとめていく。

Window_Selectable とは?

アイテム一覧や武器一覧などのリスト形式のWindowを作成する時に使えるクラス。

Window_Selectableを継承したクラスを定義して使う。

Window_Selectableの使い方

使い方は以下の通り。特に重要なのは、maxItemsdrawItem(index)の 2つのメソッドだ。


class Window_ItemList extends Window_Selectable { /** * constructorで、windowの表示する位置、windowの幅を指定する。 */ constructor(x, y, width, height) { super(x, y, width, height); // リストの表示に使うデータを配列で用意する。変数名は何でもよい。 this._items = []; // 描画するためのメソッド。 Window_Selectable側で実装している。 this.refresh(); } /** * setItems: これもメソッド名などは何でもよい。 */ setItems(items) { this._items = items; this.refresh(); }; /** * 全てのリストの個数を定義する。これは必ず定義する必要がある。 * * リストで表示したい要素の数を定義することで、 * Window_Selectableがリスト表示のスクロール処理などを良い感じにしてくれる。 */ maxItems() { return this._items.length; }; /** * 各要素を描画する際に使うメソッド。 これもユーザーが必ず定義すること。 * * 引数の index は、何番目の要素が格納される。 * */ drawItem(index) { // 要素の中身を取得する。 const item = this._items[index]; // itemRect: 現在のindexの要素の描画範囲を取得できる。 // これで rect.x rect.y rect.width rect.height などで描画に必要な情報を取得できる。 const rect = this.itemRect(index); const priceWidth = 96; rect.width -= priceWidth; // 実際に描画する。 this.drawItemName(item, rect.x, rect.y, rect.width); this.drawText(item.price + ' G', rect.x + rect.width, rect.y, priceWidth, 'right'); }; }

Windowを定義した後は、Sceneでこれを定義するとよい。

class Scene_Sample extends Scene_MenuBase {

    create() {
        super.create();

        this._itemListWnd = new Window_ItemList(100, 100, 400, 800);

        // なにか適当な配列を格納する。
        this._itemListWnd.setItems([]);
    }
}

何番目の要素を選択しているかを取得したい

実際にWindow_Selectableを使うときは、Window_Selectableで選択した後に 何かしらの処理をしたい事が大半だろう。

もし、Window_Selectableが選択している要素を取得したい場合は、以下のようにすれば良い。

class Window_ItemList extends Window_Selectable {

    constructor(x, y, width, height, confirmWnd) {
        super(x, y, width, height);

        this._confirmWnd = confirmWnd;

        // リストの表示に使うデータを配列で用意する。変数名は何でもよい。
        this._items = [];

        // 描画するためのメソッド。 Window_Selectable側で実装している。
        this.refresh();
    }

    /**
     * リストで要素を選択するたびに呼ばれるメソッド。
     * 
     * このメソッドをoverrideすることで、
     * 選択した時に追加処理ができる。
     * 
     */
    select(index) {
        super.select(index);
        const item = this._items[index];

        this._confirmWnd.setItem(item);
    }

}

上記の例ではconfirmWndという別のウィンドウに選択中のアイテムの情報を与える、 という処理を行っている。

また、何番目の要素を選択しているかを取得する方法として、index()メソッドを使う方法もある。

class Scene_Sample extends Scene_MenuBase {

    create() {
        super.create();

        this._itemListWnd = new Window_ItemList(100, 100, 400, 800);

        // なにか適当な配列を格納する。
        this._itemListWnd.setItems([]);
    }

    update(){
        const index = this._itemListWnd.index();
    }
}

実際にindex()メソッドを単体で使うよりも、クラス側でgetItem()のようなメソッドを定義して使うほうが良いだろう。

class Window_ItemList extends Window_Selectable {

    getItem(){
        return this.index() >= 0 ? this._items[this.index()] : null;
    }
}

index()メソッドは何も選択していない時は-1を返すので、それを配慮した処理にしている。

Window_Selectableのデザイン、配置を変えたい。

Window_Selectableのデザイン、配置を変えたい場合は、maxCols, itemHeightを変更すると良い。

デフォルトでは、以下のように設定されているので、これらを自分好みにカスタマイズすればよい。

class Window_ItemList extends Window_Selectable {

    // 1 であれば、1行ごと。 2であれば、1行につき2つのアイテムが表示される
    maxCols() {
        return 1;
    };

    // これはこのままで良いかも。
    itemWidth() {
        return Math.floor((this.width - this.padding * 2 +
                        this.spacing()) / this.maxCols() - this.spacing());
    };

    // 1つの要素ごとの高さを指定できる。
    itemHeight() {
        return this.lineHeight();
    };
}