Phaser 3中JSON地图保存为空问题求助
问题根源与修复方案
核心问题分析
- Tilemap尺寸参数错误:创建
tilemap时,width和height设置的是像素值(1200、720),但Phaser要求这两个参数是tile的数量而非像素尺寸。这导致地图拥有远超实际画布的tile行数/列数,保存时遍历大量空tile,看起来数据为空。 - 无效Tileset导致索引异常:你使用了不存在的
'tiles'纹理创建tileset,导致放置的tile无法正确关联到有效索引,最终保存时tile index为0或未定义。 - Tile索引偏移错误:
placeTile中使用this.tileIndex + 1,但tileset的索引从0开始,偏移后索引超出有效范围。
分步修复
1. 修正Tilemap创建尺寸
计算画布对应的tile数量,替换原有的像素尺寸参数:
create() { const tileWidth = this.tileSize const tileHeight = this.tileSize const tilesPerRow = this.tilesPerRow // 计算实际的tile数量(画布尺寸 / tile尺寸) const mapTileWidth = Math.floor(1200 / this.tileSize); const mapTileHeight = Math.floor(720 / this.tileSize); if(!this.map){ this.map = this.make.tilemap({ tileWidth: this.tileSize, tileHeight: this.tileSize, width: mapTileWidth, // 改为tile数量 height: mapTileHeight // 改为tile数量 }) // 使用预加载的第一个tile纹理创建有效tileset,指定总tile数 const tileset = this.map.addTilesetImage('tile (0)', 'tile (0)', this.tileSize, this.tileSize, 0, 0, this.totalTiles); this.layer = this.map.createBlankLayer('layer', tileset) } // ... 其余代码不变 }
2. 修复Tile索引偏移
去掉placeTile中的+1,让索引与tileset匹配:
placeTile(tileX, tileY) { if (this.map && this.layer) { if (tileY < 4) { console.log('Cannot place tile on the tile selection area'); return; } if (!this.tilePicked) { console.log('No tile is chosen'); } else { // 移除+1,使用原始tileIndex this.map.putTileAt(this.tileIndex, tileX, tileY, this.layer); } } else { console.log('Tilemap or layer is not properly initialized'); } }
3. 优化指针事件避免冲突
点击tile选择时,阻止事件冒泡到全局,避免误触发拖拽:
tile.on('pointerdown', function(event) { event.stopPropagation(); // 阻止全局pointerdown触发 this.tileset.forEach(tile => tile.clearTint()) this.tileIndex = i this.tilePicked = true tile.setTint(0xff0000) }, this)
验证修复
- 放置tile后,在控制台打印
this.layer.data[tileY][tileX].index,确认索引与选中的tileIndex一致。 - 保存地图后,查看JSON文件,
layers[0].data中会出现非0的tile索引,对应你放置的瓦片。
内容的提问来源于stack exchange,提问作者Duckpedia
相关产品推荐
相关产品推荐

