イベント
はじめに
イベントは、柔軟なリスナーとディスパッチシステムを通じて、エンティティが互いに通信する方法です。イベント・リスナー
リスナー
Property | Type | 商品説明 |
---|---|---|
ターゲット | イード | イベントがディ スパッチされたエンティティ。 |
カレントターゲット | イード | イベントがリッスンされたエンティティ。 |
name | ストリング | イベント名 |
データ | いずれも | イベント・カスタム・データ |
イベント・リスナーの作成
追加リスナー
world.events.addListener(target, name, listener)
パラメータ一覧
tip
world.events.globalId`をターゲットとして、グローバル・イベント・リスナーを作成することができる。
Property | Type | 商品説明 |
---|---|---|
ターゲット | イード | ターゲット・エンティティへの参照。 |
name | ストリン グ | リッスンするイベント名。 |
リスナー | リスナー | イベントがトリガーされたときのコールバック関数 |
イベントハンドラの作成
エンティティにイベントリスナーを追加する場合、特にコンポーネントが複数のエンティティに追加される場合は、意図したとおりに機能するようにハンドラを正しく設定することが重要です。 ハンドラーの不適切な作成は、陳腐な参照や予期せぬ動作につながる可能性がある。
例えば、NPCエンティティのハンドラを作成し、破損イベントをリッスンするとします。 ハンドラは、イベントが発生したときに、いくつかのスキーマとデータ値を更新しなければならない。
誤った例
import * as ecs from '@8thwall/ecs'
import { addCleanup, doCleanup } from './cleanup'
ecs.registerComponent({
name: 'npc',
schema: {
isInjured: ecs.boolean,
}
data: {
bpm: ecs.f32,
}
add: (world, component) => {
// ハンドラの作成が正しくない
const damagedHandler = (e) => {
component.schema.isInjured = true
component.data.bpm += 30
}
world.events.addListener(component.eid, 'damaged', damagedHandler)
const cleanup = () => {
world.events.removeListener(component.eid, 'damaged', damagedHandler)
}
addCleanup(component, cleanup)
},
remove: (world, component) => {
doCleanup(component)
},
})
この例では
- ハンドラ damagedHandler は
component.schema
とcomponent.data
を直接参照する。 - コンポーネントが複数のエンティティに追加されると、ハンドラ内のコンポーネント参照は古くなります。
- これは、ハンドラーが不正確なデータを操作する原因となり、バグを引き起こす可能性がある。
正しい例
ハンドラが正しいエンティティデータを操作するようにするには、コンポーネントの dataAttribute
と schemaAttribute
をハンドラに渡し、ハンドラ内でカーソルをフェッチするためにそれらを使用する。
import * as ecs from '@8thwall/ecs'
import { addCleanup, doCleanup } from './cleanup'
// ダメージハンドラを作成する関数
const createDamagedHandler = (dataAttribute, schemaAttribute) => (e) => {
const dataCursor = dataAttribute.cursor(e.target)
const schemaCursor = schemaAttribute.cursor(e.target)
schemaCursor.isInjured = true
dataCursor.bpm += 30
}
ecs.registerComponent({
name: 'npc',
schema: {
isInjured: ecs.boolean,
},
data: {
bpm: ecs.f32,
},
add: (world, component) => {
// 正しいハンドラ作成
const damagedHandler = createDamagedHandler(component.dataAttribute, component.schemaAttribute)
world.events.addListener(component.eid, 'damaged', damagedHandler)
const cleanup = () => {
world.events.removeListener(component.eid, 'damaged', damagedHandler)
}
addCleanup(component, cleanup)
},
remove: (world, component) => {
doCleanup(component)
},
})
イベントリスナーの削除
removeListener
world.events.removeListener(target, name, listener)
パラメータ一覧
Property | Type | 商品説明 |
---|---|---|
ターゲット | イード | ターゲット・エンティティへの参照。 |
name | ストリング | リッスンするイベント名。 |
リスナー | リスナー | イベントがトリガーされたときのコールバック関数 |