loading-assets について
Phaser の Loader を解説する、ゲーム開発者向けのスキルガイドです。Scene でのアセットのキュー登録、対応ファイル形式、共有キャッシュ、読み込み進捗を追跡するイベントを扱います。
主な機能
- 01画像、音声、動画の読み込み
- 02データ、フォント、タイルマップの読み込み
- 03パックマニフェストによるファイル整理
- 04グローバルキャッシュでのアセット共有
- 05進捗と読み込みエラーの監視
活用シーン
- 01Scene の開始前にゲームアセットを読み込む
- 02アセット読み込みの進捗バーを作る
- 03マニフェストからアセット一式を読み込む
- 04読み込みに失敗したファイルを処理する
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ phaserjs/ phaser --skill loading-assetsインストール後、Claude Code で/loading-assetsを入力して読み込まれたか確認します。
同梱ファイルreferences/REFERENCE.md
詳細
アセットの読み込み
Phaser Loader(
this.load)は、画像、音声、JSON、タイルマップ、アトラス、フォント、スクリプトなど、すべての外部コンテンツの取得を処理します。アセットはpreload()でキューに追加され、並列で読み込まれ、すべての Scene からアクセスできるグローバルキャッシュに配置されます。
主要なソースパス: src/loader/LoaderPlugin.js、src/loader/File.js、src/loader/filetypes/、src/loader/events/
関連スキル: ../game-setup-and-config/SKILL.md、../scenes/SKILL.md、../sprites-and-images/SKILL.md
クイックスタート
class GameScene extends Phaser.Scene {
preload() {
this.load.image('logo', 'assets/logo.png');
}
create() {
this.add.image(400, 300, 'logo');
}
}
preload() で読み込まれたアセットは、create() が実行されるときに必ず準備が整っています。Loader は preload フェーズ中に自動的に開始されます。
基本概念
preload パターン
すべての Scene は preload() メソッドを定義できます。preload() が完了すると Loader が自動的に開始され、キューに追加されたすべてのファイルが完了するまで待ってから create() を呼び出します。
preload() {
// Queue files - they don't load immediately
this.load.image('sky', 'assets/sky.png');
this.load.spritesheet('dude', 'assets/dude.png', { frameWidth: 32, frameHeight: 48 });
this.load.audio('jump', 'assets/jump.mp3');
}
create() {
// All assets above are now available
this.add.image(400, 300, 'sky');
this.add.sprite(100, 450, 'dude');
this.sound.play('jump');
}
preload 以外での読み込み
preload() の外で this.load メソッドを呼び出す場合(たとえば create() 内やユーザー操作に応じて)、Loader を手動で開始する必要があります。
create() {
this.load.image('extra', 'assets/extra.png');
this.load.once('complete', () => {
this.add.image(400, 300, 'extra');
});
this.load.start();
}
URL の解決: baseURL、path、prefix
ファイルの最終的な URL は baseURL + path + filename として解決されます。これらはゲーム設定または実行時に設定できます。
preload() {
// Set base URL (prepended to all relative paths)
this.load.setBaseURL('https://cdn.example.com/');
// Set path (prepended after baseURL, before filename)
this.load.setPath('assets/images/');
// Set key prefix (prepended to the cache key, not the URL)
this.load.setPrefix('LEVEL1.');
// Loads from: https://cdn.example.com/assets/images/hero.png
// Cached with key: LEVEL1.hero
this.load.image('hero', 'hero.png');
// Absolute URLs bypass the path/baseURL
this.load.image('cloud', 'https://other-server.com/cloud.png');
}
これらはゲーム設定でも設定できます。
const config = {
loader: {
baseURL: 'https://cdn.example.com/',
path: 'assets/',
prefix: '',
maxParallelDownloads: 32,
crossOrigin: 'anonymous',
responseType: '',
async: true,
timeout: 0,
maxRetries: 2,
imageLoadType: 'XHR' // or 'HTMLImageElement'
}
};
グローバルキャッシュ
アセットは Scene ごとではなく、ゲームレベルのグローバルキャッシュに保存されます。ある Scene で読み込まれた画像は、他のすべての Scene で利用できます。テクスチャは game.textures(Texture Manager)に入ります。その他のデータは game.cache のサブキャッシュ(例: game.cache.json、game.cache.audio、game.cache.xml)に入ります。
読み込みイベント
Loader は読み込みライフサイクル全体を通じてイベントを発行します。これらはプログレスバーやローディング画面に使用します。
preload() {
this.load.on('progress', (value) => {
// value is 0 to 1
console.log(`Loading: ${Math.round(value * 100)}%`);
});
this.load.on('complete', () => {
console.log('All assets loaded');
});
this.load.on('loaderror', (file) => {
console.warn('Failed to load:', file.key);
});
this.load.image('bg', 'assets/bg.png');
}
一般的なパターン
画像とスプライトシートの読み込み
preload() {
// Single image
this.load.image('star', 'assets/star.png');
// Image with normal map (pass URL array: [texture, normalMap])
this.load.image('brick', ['assets/brick.png', 'assets/brick_n.png']);
// Sprite sheet (fixed frame sizes)
this.load.spritesheet('explosion', 'assets/explosion.png', {
frameWidth: 64,
frameHeight: 64,
startFrame: 0,
endFrame: 23,
margin: 0,
spacing: 0
});
// SVG (optionally rasterize at a specific size)
this.load.svg('logo', 'assets/logo.svg', { width: 400, height: 400 });
}
音声の読み込み
preload() {
// Single file
this.load.audio('bgm', 'assets/music.mp3');
// Multiple formats for cross-browser support
this.load.audio('bgm', ['assets/music.ogg', 'assets/music.mp3']);
// Audio sprite (JSON defines named regions within a single audio file)
this.load.audioSprite('sfx', 'assets/sfx.json', [
'assets/sfx.ogg',
'assets/sfx.mp3'
]);
}
JSON とタイルマップの読み込み
preload() {
// JSON data (stored in this.cache.json)
this.load.json('levelData', 'assets/level1.json');
// JSON with a dataKey to extract a sub-object
this.load.json('enemies', 'assets/data.json', 'enemies');
// Tiled tilemap (JSON format exported from Tiled)
this.load.tilemapTiledJSON('map', 'assets/map.json');
// CSV tilemap
this.load.tilemapCSV('csvmap', 'assets/level.csv');
// Impact tilemap
this.load.tilemapImpact('impactmap', 'assets/level.js');
}
create() {
const data = this.cache.json.get('levelData');
const map = this.make.tilemap({ key: 'map' });
}
アトラスの読み込み
preload() {
// JSON atlas (e.g., TexturePacker JSON Hash/Array)
this.load.atlas('sprites', 'assets/sprites.png', 'assets/sprites.json');
// XML atlas (e.g., Starling/Sparrow format)
this.load.atlasXML('ui', 'assets/ui.png', 'assets/ui.xml');
// Multi-atlas (atlas split across multiple textures)
this.load.multiatlas('world', 'assets/world.json', 'assets/');
// Unity texture atlas format
this.load.unityAtlas('chars', 'assets/chars.png', 'assets/chars.txt');
// Aseprite atlas
this.load.aseprite('knight', 'assets/knight.png', 'assets/knight.json');
}
create() {
this.add.sprite(400, 300, 'sprites', 'walk_01');
}
ビットマップフォントの読み込み
preload() {
// Requires both a texture and XML/JSON font data file
this.load.bitmapFont('pixels', 'assets/font.png', 'assets/font.xml');
}
create() {
this.add.bitmapText(100, 100, 'pixels', 'Hello World', 32);
}
動画の読み込み
preload() {
// Load a video file. Third arg: noAudio flag (default false)
this.load.video('intro', 'assets/intro.mp4');
// Load without audio track
this.load.video('bg_loop', 'assets/loop.mp4', true);
}
Web フォントの読み込み
preload() {
// Load a font file (ttf, otf, woff, woff2)
this.load.font('myFont', 'assets/myfont.ttf', 'truetype');
// With optional font face descriptors
this.load.font('boldFont', 'assets/bold.woff2', 'woff2', {
weight: 'bold',
style: 'normal'
});
}
パックファイルの読み込み
パックファイルは、一度に読み込む複数のアセットを記述した JSON ファイルです。アセットマニフェストの整理に便利です。
preload() {
this.load.pack('pack1', 'assets/pack.json');
}
パックファイルの形式:
{
"section1": {
"baseURL": "assets/",
"files": [
{ "type": "image", "key": "bg", "url": "bg.png" },
{ "type": "atlas", "key": "chars", "textureURL": "chars.png", "atlasURL": "chars.json" }
]
}
}
プログレスバーを使った読み込み
preload() {
const progressBar = this.add.graphics();
const progressBox = this.add.graphics();
progressBox.fillStyle(0x222222, 0.8);
progressBox.fillRect(240, 270, 320, 50);
this.load.on('progress', (value) => {
progressBar.clear();
progressBar.fillStyle(0xffffff, 1);
progressBar.fillRect(250, 280, 300 * value, 30);
});
this.load.on('complete', () => {
progressBar.destroy();
progressBox.destroy();
});
// Queue your assets
this.load.image('sky', 'assets/sky.png');
// ... more assets
}
すべてのファイルタイプのリファレンス
すべての this.load メソッドは、位置引数または単一の設定オブジェクトを受け取ります。また、同じタイプの複数のファイルを一括読み込みするために、設定オブジェクトの配列も受け取ります。完全なパラメータ表については references/REFERENCE.md を参照してください。
テクスチャ: image、spritesheet、atlas、atlasXML、multiatlas、unityAtlas、aseprite、svg、htmlTexture、texture(圧縮)
音声/動画: audio、audioSprite、video
データ: json、xml、text、binary、html、css、glsl
フォント: bitmapFont、font
タイルマップ: tilemapTiledJSON、tilemapCSV、tilemapImpact
その他: animation、pack、script、scripts、plugin、scenePlugin、sceneFile
イベント
すべてのイベントは Loader インスタンス(this.load)で発行されます。
| イベント文字列 | コールバックシグネチャ | 説明 |
|---|---|---|
'addfile' | (key, type, loader, file) | 読み込みキューにファイルが追加されました |
'start' | (loader) | Loader が開始されました。進捗はゼロです |
'load' | (file) | 単一のファイルの読み込みが完了しました(処理/キャッシュの前) |
'fileprogress' | (file, percentComplete) | ファイルごとのダウンロード進捗(0〜1)。ブラウザが lengthComputable を提供する場合のみ発行されます |
'progress' | (value) | 全体の読み込み進捗が更新されました(0〜1) |
'postprocess' | (loader) | すべてのファイルが読み込まれ、処理されました。内部クリーンアップの前です |
'filecomplete' | (key, type, data) | 任意のファイルの読み込みと処理が完了しました |
'filecomplete-{type}-{key}' | (key, type, data) | 特定のファイルが完了しました(例: 'filecomplete-image-hero') |
'loaderror' | (file) | ファイルの読み込みに失敗しました |
'complete' | (loader, totalComplete, totalFailed) | キュー内のすべてのファイルが完了しました |
イベントのライフサイクル順序
'start'- ローダーが開始'fileprogress'- ファイルごとの進捗(利用可能な場合、ファイルごとに繰り返し)'load'- 各ファイルのダウンロードが完了'filecomplete-{type}-{key}'- 特定のファイルが処理され、キャッシュされる'filecomplete'- 汎用的なファイルごとの完了'progress'- 全体の進捗が更新される'postprocess'- すべてのファイルが完了、クリーンアップ前'complete'- すべてが終了
注意点とよくある間違い
キーはそのタイプ内で一意でなければなりません。 既存のものと同じキーで 2 つ目の画像を読み込むと、警告がログに記録され、スキップされます。置き換える必要がある場合は、まず Texture Manager から古いテクスチャを削除してください。
スプライトシートはアトラスとは異なります。 固定サイズのフレームのグリッド(インデックスで参照)には spritesheet() を使用します。名前付きフレームを持つパック済みテクスチャアトラスには atlas() を使用します。
preload 以外で this.load.start() を忘れる。 create() 以降で load メソッドを呼び出す場合、ローダーは自動的に開始されません。手動で this.load.start() を呼び出す必要があります。
パスは / で終わる必要があります。 this.load.setPath() を呼び出すと、スラッシュが自動的に追加されます。this.load.path を直接設定する場合は、末尾のスラッシュを自分で含める必要があります。
オーディオ形式のフォールバック。 クロスブラウザー対応のために、常に複数のオーディオ形式(最低でも OGG + MP3)を提供してください。ローダーはブラウザーがサポートする最初の形式を選択します。
パックファイルは baseURL/path/prefix を上書きできます。 パックファイル内の各セクションは、独自の baseURL、path、prefix の値を設定できます。これらはそのセクション内のファイルにのみ適用され、セクションの処理後に復元されます。
ファイルキーにはプレフィックスが含まれます。 this.load.setPrefix('MENU.') を設定し、キー 'bg' で画像を読み込むと、実際のキャッシュキーは 'MENU.bg' になります。アセットを参照する際は、その完全なキーを使用する必要があります。
maxRetries プロパティ(デフォルト: 2) は、ローダーが失敗したファイルを諦める前に再試行する回数を制御します。これは作成時に this.load.maxRetries に基づいてファイルごとに設定されます。ファイルが追加された後に調整しても、それらのファイルには影響しません。
画像の読み込みタイプ。 デフォルトでは画像は XHR(ブロブとして)経由で読み込まれます。ローダー設定で imageLoadType: 'HTMLImageElement' を設定すると、代わりに <img> タグによる読み込みを使用でき、一部の環境で CORS の問題に役立つことがあります。
ローカルファイルスキーム。 ローダーはデフォルトで file:// と capacitor:// をローカルスキームとして認識します(localSchemes 経由)。ローカルスキームから読み込まれたファイルは CORS ヘッダーをスキップします。
クロスオリジン。 別のドメインからアセットを読み込む際は、ローダー設定で crossOrigin: 'anonymous' を設定するか(または this.load.setCORS('anonymous') 経由で)、特にそれらのテクスチャを WebGL で使用する場合は設定してください。
キーは大文字と小文字を区別し、タイプごとにスコープが分かれます。 'Player' と 'player' は異なるキーです。画像キー 'player' とオーディオキー 'player' は競合せずに共存できます。
重複したキーは黙って無視されます。 'bg' がすでにテクスチャキャッシュに存在する場合、2 回目の this.load.image('bg', ...) 呼び出しは何も行いません。置き換えるには、まず古いアセットを削除してください。
シーンの update() は preload 中に発生しません。 アセットの読み込み中は update() が一時停止されます。ただし、preupdate、postupdate、render は引き続き発生します。
進捗は減少する可能性があります。 読み込みの途中で新しいファイルが追加された場合(たとえば、filecomplete の連鎖経由で)、合計ファイル数が増加するため、進捗値が下がることがあります。
シーンペイロード(preload の前に読み込む)
Scene コンストラクターで pack を定義することで、preload() が実行される前にファイルを読み込めます。プログレスバーのアセットを読み込むのに便利です。
class BootScene extends Phaser.Scene {
constructor() {
super({
key: 'BootScene',
pack: {
files: [
{ type: 'image', key: 'bar', url: 'loaderBar.png' }
]
}
});
}
// 'bar' is already available in preload()
}
読み込み途中でのファイル追加
ファイルごとの完了イベントを使用して、アクティブな読み込みセッション中に依存する読み込みを連鎖させます。
preload() {
this.load.json('level1', 'level1.json');
this.load.on('filecomplete-json-level1', (key, type, data) => {
this.load.image(data.images);
this.load.spritesheet(data.spritesheets);
});
}
インラインパックマニフェスト
パックデータは URL からではなく、インラインで提供できます。
preload() {
this.load.pack('manifest', {
section1: {
prefix: '',
path: 'assets/',
defaultType: 'image',
files: [
{ type: 'image', key: 'bg', url: 'bg.png' },
{ type: 'spritesheet', key: 'player', url: 'player.png', frameConfig: { frameWidth: 32, frameHeight: 32 } }
]
}
});
}
キャッシュシステム
読み込まれたアセットは、すべてのシーンで共有されるグローバルキャッシュに格納されます。テクスチャはテクスチャマネージャー(this.textures)に保存され、その他のアセットタイプは this.cache 以下の型付きサブキャッシュに格納されます。
// Access cached data
const json = this.cache.json.get('levelData');
const text = this.cache.text.get('dialogue');
// Check existence
this.cache.json.exists('levelData'); // or .has('levelData')
this.textures.exists('hero');
// Remove assets to free memory
this.textures.remove('hero');
this.cache.audio.remove('bgm');
// Listen for cross-scene texture additions
this.textures.on('addtexture-mapKey', (texture) => {
// Another scene loaded 'mapKey' — now available here
});
キャッシュのサブタイプ: this.cache.text、this.cache.json、this.cache.audio、this.cache.binary、this.cache.shader、this.cache.xml。完全な Cache API については references/REFERENCE.md を参照してください。
ソースファイルマップ
完全なソースファイルマップと Cache API リファレンスについては references/REFERENCE.md を参照してください。
主要なファイル: src/loader/LoaderPlugin.js(メインの Loader)、src/loader/File.js(基底の File クラス)、src/loader/filetypes/(すべてのファイルタイプローダー)、src/loader/events/(イベント定数)。