melonJSを使ったゲーム制作で、目的に合う専門ガイドを選ぶための入口です。初期化から描画、入力、物理演算、音声、2D・3D機能まで案内します。
- melonJSで作る内容に合うガイドを探したいとき
- 新しいゲームの初期化手順を知りたいとき
- 3Dやモデル読み込みの参照先を探したいとき
melonJS 20.xでゲームを起動し、初期化や描画先の選択、画面へのオブジェクト追加、シーン切り替えまでの基本を押さえられます。
Use this skill when starting or bootstrapping a melonJS game, creating the Application, choosing a renderer, or setting up the first scene. Covers the mandatory async init, the world container, adding renderables, and the WebGPU/WebGL 2/Canvas fallback. Triggers on: melonjs, new Application, app.init, app.world, video.AUTO, video.WEBGL, video.CANVAS, Stage, state.change, getting started, bootstrap.
実行スコア 未検証
インストール方法を見るmelonJS 20.xでゲームを起動するときの基本を扱います。Applicationを作成したあとにawait app.init()を呼ぶ手順や、描画対象をapp.worldへ追加する方法、Stageとstateを使ったシーンの切り替え方を確認できます。描画方式はvideo.AUTOでWebGPU、WebGL 2、Canvasの順に選ばれます。実行環境によって方式が異なり、シェーダーなど一部の機能はCanvasでは動かない点も説明します。
新しいmelonJSゲームのひな形を作るときや、画面が真っ白になる、SpriteやTextの生成でエラーが出るなど、起動直後の問題を調べたいときに役立ちます。古いバージョンの初期化方法を使っていないか確認する際にも参照できます。
video.AUTOではどの描画方式が選ばれ、機能にどんな違いがありますか?」Stageで切り替える方法を説明して」対象はmelonJS 20.xです。19.x以前とは初期化方法などが異なります。
この紹介文は、公開されている SKILL.md をもとに AI(OpenAI Codex)が作成しました。正確な仕様は下の原文を確認してください。
インストールする前に、エージェントに与えられる指示の中身を確認できます。
Bootstrapping a melonJS 20.x game: the
Applicationlifecycle, the mandatoryawait app.init(), the world container, and what the renderer fallback means for feature availability.
Applies to: melonJS 20.x. Older major versions differ — see the
melonjs-20-migration skill.
Application construction is synchronous but initialisation is not. init()
returns a promise and must be awaited before building any renderable, loading
assets, or entering a scene.
import { Application, Text } from "melonjs";
const app = new Application(1218, 562, {
parent: "screen", // id of the DOM element to mount into
scale: "auto",
backgroundColor: "#202020",
});
await app.init(); // ← REQUIRED. Nothing below works without it.
app.world.addChild(
new Text(609, 281, {
font: "Arial",
size: 160,
fillStyle: "#FFFFFF",
textAlign: "center",
textBaseline: "middle",
text: "Hello World !",
}),
);
This is the single most common thing to get wrong. On 19.x the constructor
called init(width, height, options) for you; on 20.x init() takes no
arguments and calling — and awaiting — it is your job. Nothing that follows
names the missing call. The constructor does build app.world, so adding a
plain renderable succeeds and simply never draws — no canvas is appended and the
app never subscribes to the frame tick — while constructing a Sprite or a
Text throws Cannot read properties of undefined (reading 'renderer'),
because the global game those two fall back on is only set once the first
init() resolves. Either way app.renderer and app.viewport stay undefined
and the page stays blank.
init() is asynchronous because acquiring a WebGPU device is asynchronous. There
is no synchronous alternative.
The bootstrap needs await at module scope. In an ES module that is fine. If the
surrounding tooling does not allow it, wrap it:
async function main() {
const app = new Application(800, 600, { parent: "screen" });
await app.init();
// …
}
void main();
video.AUTO (the default) tries WebGPU → WebGL 2 → Canvas and uses the first
that works.
import { video } from "melonjs";
const app = new Application(800, 600, {
parent: "screen",
renderer: video.AUTO, // default; or video.WEBGPU / video.WEBGL / video.CANVAS
});
Two consequences worth knowing before writing rendering code:
Pin the renderer explicitly (video.WEBGL) only when you have a reason to. It
costs you the WebGPU path and the Canvas fallback.
app.world is the root Container. Everything drawn is a descendant of it.
app.world.addChild(sprite, 10); // 10 is the z / draw order
Pass the z-order as the second argument to addChild — it is the only form
that works. renderable.z does not exist as a property, setting depth before
addChild is overwritten by autoDepth, and setting it afterwards does not
resort. See the melonjs-renderables skill for the full explanation.
For anything beyond a single screen, use Stage subclasses and the state
manager rather than mutating app.world directly:
import { Stage, state } from "melonjs";
class PlayScreen extends Stage {
onResetEvent() { /* build the scene */ }
onDestroyEvent() { /* tear it down */ }
}
state.set(state.PLAY, new PlayScreen());
state.change(state.PLAY);
onResetEvent runs every time the state is entered, not once — build scene
content there, not in the constructor.
Assets are declared and preloaded through loader; audio needs audio.init()
with the formats you ship before any audio asset is preloaded.
import { audio, loader } from "melonjs";
loader.setOptions({ crossOrigin: "anonymous" }); // needed for remote assets
audio.init("mp3,ogg"); // BEFORE preloading audio
await loader.preload([
{ name: "tileset", type: "image", src: "data/img/tileset.png" },
{ name: "jump", type: "audio", src: "data/sfx/" }, // directory, not file
]);
Two ordering rules that produce confusing failures when missed:
audio.init() must run before any audio asset is preloaded, and names the
formats you actually ship. Preloading first throws "target audio extension(s)
should be set through me.audio.init() before calling the preloader".src is a directory, not a file. The loader appends the asset
name plus each configured extension, so a full filename gives you a 404.anchorPoint defaults to the centreRenderable.anchorPoint is (0.5, 0.5), so pos is an object's centre, not
its top-left. Container forces (0, 0) instead.
Writing top-left math against a centred anchor puts everything half a sprite off with no error — it is the most common source of "close but subtly wrong" placement.
| symptom | cause |
|---|---|
blank page, nothing drawn, or a TypeError reading renderer from new Sprite / new Text | missing await app.init() |
| objects draw in the wrong order | .z/depth set instead of addChild(child, z) — .z is not even a real property |
| shader/post effect does nothing, warning in console | running on the Canvas renderer |
| audio 404s | audio asset src given as a file rather than a directory |
| scene content appears once and never resets | scene built in the constructor instead of onResetEvent |
| everything offset by half a sprite | top-left math against the centred anchorPoint default |
a Tween or ParticleEmitter does nothing | .start() / streamParticles() never called |
| cross-origin textures fail to load | missing loader.setOptions({ crossOrigin: "anonymous" }) |
melonjs-20-migration — what changed in 20.x that older code and older
training data get wrongmelonjs-renderables — custom Renderable subclasses, pointer events, post
effects and the traps in eachまだレビューはありません。使ってみた感想をお寄せください。
ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。
まだコメントはありません。最初のコメントを書いてみませんか。
melonJSを使ったゲーム制作で、目的に合う専門ガイドを選ぶための入口です。初期化から描画、入力、物理演算、音声、2D・3D機能まで案内します。
melonJS 19.x以前の知識を20.x向けに更新し、初期化や描画効果、廃止・非推奨APIの変更点を確認して移行時の不具合を調べられます。
melonJSの3D・2.5Dゲーム向けに、カメラ、メッシュ、ライト、奥行き順、透明表現やフォグの設定と座標系の注意点を確認できます。
melonJSでglTF・GLBやOBJ・MTLの3Dモデルを読み込み、マテリアルやライト、アニメーション、影、インスタンスの扱い方を確認できます。
melonJSで効果音やBGMを読み込み、再生・停止・音量調整するほか、位置に応じた音や音声合成、ミックス全体へのエフェクト設定を扱うスキルです。
melonJSのカメラ追従や画面効果、座標変換、図形描画を実装する際の要点を確認できます。描画のクリッピングやCanvasへの焼き込み、ピクセルの読み出しも扱います。