본문으로 건너뛰기
cccskills
무료GitHub에 공개

melonjs-events

Use melonJS events and renderable lifecycle callbacks to react to updates, state changes, loading, and pointer movement. Learn how to remove listeners with the same handler and context, and where pooled objects need cleanup to avoid repeated subscriptions.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

원문원문 설명 보기

Use this skill for the melonJS event bus and lifecycle hooks — subscribing to engine events, the per-frame and per-state event names, renderable lifecycle callbacks, and how to unsubscribe without leaking. Triggers on: event.on, event.off, event.once, event.emit, GAME_UPDATE, GAME_BEFORE_DRAW, LEVEL_LOADED, LOADER_COMPLETE, STATE_CHANGE, CANVAS_ONRESIZE, POINTERMOVE, WORLD_STEP, onActivateEvent, onDeactivateEvent, onDestroyEvent, lifecycle, subscribe, listener.

melonjs/melonJS스타 6,429(GitHub 6,429 + cccskills 0)

실행 점수 미검증

설치 방법 보기

이럴 때 유용합니다

  • Reacting to game updates or state changes
  • Listening for asset loading completion
  • Cleaning up listeners on pooled objects
  • Choosing a safe removal method during collisions

포함된 파일(1)

  • SKILL.md7.0 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Events and lifecycle

The bus

import { event } from "melonjs";

const onUpdate = () => { /* … */ };
const unsubscribe = event.on(event.GAME_UPDATE, onUpdate);  // on() returns its own off()
event.once(event.LEVEL_LOADED, () => { /* … */ });

// two ways to undo it — the same reference, or the returned function
event.off(event.GAME_UPDATE, onUpdate);
unsubscribe();

event.on/once/off/has all take an optional third context argument, invoked as the handler's this. off matches on the pair — handler identity AND context identity. on(EVT, fn, this) followed by off(EVT, fn) removes nothing, silently.

Store the handler reference, or use the context argument. An inline arrow or a fresh .bind(this) in the on call can never be removed — that is the standard way to leak listeners in melonJS.

// ✗ unremovable
event.on(event.GAME_UPDATE, this.tick.bind(this));

// ✓ keep the bound reference
this._tick = this.tick.bind(this);
event.on(event.GAME_UPDATE, this._tick);
// later: event.off(event.GAME_UPDATE, this._tick);

// ✓ or skip the bind entirely — the context is part of the identity
event.on(event.GAME_UPDATE, this.tick, this);
// later: event.off(event.GAME_UPDATE, this.tick, this);

Custom event names work at runtime (event.emit("my.custom.event", payload)), but on/emit are typed against a closed map of the engine's own events, so in TypeScript a name outside that map is a compile error. Use your own emitter for game events in a .ts project.

The events worth knowing

Per frame

eventwhen
GAME_BEFORE_UPDATE / GAME_UPDATE / GAME_AFTER_UPDATEaround the world update — GAME_UPDATE is not emitted while paused
GAME_BEFORE_DRAW / GAME_AFTER_DRAWaround the draw pass
WORLD_STEPafter the physics step
TICKthe raw engine tick

Lifecycle

eventwhen
BOOT, GAME_INIT, VIDEO_INITengine start-up
STATE_CHANGE, STATE_PAUSE, STATE_RESUME, STATE_STOPstate machine
STAGE_RESETa stage was reset
LEVEL_LOADEDa Tiled level finished loading
LOADER_PROGRESS, LOADER_COMPLETE, LOADER_ERRORasset loading
BLUR / FOCUSthe page lost or regained focus
CANVAS_ONRESIZE, VIEWPORT_ONRESIZErelayout hooks
POINTERMOVEglobal pointer movement

Use LOADER_PROGRESS / LOADER_COMPLETE. The loader.onProgress / loader.onload / loader.onError properties were deprecated in 18.2.0 and removed in 20.3: they were module-level let bindings on an ES module namespace, so loader.onProgress = fn threw and the documented migration path never worked. For completion, loader.preload(assets, onloadcb) also takes the callback directly.

Renderable lifecycle callbacks

Prefer these over bus subscriptions where they fit — the engine calls them at the right times and there is nothing to unsubscribe:

callbackwhen
onActivateEvent()addChild-ed into a container that is already attached to the world root (a Container forwards it to its children)
onDeactivateEvent()removed from its container — including the automatic world clear on a state change
onDestroyEvent()destroy() ran; called with no arguments from the container-removal path
onCollisionStart / onCollisionActive / onCollisionEndcontacts

Note the activate gate: adding a child to a detached container fires nothing. The callback arrives later, when that container itself is added to the world. And an isPersistent renderable survives the world clear between stages, so it gets no fresh onActivateEvent on the next state.

Pair subscriptions with activate/deactivate, not the constructor. This is the rule that keeps pooled objects working:

onActivateEvent() {
    this._tick = this.update.bind(this);
    event.on(event.GAME_UPDATE, this._tick);
    input.registerPointerEvent("pointerdown", this, this._onDown);
}
onDeactivateEvent() {
    event.off(event.GAME_UPDATE, this._tick);
    input.releasePointerEvent("pointerdown", this);
}

Pool-recycled objects never fire onDestroyEvent on removal — removeChildNow first tries to return the child to the pool that built it, and only calls destroy() when nothing owns it. So anything taken from a createPool goes back to that pool instead. Anything you clean up there will not run. destroy() is also what calls releaseAllPointerEvents(this), which is why a pooled object must release its own pointer registrations in onDeactivateEvent.

Guard callbacks that can fire during teardown

Events can arrive while a stage is being dismantled, when the current state is already something else:

if (!state.isCurrent(state.PLAY)) return;

Without this, a "children emptied" handler can reset the wrong stage.

Removing objects from a collision callback

Contact callbacks fire inline inside the physics step, mid-iteration over the detector's pair list. container.removeChild() is safe there — it defers the actual removal to the next tick, which is exactly why it defers. The immediate forms are the dangerous ones: removeChildNow() tears the object down under the iteration, via the internal destroy() it calls, which nulls pos and body. (destroy() is engine teardown and is not in the published types, so removeChildNow is the call a game actually makes.) The builtin detector guards the pair it is currently resolving, but nothing guarantees that for the rest of the step or for another adapter.

Use removeChild(), or flag the work and drain it from Stage.update.

Symptom → cause

symptomcause
handler still fires after removing the objectevent.off given a different function reference, or a different context than on got
handlers accumulate on pooled objectssubscribed in the constructor rather than onActivateEvent
cleanup never runs on a pooled objectpooled removal does not fire onDestroyEvent
crash during a stage switchcallback ran mid-teardown — guard with state.isCurrent
crash after a collisionremoveChildNow() inside a contact callback — use removeChild()
progress callbacks never fireassigned loader.onProgress (removed in 20.3) instead of subscribing to LOADER_PROGRESS
onActivateEvent never runsthe child was added to a container not yet attached to the world

Related skills

  • melonjs-scenes-and-state — the state machine and stage lifecycle
  • melonjs-performance — pooling, and why activate/deactivate pairing matters

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

melonjs

무료

Use this entry point to find the melonJS guide for a game development task, from application setup and scenes to sprites, input, physics, audio, and 3D. It also points to companion packages and the API index when the guides do not cover a need.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Choose a guide for a melonJS game task
  • Find the right setup steps for a new game
  • Locate guidance for a 3D scene or imported model
melonjs/melonJS6.4천2026년 10월 29일 업데이트

Update older melonJS code for version 20.x. Review the asynchronous Application setup, renderer changes, post-effect API, and deprecated exports so you can identify outdated patterns when migrating or debugging expected APIs.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Migrating a game from melonJS 19.x
  • Checking why an older API is missing
  • Replacing deprecated shader assignments
melonjs/melonJS6.4천2026년 10월 29일 업데이트

Build 3D or 2.5D scenes in melonJS with cameras, meshes, billboards, lights, shadows, and depth sorting. This guide explains the engine’s Y-down and +Z-forward coordinates, camera setup, transparency, and fog, and identifies features that require a GPU renderer instead of the Canvas fallback.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Setting up a Camera3d for a game stage
  • Placing meshes, billboards, or repeated instances
  • Fixing depth order or transparency in a 3D scene
melonjs/melonJS6.4천2026년 10월 29일 업데이트

Load glTF, GLB, or OBJ/MTL assets into melonJS and understand how their materials, lights, animations, shadows, and instances are handled. The guide explains loader options and common format limitations so you can configure scenes and diagnose missing or incorrectly rendered asset features.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Loading a glTF or GLB scene into a melonJS level
  • Adding a static OBJ model with its MTL material
  • Checking why imported materials or lights look different
melonjs/melonJS6.4천2026년 10월 29일 업데이트

Manage sound in melonJS games: load audio, play effects and looping background tracks, control volume, and place sounds in the game world. It also covers generated tones and noise, whole-mix effects, and common causes of silent playback.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Loading sound files and choosing supported audio formats
  • Playing sound effects and looping background music
  • Positioning sounds around a player or game object
melonjs/melonJS6.4천2026년 10월 29일 업데이트

Use this skill to control melonJS cameras and draw shapes, lines, and gradients. It covers target following, camera bounds and effects, coordinate conversion, clipping, rendering into a canvas target, and reading rendered pixels for images or data.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Making a camera follow a player within world bounds
  • Converting pointer or 3D positions to screen coordinates
  • Drawing shapes or gradients in a custom draw method
melonjs/melonJS6.4천2026년 10월 29일 업데이트

melonjs의 스킬 모두 보기

이 스킬의 문제 신고