Skip to main content

tilemaps

Use this skill when working with tilemaps in Phaser 4. Covers loading Tiled JSON maps, creating tilemap layers, tile collision, dynamic tiles, tile properties, and tilemap camera culling. Triggers on: Tilemap, Tiled, tilemap layer, tile collision, tile properties.

来源信息

仓库
phaserjs/phaser
最近来源活动
2026年4月10日 12:38
检测到的 SKILL.md 语言
英语
星标
40,490
分支
7,173

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
tilemaps
description
Use this skill when working with tilemaps in Phaser 4. Covers loading Tiled JSON maps, creating tilemap layers, tile collision, dynamic tiles, tile properties, and tilemap camera culling. Triggers on: Tilemap, Tiled, tilemap layer, tile collision, tile properties.
# Tilemaps > Phaser Tilemaps render tile-based levels from Tiled JSON, CSV, or raw 2D arrays. A `Tilemap` holds parsed map data and provides methods to add tilesets, create layers, set collision, and query tiles. Layers (`TilemapLayer` or `TilemapGPULayer`) are the Game Objects that actually render tiles. Phaser supports orthogonal, isometric, hexagonal, and staggered maps. **Key source paths:** `src/tilemaps/Tilemap.js`, `src/tilemaps/TilemapLayer.js`, `src/tilemaps/TilemapGPULayer.js`, `src/tilemaps/TilemapLayerBase.js`, `src/tilemaps/Tile.js`, `src/tilemaps/Tileset.js`, `src/tilemaps/TilemapFactory.js`, `src/tilemaps/components/`, `src/tilemaps/parsers/tiled/` **Related skills:** ../loading-assets/SKILL.md, ../sprites-and-images/SKILL.md ## Quick Start ```js class GameScene extends Phaser.Scene { preload() { // Load the Tiled JSON and the tileset image this.load.tilemapTiledJSON('map', 'assets/level1.json'); this.load.image('tiles', 'assets/tilesheet.png'); } create() { // Create the tilemap from cached JSON const map = this.add.tilemap('map'); // Link the tileset image to the tileset name used in Tiled const tileset = map.addTilesetImage('tilesheet', 'tiles'); // Create a layer - layerID must match the layer name in Tiled const ground = map.createLayer('Ground', tileset); // Enable collision on specific tile indexes ground.setCollision([1, 2, 3]); } } ``` The flow is always: load JSON + image, create tilemap, add tileset image, create layer(s), set collision. ## Core Concepts ### Tilemap vs Layer A `Tilemap` is a data container, not a display object. It stores parsed map data (layers, tilesets, objects) and provides methods that operate on them. A `TilemapLayer` or `TilemapGPULayer` is the actual Game Object added to the display list that renders tiles. ```js const map = this.add.tilemap('map'); // Data container (not rendered) const layer = map.createLayer('Ground', tileset); // Game Object (rendered) ``` `this.add.tilemap(key)` is a factory registered on `GameObjectFactory`. It delegates to `ParseToTilemap` which reads from the cache and returns a `Tilemap` instance. ### Tilesets A `Tileset` (`src/tilemaps/Tileset.js`) links a tileset name (from Tiled) to a loaded texture. It stores `firstgid`, tile dimensions, margin, and spacing. ```js // tilesetName: the name in Tiled's tileset panel // key: the Phaser texture key (defaults to tilesetName if omitted) const tileset = map.addTilesetImage('tilesetName', 'textureKey'); // Override tile dimensions, margin, and spacing if needed const tileset = map.addTilesetImage('name', 'key', 16, 16, 1, 2); ``` `addTilesetImage(tilesetName, key, tileWidth, tileHeight, tileMargin, tileSpacing, gid, tileOffset)` - If the tileset name already exists in the parsed map data, it updates the existing Tileset object with the texture. If not (non-Tiled maps), it creates a new Tileset. **Important:** The Phaser Tiled parser does not support "Collection of Images" tilesets. All tiles must be in a single tileset image per tileset. ### The Tile Class Each cell in a layer is a `Tile` object (`src/tilemaps/Tile.js`). Key properties: - `index` - tile index in the tileset (-1 for empty) - `x`, `y` - tile coordinates (in tiles, not pixels) - `pixelX`, `pixelY` - pixel position relative to layer origin - `width`, `height` - tile size in pixels - `properties` - custom properties from Tiled (object) - `collideLeft`, `collideRight`, `collideUp`, `collideDown` - per-edge collision flags - `faceLeft`, `faceRight`, `faceTop`, `faceBottom` - interesting face flags for collision optimization - `collisionCallback` - per-tile collision callback function - `tint` - tint color value (default `0xffffff`) - `tintMode` - tint blend mode (default `TintModes.MULTIPLY`) - `rotation` - rotation angle - `physics` - object for physics-engine-specific data (e.g. bodies) - `alpha`, `visible`, `flipX`, `flipY` - inherited from mixins ### TilemapGPULayer (v4.0.0) `TilemapGPULayer` is a high-performance WebGL-only alternative to `TilemapLayer`. It renders the entire layer as a single quad using a shader, making it almost entirely GPU-bound. ```js // Pass gpu: true as the 5th argument to createLayer const layer = map.createLayer('Ground', tileset, 0, 0, true); ``` **Capabilities:** - Single tileset per layer only (no multi-tileset) - Max tilemap size: 4096x4096 tiles - Max unique tile IDs: 2^23 (8,388,608) - Supports tile flip and tile animation - Orthographic maps only (no iso/hex/staggered) - Smooth tile borders with LINEAR filtering (no seams) - Sharp pixels with NEAREST filtering **Restrictions:** - Layer edits do not display automatically. Call `generateLayerDataTexture()` after modifying tiles. - WebGL renderer only (no Canvas fallback) - Cannot use multiple tilesets on a single layer ```js // If you edit tiles on a GPU layer, regenerate the data texture: gpuLayer.putTileAt(5, 10, 10); gpuLayer.generateLayerDataTexture(); ``` ### TilemapLayerBase Both `TilemapLayer` and `TilemapGPULayer` extend `TilemapLayerBase` (`src/tilemaps/TilemapLayerBase.js`), which extends `GameObject`. The base class provides all tile query, manipulation, and collision methods. It includes these component mixins: Alpha, BlendMode, ComputedSize, Depth, ElapseTimer, Flip, GetBounds, Lighting, Mask, Origin, RenderNodes, Transform, Visible, ScrollFactor, and Arcade Physics Collision. ## Common Patterns ### Creating from Tiled JSON ```js preload() { this.load.tilemapTiledJSON('map', 'assets/map.json'); this.load.image('tiles', 'assets/tileset.png'); } create() { const map = this.add.tilemap('map'); const tileset = map.addTilesetImage('TilesetNameInTiled', 'tiles'); const layer = map.createLayer('LayerNameInTiled', tileset); } ``` The `layerID` passed to `createLayer` must match the layer name in Tiled exactly. Group layer children are flattened with a `'ParentGroup/Layer'` naming convention. ### Multiple Layers ```js const map = this.add.tilemap('map'); const tileset = map.addTilesetImage('terrain', 'terrain-img'); const background = map.createLayer('Background', tileset); const ground = map.createLayer('Ground', tileset); const foreground = map.createLayer('Foreground', tileset); // Layers are rendered in creation order. Use depth for finer control: foreground.setDepth(10); ``` A layer can use multiple tilesets (CPU layer only): ```js const tiles1 = map.addTilesetImage('terrain', 'terrain-img'); const tiles2 = map.addTilesetImage('objects', 'objects-img'); const layer = map.createLayer('Ground', [tiles1, tiles2]); ``` ### Creating a Blank Layer ```js const map = this.add.tilemap('map'); const tileset = map.addTilesetImage('terrain', 'terrain-img'); // createBlankLayer(name, tileset, x, y, width, height, tileWidth, tileHeight) const layer = map.createBlankLayer('dynamic', tileset, 0, 0, 50, 50, 32, 32); // Fill it with tiles layer.fill(1); // Fill entire layer with tile index 1 layer.putTileAt(5, 10, 10); // Place tile index 5 at tile coord (10, 10) ``` ### Collision Setup There are several ways to enable tile collision for Arcade Physics: ```js // By specific tile indexes layer.setCollision([1, 2, 3]); // By range (inclusive) layer.setCollisionBetween(1, 50); // By tile property (set in Tiled's tileset editor) layer.setCollisionByProperty({ collides: true }); // Supports arrays: { type: ['stone', 'lava'] } // By exclusion - collide on ALL tiles except these layer.setCollisionByExclusion([-1, 0]); // -1 is empty, 0 is often background // From Tiled collision editor shapes layer.setCollisionFromCollisionGroup(); ``` All collision methods on `TilemapLayerBase` mirror methods on `Tilemap` but don't require a `layer` parameter. On the `Tilemap`, you can pass a layer reference or use the "current layer": ```js map.setLayer('Ground'); map.setCollision([1, 2, 3]); // Applies to current layer // Or specify a layer explicitly: map.setCollision([1, 2, 3], true, true, 'Ground'); ``` ### Physics Integration (Arcade) ```js // Enable collisions between a sprite and a tilemap layer this.physics.add.collider(player, groundLayer); // With a callback this.physics.add.collider(player, groundLayer, (sprite, tile) => { if (tile.index === 5) { // Hit a special tile } }); // Overlap detection instead of collision this.physics.add.overlap(player, groundLayer, (sprite, tile) => { // Player is overlapping this tile }); ``` The layer must have collision set on its tiles (via `setCollision*` methods) for physics to detect them. The layer itself has `collisionCategory` and `collisionMask` properties for collision filtering. ### Tile Properties Tiles can have custom properties set in Tiled's tileset editor: ```js // Access tile properties const tile = layer.getTileAt(10, 5); console.log(tile.properties.damage); // Custom property from Tiled console.log(tile.properties.type); // Custom property from Tiled // Set collision based on custom properties layer.setCollisionByProperty({ collides: true }); layer.setCollisionByProperty({ type: ['wall', 'rock'] }); ``` ### Tile Callbacks ```js // Callback by tile index - fires when physics body overlaps these tiles map.setTileIndexCallback([5, 6, 7], (sprite, tile) => { // Called for tiles with index 5, 6, or 7 console.log('Hit tile', tile.index, 'at', tile.x, tile.y); }, this); // Callback by tile location - fires for tiles in a rectangular area map.setTileLocationCallback(10, 10, 5, 5, (sprite, tile) => { // Called for any tile in the 5x5 region starting at (10, 10) }, this); // Per-tile callback const tile = layer.getTileAt(10, 5); tile.collisionCallback = (sprite, tile) => { // Custom logic for this specific tile }; ``` Tile callbacks require an active physics collider/overlap between the body and the layer. ### Querying Tiles ```js const tile = layer.getTileAt(10, 5); // By tile coords (or null) const tile = layer.getTileAt(10, 5, true); // nonNull: Tile with index -1 instead of null const tile = layer.getTileAtWorldXY(worldX, worldY); // By world coords const exists = layer.hasTileAt(10, 5); // Boolean check // Region queries const tiles = layer.getTilesWithin(0, 0, 10, 10); // Tile coord region const tiles = layer.getTilesWithinWorldXY(x, y, w, h); // World coord region const tiles = layer.getTilesWithinShape(circle); // Shape overlap // Functional queries const water = layer.filterTiles(t => t.properties.type === 'water'); const spawn = layer.findTile(t => t.properties.isSpawn); layer.forEachTile(t => { /* iterate all tiles */ }); ``` ### Modifying Tiles at Runtime ```js layer.putTileAt(5, 10, 10); // Place tile index 5 at (10, 10) layer.putTileAtWorldXY(5, worldX, worldY); // Place by world coords layer.putTilesAt([[1, 2], [3, 4]], 10, 10); // Place a 2x2 grid layer.removeTileAt(10, 10); // Remove tile layer.fill(1, 0, 0, 10, 10); // Fill 10x10 region with index 1 layer.replaceByIndex(5, 10); // Replace all index-5 with index-10 layer.copy(0, 0, 5, 5, 20, 20); // Copy 5x5 from (0,0) to (20,20) layer.randomize(0, 0, 10, 10, [1, 2, 3, 4]); // Random tiles in region layer.weightedRandomize([{ index: 1, weight: 4 }, { index: 2, weight: 1 }], 0, 0, 10, 10); layer.shuffle(0, 0, 10, 10); // Shuffle tiles in region ``` ### Coordinate Conversion ```js const tileXY = layer.worldToTileXY(worldX, worldY); // World -> tile coords const worldXY = layer.tileToWorldXY(tileX, tileY); // Tile -> world coords // Reuse a vector to avoid allocation const vec = new Phaser.Math.Vector2(); layer.worldToTileXY(worldX, worldY, true, vec); // snapToFloor = true ``` ### Object Layers (Tiled) Tiled object layers define points, rectangles, and sprite placement. Use `createFromObjects` on the `Tilemap`: ```js // Create sprites from all objects on the 'Enemies' object layer const enemies = map.createFromObjects('Enemies', { gid: 26, // Match by tile GID classType: Enemy // Custom class extending Sprite }); // Match by name const coins = map.createFromObjects('Items', { name: 'coin', key: 'coin-texture', frame: 0 }); // Match by type const spawns = map.createFromObjects('Spawns', { type: 'player-spawn' }); // Access raw object layer data const objectLayer = map.getObjectLayer('Enemies'); objectLayer.objects.forEach(obj => { console.log(obj.name, obj.x, obj.y, obj.properties); }); ```
在 GitHub 查看
这个 SKILL.md 很大,SkillsMP 这里只预览前一段内容。 在 GitHub 查看