1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[ScriptAPI参考書] イベントの操作 構造編 #4

Last updated at Posted at 2025-02-15

目次

はじめに

今回から、ScriptAPIの基本、イベントの操作を扱っていきます。
構造編ということで、ScriptAPIのイベントとは何なのか、ということについて考えたいと思います。
次回以降、どのようなイベントがあるのかを紹介していきます。

この「ScriptAPI参考書」シリーズではマインクラフト統合版のScriptAPIについて基礎から応用、例文まで詳細に解説し、ScriptAPI開発者や、ScriptAPIの開発を始めようと思っている人の助けになることを目的としています。

また、このシリーズを読むにあたって、ある程度のマインクラフトとJavaScriptの事前知識が必要になってくることがあります。

注意: このシリーズではMinecraft Bedrock Editionを省略してマインクラフトと表記しています。

前回: 基本的な扱い
次回: 準備中...

イベントとは

先ずはじめに、プログラミングで言うイベントとは、ScriptAPIに限らず、大体のライブラリにはイベントが備わっており、そのライブラリ特有のイベントが発生した時に、そのイベントの情報をプログラム内で扱えるようにするためのものです。

例えばScriptAPIの場合では、任意のプレイヤーがチャットを送信した時や、アイテムを使った時など、限界はありますが様々な事象のデータが取得出来ます。

イベントの種類

ScriptAPIのイベントは、@minecraft/serverworldsystemにのみ存在しており、他のモジュールにはありません。
また、worldsystemのどちらにもafterEventsbeforeEventsが存在しており、これらの使い分けでイベントの操作を行います。

afterEvents

そのイベントが発生した後に実行されます。
通常、こちらのイベントを使用する事が多いです。
次回のアフターイベント編で紹介します。

beforeEvents

そのイベントが発生する前に実行されます。
この特性により、イベントの発生をキャンセルすることが出来ます。
例えば、チャットの送信のイベントをキャンセルすれば、メッセージの送信が取り消されるといった具合です。
但し、一部制限が存在しています。
次々回のビフォーイベント編で紹介します。

イベントの扱い

イベントの登録

ScriptAPIでイベントを登録するときは、基本的に以下の様なコードが一般的です。

world.afterEvents.itemUse.subscribe((ev) => {
    // evにイベントのデータが渡される
});

これはどのようになっているかというと、subscribeという関数の引数に、「evという引数を持った、そのイベントが発生した際に実行される関数」を渡している形になります。evにはイベントが発生した際のイベントの情報が渡されます。

ここが少しややこしいところで、理解が出来なくてもプログラム自体は書けますが、ここが分かることでかなり根本的な理解を得られ、大変有益なので、理解に難がある方は「イベントハンドラ」や「イベントリスナー」等と検索してください。

ここで使用しているevという引数名は、eventの略で、ScriptAPIのイベントではよく見る引数名です。人によってはeventitemUseなどと名付ける人も居ますが、ここは好みの問題ですね。
因みに、公式のJSDocでは、itemUseイベントならitemUseのように、イベント名が引数になっていることが多いようです。

また、ここではアロー関数を使用していますが、当然通常の関数を渡すことも出来ます。

直接関数を渡す
world.afterEvents.itemUse.subscribe(function (ev) {
    // 処理
});
定義されている関数を渡す
function onItemUse(ev) {
    // 処理
}

world.afterEvents.itemUse.subscribe(onItemUse);

これは、JavaScriptではモジュールやライブラリ等を使っているとよく出てくる形で、他の場所でも活用出来るので、覚えておいて損はないでしょう。

登録オプション

イベントを登録する時、第二引数としてオプションを入力出来るイベントがあります。

playerBreakBlockイベントが一例で、このイベントはプレイヤーがブロックを破壊した時に実行されますが、オプションを使用して特定のブロックを破壊した時のみ実行させることが出来ます。

world.afterEvents.playerBreakBlock.subscribe((ev) => {
    // 処理
}, {
    blockTypes: [
        // どのブロックを破壊した時にイベントを実行させるかを指定出来る
    ]
});

イベントの解除

実際にモジュールを入れて書いた経験がある方は既知かもしれませんが、subscribeともう一つunsubscribeというメソッドがあります。
このメソッドは名前の通り、イベントの登録を解除するためのもので、登録時に渡した関数を引数に入れることで、その関数の登録を解除することができます。

function onItemUse(ev) {
    // 処理
}

world.afterEvents.itemUse.subscribe(onItemUse); // イベントの登録

world.afterEvents.itemUse.unsubscribe(onItemUse); // イベントの登録の解除

例えば、以下のようにすることで、一度だけイベントを拾う関数を簡単に作成することができます。

function onceItemUse(ev) {
    // 処理
    
    world.afterEvents.itemUse.unsubscribe(onceItemUse); // イベントの解除
}

world.afterEvents.itemUse.subscribe(onceItemUse); // イベントの登録

実行したときに処理と同時にイベントの登録の解除をするような構造ですね。

応用として、subscribe()は返り値として、引数に入れたコールバック関数を返すので、以下のようにイベントの解除を記述することも出来ます。

const itemUse = world.afterEvents.itemUse.subscribe((ev) => { // イベントの登録
    // 処理
    
    world.afterEvents.itemUse.unsubscribe(itemUse); // イベントの解除
});

最後に

今回は、ScriptAPIにおいてイベントとは何か?を中心として紹介しました。
この記事を参考にイベントの扱いについて少しでも理解して頂けたら、とても幸いです。
冒頭にも記述した通り、次回以降はどのようなイベントがあるのかを紹介していきます。
今後ともよろしくお願いいたします。

1
1
1

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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?