From dbef3822c029259300d2f54c8fde0ef9a911a12f Mon Sep 17 00:00:00 2001 From: chicrobot Date: Wed, 7 Jan 2026 21:36:27 +0800 Subject: [PATCH] =?UTF-8?q?feat(assets)=20=E8=B5=84=E6=BA=90=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E5=A4=87=E4=BB=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.js | 5 +- scenes/BootScene.js | 1 + scenes/CharacterAnimationTestScene.js | 305 ++++++++++++++++++++++++++ scenes/MapEditTestScene.js | 222 +++++++++++-------- 4 files changed, 437 insertions(+), 96 deletions(-) create mode 100644 scenes/CharacterAnimationTestScene.js diff --git a/main.js b/main.js index da5acba..ccb5c78 100644 --- a/main.js +++ b/main.js @@ -22,6 +22,8 @@ import ItemListTestScene from './scenes/ItemListTestScene.js'; import ResourceTestScene from './scenes/ResourceTestScene.js'; // 导入地图编辑测试场景 import MapEditTestScene from './scenes/MapEditTestScene.js'; +// 导入角色动画测试场景 +import CharacterAnimationTestScene from './scenes/CharacterAnimationTestScene.js'; // 创建游戏的最终配置对象 const config = { @@ -42,7 +44,8 @@ const config = { InventoryTestScene, ItemListTestScene, ResourceTestScene, - MapEditTestScene + MapEditTestScene, + CharacterAnimationTestScene ] }; diff --git a/scenes/BootScene.js b/scenes/BootScene.js index 6c158bf..b4bac62 100644 --- a/scenes/BootScene.js +++ b/scenes/BootScene.js @@ -19,6 +19,7 @@ export default class BootScene extends Phaser.Scene { // 测试场景列表 const testScenes = [ + { key: 'CharacterAnimationTestScene', name: '测试场景12:角色动画测试' }, { key: 'MapEditTestScene', name: '测试场景11:地图编辑测试' }, { key: 'ResourceTestScene', name: '测试场景10:资源包测试' }, { key: 'ItemListTestScene', name: '测试场景9:物品列表菜单测试' }, diff --git a/scenes/CharacterAnimationTestScene.js b/scenes/CharacterAnimationTestScene.js new file mode 100644 index 0000000..82f6171 --- /dev/null +++ b/scenes/CharacterAnimationTestScene.js @@ -0,0 +1,305 @@ +// 角色动画测试场景 +// 使用Player0和Player1图片作为移动帧 + +export default class CharacterAnimationTestScene extends Phaser.Scene { + constructor() { + super({ key: 'CharacterAnimationTestScene' }); + this.tileSize = 32; // 瓦片大小 + this.player = null; // 玩家角色 + this.cursors = null; // 键盘控制 + } + + preload() { + // 加载玩家瓦片图片 + console.log('加载玩家瓦片图片...'); + + // 加载Player0的动画帧(假设tile_0000.png到tile_0007.png是Player0的帧) + for (let i = 0; i < 8; i++) { + this.load.image(`player0-${i}`, `assets/PNG/Players/Tiles/tile_${String(i).padStart(4, '0')}.png`); + } + + // 加载Player1的动画帧(假设tile_0008.png到tile_0015.png是Player1的帧) + for (let i = 8; i < 16; i++) { + this.load.image(`player1-${i-8}`, `assets/PNG/Players/Tiles/tile_${String(i).padStart(4, '0')}.png`); + } + + console.log('玩家瓦片图片加载完成'); + } + + create() { + // 物理世界和相机边界 + const worldSize = 2000; + this.physics.world.setBounds(0, 0, worldSize, worldSize); + this.cameras.main.setBounds(0, 0, worldSize, worldSize); + + // 设置背景色 + this.cameras.main.setBackgroundColor('#222222'); + + // 创建地面网格 + this.createGrid(); + + // 创建角色动画 + this.createCharacterAnimations(); + + // 创建玩家角色 + this.createPlayer(); + + // 设置输入控制 + this.setupInput(); + + // 显示提示信息 + this.showInstructions(); + + // 相机跟随玩家 + this.cameras.main.startFollow(this.player, true, 0.1, 0.1); + } + + /** + * 创建地面网格 + */ + createGrid() { + // 创建网格线 + const gridGraphics = this.add.graphics(); + gridGraphics.lineStyle(1, 0x444444, 0.5); + + // 绘制垂直线 + for (let x = 0; x <= 2000; x += this.tileSize) { + gridGraphics.moveTo(x, 0); + gridGraphics.lineTo(x, 2000); + } + + // 绘制水平线 + for (let y = 0; y <= 2000; y += this.tileSize) { + gridGraphics.moveTo(0, y); + gridGraphics.lineTo(2000, y); + } + } + + /** + * 创建角色动画 + */ + createCharacterAnimations() { + console.log('创建角色动画...'); + + // 创建Player0的移动动画 + this.anims.create({ + key: 'player0-move', + frames: [ + { key: 'player0-0' }, + { key: 'player0-1' }, + { key: 'player0-2' }, + { key: 'player0-3' }, + { key: 'player0-4' }, + { key: 'player0-5' }, + { key: 'player0-6' }, + { key: 'player0-7' } + ], + frameRate: 10, + repeat: -1 + }); + + // 创建Player1的移动动画 + this.anims.create({ + key: 'player1-move', + frames: [ + { key: 'player1-0' }, + { key: 'player1-1' }, + { key: 'player1-2' }, + { key: 'player1-3' }, + { key: 'player1-4' }, + { key: 'player1-5' }, + { key: 'player1-6' }, + { key: 'player1-7' } + ], + frameRate: 10, + repeat: -1 + }); + + console.log('角色动画创建完成'); + } + + /** + * 创建玩家角色 + */ + createPlayer() { + console.log('创建玩家角色...'); + + // 创建玩家角色 + this.player = this.physics.add.sprite(1000, 1000, 'player0-0'); + this.player.setScale(2); // 放大角色 + this.player.setBounce(0.2); // 反弹效果 + this.player.setCollideWorldBounds(true); // 碰撞世界边界 + + console.log('玩家角色创建完成'); + } + + /** + * 设置输入控制 + */ + setupInput() { + // 键盘控制 - 方向键 + this.cursors = this.input.keyboard.createCursorKeys(); + + // 添加字母键控制 + this.keys = { + a: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.A), + w: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.W), + s: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.S), + d: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.D), + space: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE) + }; + + // 切换角色按钮 + this.createButton(this.sys.game.config.width - 200, 100, '切换角色', () => { + this.switchCharacter(); + }); + + // 返回启动场景按钮 + this.createButton(this.sys.game.config.width - 200, 150, '返回启动场景', () => { + this.scene.start('BootScene'); + }); + } + + /** + * 创建按钮 + */ + createButton(x, y, text, callback) { + // 按钮背景 + const button = this.add.rectangle(x, y, 180, 40, 0x333333); + button.setOrigin(0.5, 0.5); + button.setScrollFactor(0, 0); + button.setDepth(10); + button.setInteractive({ useHandCursor: true }); + + // 按钮文本 + const buttonText = this.add.text(x - 70, y - 15, text, { + fontSize: '14px', + fill: '#ffffff', + fontFamily: 'Arial' + }); + buttonText.setScrollFactor(0, 0); + buttonText.setDepth(11); + + // 按钮事件 + button.on('pointerdown', callback); + + button.on('pointerover', () => { + button.setFillStyle(0x555555); + }); + + button.on('pointerout', () => { + button.setFillStyle(0x333333); + }); + } + + /** + * 切换角色 + */ + switchCharacter() { + // 根据当前使用的纹理切换角色 + if (this.player.anims.currentAnim && this.player.anims.currentAnim.key === 'player0-move') { + // 切换到Player1 + this.player.play('player1-move'); + console.log('切换到Player1'); + } else { + // 切换到Player0 + this.player.play('player0-move'); + console.log('切换到Player0'); + } + } + + /** + * 显示提示信息 + */ + showInstructions() { + // 标题 + this.add.text(20, 20, '角色动画测试场景', { + fontSize: '20px', + fill: '#ffffff', + fontFamily: 'Arial', + fontWeight: 'bold' + }).setScrollFactor(0, 0).setDepth(11); + + // 操作提示 + const instructions = [ + 'WASD或方向键移动角色', + '角色移动时播放动画', + '点击"切换角色"按钮切换Player0和Player1', + '角色动画使用Player0和Player1的图片作为移动帧', + '按空格键返回启动场景' + ]; + + for (let i = 0; i < instructions.length; i++) { + this.add.text(20, 50 + i * 25, instructions[i], { + fontSize: '14px', + fill: '#ffffff', + fontFamily: 'Arial' + }).setScrollFactor(0, 0).setDepth(11); + } + + // 显示当前角色 + this.currentCharacterText = this.add.text(20, 200, '当前角色: Player0', { + fontSize: '16px', + fill: '#00ff00', + fontFamily: 'Arial', + fontWeight: 'bold' + }).setScrollFactor(0, 0).setDepth(11); + } + + /** + * 更新玩家移动 + */ + updatePlayerMovement() { + const speed = 200; // 移动速度 + + // 停止所有移动 + this.player.setVelocity(0); + + let isMoving = false; + + // 水平移动 + if (this.cursors.left.isDown || this.keys.a.isDown) { + this.player.setVelocityX(-speed); + this.player.setFlipX(true); // 向左翻转 + isMoving = true; + } else if (this.cursors.right.isDown || this.keys.d.isDown) { + this.player.setVelocityX(speed); + this.player.setFlipX(false); // 向右不翻转 + isMoving = true; + } + + // 垂直移动 + if (this.cursors.up.isDown || this.keys.w.isDown) { + this.player.setVelocityY(-speed); + isMoving = true; + } else if (this.cursors.down.isDown || this.keys.s.isDown) { + this.player.setVelocityY(speed); + isMoving = true; + } + + // 根据移动状态播放或停止动画 + if (isMoving) { + if (!this.player.anims.isPlaying) { + // 如果没有播放动画,根据当前角色播放对应的移动动画 + if (this.currentCharacterText.text === '当前角色: Player0') { + this.player.play('player0-move'); + } else { + this.player.play('player1-move'); + } + } + } else { + // 停止动画,保持当前帧 + this.player.anims.pause(); + } + } + + update() { + // 更新玩家移动 + this.updatePlayerMovement(); + + // 按空格键返回启动场景 + if (this.keys.space.isDown) { + this.scene.start('BootScene'); + } + } +} \ No newline at end of file diff --git a/scenes/MapEditTestScene.js b/scenes/MapEditTestScene.js index 37e69ad..56b70b9 100644 --- a/scenes/MapEditTestScene.js +++ b/scenes/MapEditTestScene.js @@ -14,15 +14,21 @@ export default class MapEditTestScene extends Phaser.Scene { constructor() { super({ key: 'MapEditTestScene' }); - this.tileSize = 32; // 瓦片大小 + this.tileSize = 32; // 地图瓦片大小 this.selectedTile = null; // 当前选中的瓦片 - this.tileSet = []; // 瓦片集合 this.mapLayer = null; // 地图层 this.mapWidth = 50; // 地图宽度(瓦片数量) this.mapHeight = 50; // 地图高度(瓦片数量) this.isDragging = false; // 是否正在拖拽地图 this.lastDragPosition = { x: 0, y: 0 }; // 上次拖拽位置 this.zoomLevel = 1; // 缩放级别 + // 瓦片图相关属性 + this.tilemapKey = ''; // 单张瓦片图的键名 + this.tileCount = 234; // 总瓦片数 + this.tileImageSize = 16; // 瓦片在图片中的实际大小 + this.tileSpacing = 1; // 瓦片间距 + this.tileColumns = 18; // 瓦片图列数 + this.tileRows = 13; // 瓦片图行数 } preload() { @@ -81,16 +87,12 @@ export default class MapEditTestScene extends Phaser.Scene { */ loadTileAssets() { console.log('开始加载瓦片资源'); - // 加载地形瓦片 - this.tileCount = 32; - for (let i = 0; i < this.tileCount; i++) { - // 使用唯一的键名,避免与其他场景冲突 - const tileKey = `mapedit-tile-${i}`; - const tilePath = `assets/PNG/Tiles/Tiles/tile_${String(i).padStart(4, '0')}.png`; - console.log(`加载瓦片: ${tileKey} -> ${tilePath}`); - // 修复:使用正确的方式加载瓦片,不使用setFilter链式调用 - this.load.image(tileKey, tilePath); - } + + // 只加载单张瓦片图,替代多张瓦片资源 + const tilemapKey = 'mapedit-tilemap'; + const tilemapPath = 'assets/PNG/Tiles/Tilemap/tilemap_packed.png'; + console.log(`加载瓦片图: ${tilemapKey} -> ${tilemapPath}`); + this.load.image(tilemapKey, tilemapPath); // 加载进度回调 this.load.on('progress', (progress) => { @@ -108,25 +110,23 @@ export default class MapEditTestScene extends Phaser.Scene { this.assetsLoaded = true; this.loadingText.setText('资源加载完成!'); - // 修复:在资源加载完成后为每个纹理设置NEAREST过滤模式 - for (let i = 0; i < this.tileCount; i++) { - const tileKey = `mapedit-tile-${i}`; - // 检查纹理是否存在 - if (this.textures.exists(tileKey)) { - // 获取纹理并设置过滤模式 - const texture = this.textures.get(tileKey); - // 设置所有帧的过滤模式为NEAREST - texture.setFilter(Phaser.Textures.FilterMode.NEAREST); - console.log(`设置纹理 ${tileKey} 的过滤模式为NEAREST`); - } + // 设置瓦片图的过滤模式为NEAREST + if (this.textures.exists(tilemapKey)) { + const texture = this.textures.get(tilemapKey); + texture.setFilter(Phaser.Textures.FilterMode.NEAREST); + console.log(`设置纹理 ${tilemapKey} 的过滤模式为NEAREST`); } - // 初始化瓦片集合 - this.tileSet = []; - for (let i = 0; i < this.tileCount; i++) { - this.tileSet.push(`mapedit-tile-${i}`); - } - console.log(`瓦片集合初始化完成,共 ${this.tileSet.length} 个瓦片键名`); + // 初始化瓦片集合 - 只使用单张瓦片图键名 + this.tileCount = 234; // 根据Tilesheet.txt,总瓦片数为18x13=234 + this.tilemapKey = tilemapKey; + // 存储瓦片的位置信息,用于后续切割 + this.tileImageSize = 16; // 瓦片大小16x16px + this.tileSpacing = 1; // 瓦片间距1px + this.tileColumns = 18; // 18列 + this.tileRows = 13; // 13行 + + console.log(`瓦片图初始化完成,共 ${this.tileCount} 个瓦片`); // 只有在tileSelectionContainer初始化后才调用updateTileSelection if (this.tileSelectionContainer) { console.log('tileSelectionContainer已初始化,调用updateTileSelection'); @@ -220,8 +220,8 @@ export default class MapEditTestScene extends Phaser.Scene { * 创建瓦片选择区域 */ createTileSelectionArea() { - // 瓦片选择区域背景 - const tilePanel = this.add.rectangle(10, 70, 220, 400, 0x111111, 0.8); + // 瓦片选择区域背景 - 使用固定大小,足够容纳完整瓦片图 + const tilePanel = this.add.rectangle(10, 70, 300, 250, 0x111111, 0.8); tilePanel.setOrigin(0, 0); tilePanel.setScrollFactor(0, 0); tilePanel.setDepth(10); @@ -239,12 +239,12 @@ export default class MapEditTestScene extends Phaser.Scene { this.tileSelectionContainer.setScrollFactor(0, 0); this.tileSelectionContainer.setDepth(11); - // 瓦片选择网格 - this.tileSelectionGrid = this.add.grid(0, 0, 200, 360, 64, 64, 0x333333, 0.5, 0x444444, 0.5); - this.tileSelectionContainer.add(this.tileSelectionGrid); + // 移除网格,不再需要 + // this.tileSelectionGrid = this.add.grid(0, 0, fullWidth, fullHeight, tileWidth, tileHeight, 0x333333, 0.5, 0x444444, 0.5); + // this.tileSelectionContainer.add(this.tileSelectionGrid); // 当前选中瓦片显示 - 改为使用Container容器,而不是Rectangle,这样可以使用removeAll方法 - this.selectedTileContainer = this.add.container(20, 490); + this.selectedTileContainer = this.add.container(20, 340); this.selectedTileContainer.setScrollFactor(0, 0); this.selectedTileContainer.setDepth(11); @@ -254,7 +254,7 @@ export default class MapEditTestScene extends Phaser.Scene { selectedTileBg.setDepth(10); this.selectedTileContainer.add(selectedTileBg); - this.add.text(20, 470, '当前选中瓦片:', { + this.add.text(20, 320, '当前选中瓦片:', { fontSize: '14px', fill: '#ffffff', fontFamily: 'Arial' @@ -330,65 +330,78 @@ export default class MapEditTestScene extends Phaser.Scene { */ updateTileSelection() { console.log('开始更新瓦片选择显示'); - console.log(`当前瓦片集合数量: ${this.tileSet.length}`); + console.log(`当前瓦片数量: ${this.tileCount}`); // 清空当前瓦片选择 console.log('清空当前瓦片选择'); this.tileSelectionContainer.removeAll(true); - // 重新添加网格 - console.log('重新添加瓦片选择网格'); - this.tileSelectionGrid = this.add.grid(0, 0, 200, 360, 64, 64, 0x333333, 0.5, 0x444444, 0.5); - this.tileSelectionContainer.add(this.tileSelectionGrid); - - // 添加瓦片到选择区域 - console.log('开始添加瓦片到选择区域'); - for (let i = 0; i < this.tileSet.length; i++) { - const tileX = (i % 3) * 64; - const tileY = Math.floor(i / 3) * 64; - const tileKey = this.tileSet[i]; - - console.log(`添加瓦片 ${i}: ${tileKey} 到位置 (${tileX}, ${tileY})`); - - try { - // 检查纹理是否存在 - if (this.textures.exists(tileKey)) { - console.log(`纹理 ${tileKey} 存在`); - // 创建瓦片 - const tile = this.add.image(tileX, tileY, tileKey); - tile.setOrigin(0, 0); - // 修复:根据瓦片实际大小调整缩放比例,确保在选择区域中显示正确大小 - const selectionTileSize = 64; // 选择区域中每个瓦片的大小 - tile.setScale(selectionTileSize / tile.width); - tile.setInteractive({ useHandCursor: true }); - this.tileSelectionContainer.add(tile); + try { + // 检查纹理是否存在 + if (this.textures.exists(this.tilemapKey)) { + console.log(`纹理 ${this.tilemapKey} 存在`); + + // 获取瓦片图的实际尺寸 + const texture = this.textures.get(this.tilemapKey); + const frame = texture.get(); + const actualWidth = frame.width; + const actualHeight = frame.height; + console.log(`瓦片图实际尺寸: ${actualWidth}x${actualHeight}`); + + // 直接添加完整瓦片图,不裁剪,不缩放 + const fullTilemap = this.add.image(0, 0, this.tilemapKey); + fullTilemap.setOrigin(0, 0); + fullTilemap.setScale(1); + this.tileSelectionContainer.add(fullTilemap); + + // 计算每个瓦片在实际图片中的位置和大小 + const tileWidth = 16; // 瓦片大小16x16px + const tileHeight = 16; + const spacing = 1; // 瓦片间距1px + const columns = 18; // 18列 + + // 为每个瓦片位置添加透明的交互式矩形,用于悬停高亮和点击选择 + for (let i = 0; i < this.tileCount; i++) { + const col = i % columns; + const row = Math.floor(i / columns); + + // 精确计算瓦片在实际图片中的位置 + const tileX = col * (tileWidth + spacing); + const tileY = row * (tileHeight + spacing); + + console.log(`瓦片 ${i} 位置: (${tileX}, ${tileY}), 大小: ${tileWidth}x${tileHeight}`); + + // 创建透明的交互式矩形,精确对齐瓦片 + const tileRect = this.add.rectangle(tileX, tileY, tileWidth, tileHeight, 0x000000, 0); + tileRect.setOrigin(0, 0); + tileRect.setInteractive({ useHandCursor: true }); + this.tileSelectionContainer.add(tileRect); // 瓦片点击事件 - tile.on('pointerdown', () => { - console.log(`点击了瓦片 ${i}: ${tileKey}`); + tileRect.on('pointerdown', () => { + console.log(`点击了瓦片 ${i},位置: (${tileX}, ${tileY})`); this.selectTile(i); }); - tile.on('pointerover', () => { - // 高亮显示 - tile.setTint(0x888888); + // 悬停高亮效果 + tileRect.on('pointerover', () => { + // 创建高亮效果 + tileRect.setFillStyle(0xffffff, 0.3); }); - tile.on('pointerout', () => { - // 取消高亮 - tile.clearTint(); + tileRect.on('pointerout', () => { + // 移除高亮效果 + tileRect.setFillStyle(0x000000, 0); }); - - console.log(`成功添加瓦片 ${i}: ${tileKey}`); - } else { - console.error(`纹理 ${tileKey} 不存在!`); } - } catch (error) { - console.error(`加载瓦片${i}失败:`, error); + + console.log('瓦片选择区域已更新,直接显示完整瓦片图'); + } else { + console.error(`纹理 ${this.tilemapKey} 不存在!`); } + } catch (error) { + console.error('更新瓦片选择显示失败:', error); } - - console.log('瓦片选择区域已更新,瓦片数量:', this.tileSet.length); } /** @@ -423,13 +436,22 @@ export default class MapEditTestScene extends Phaser.Scene { if (this.selectedTile !== null && this.selectedTile !== -1) { try { // 防御性编程:检查瓦片索引是否在有效范围内 - if (this.selectedTile >= 0 && this.selectedTile < this.tileSet.length) { - const tileKey = this.tileSet[this.selectedTile]; + if (this.selectedTile >= 0 && this.selectedTile < this.tileCount) { // 防御性编程:检查纹理是否存在 - if (this.textures.exists(tileKey)) { - // 创建瓦片 - 注意:添加到Container容器中,而不是直接添加到场景 - const tile = this.add.image(0, 0, tileKey).setScale(2); + if (this.textures.exists(this.tilemapKey)) { + // 计算瓦片在大图中的位置 + const col = this.selectedTile % this.tileColumns; + const row = Math.floor(this.selectedTile / this.tileColumns); + + // 计算源矩形 + const frameX = col * (this.tileSize + this.tileSpacing); + const frameY = row * (this.tileSize + this.tileSpacing); + + // 创建瓦片 - 使用单张瓦片图并裁剪 + const tile = this.add.image(0, 0, this.tilemapKey); tile.setOrigin(0, 0); + tile.setCrop(frameX, frameY, this.tileSize, this.tileSize); + tile.setScale(2); // 放大显示 this.selectedTileContainer.add(tile); // 添加选中边框 @@ -438,10 +460,10 @@ export default class MapEditTestScene extends Phaser.Scene { border.setStrokeStyle(2, 0x00ff00, 1); this.selectedTileContainer.add(border); } else { - console.error(`selectTile: 纹理 ${tileKey} 不存在`); + console.error(`selectTile: 纹理 ${this.tilemapKey} 不存在`); } } else { - console.error(`selectTile: 瓦片索引 ${this.selectedTile} 超出范围 (0-${this.tileSet.length-1})`); + console.error(`selectTile: 瓦片索引 ${this.selectedTile} 超出范围 (0-${this.tileCount-1})`); } } catch (error) { console.error('selectTile: 显示选中瓦片失败:', error); @@ -626,9 +648,10 @@ export default class MapEditTestScene extends Phaser.Scene { // 将屏幕坐标转换为世界坐标 const worldPoint = this.cameras.main.getWorldPoint(pointer.x, pointer.y); - // 计算瓦片坐标 - const tileX = Math.floor(worldPoint.x / this.tileSize); - const tileY = Math.floor(worldPoint.y / this.tileSize); + // 计算瓦片坐标 - 使用地图的瓦片大小32px + const mapTileSize = 32; + const tileX = Math.floor(worldPoint.x / mapTileSize); + const tileY = Math.floor(worldPoint.y / mapTileSize); // 检查瓦片坐标是否在地图范围内 if (tileX < 0 || tileX >= this.mapWidth || tileY < 0 || tileY >= this.mapHeight) { @@ -644,8 +667,7 @@ export default class MapEditTestScene extends Phaser.Scene { if (this.selectedTile === -1) { this.removeTile(tileX, tileY); } else { - // 放置瓦片 - const tileKey = this.tileSet[this.selectedTile]; + // 放置瓦片 - 使用单张瓦片图 // 检查该位置是否已有瓦片 const existingTile = this.getTileAt(tileX, tileY); @@ -654,12 +676,22 @@ export default class MapEditTestScene extends Phaser.Scene { existingTile.destroy(); } - // 创建新瓦片 - 修复:使用正确的缩放比例,确保瓦片填满整个图块 + // 创建新瓦片 try { - const tile = this.add.image(tileX * this.tileSize, tileY * this.tileSize, tileKey); + const tile = this.add.image(tileX * mapTileSize, tileY * mapTileSize, this.tilemapKey); tile.setOrigin(0, 0); - // 修复:根据瓦片实际大小调整缩放比例,确保填满32x32图块 - tile.setScale(this.tileSize / tile.width); + + // 计算瓦片在大图中的位置 + const col = this.selectedTile % this.tileColumns; + const row = Math.floor(this.selectedTile / this.tileColumns); + + // 设置裁剪区域,只显示当前瓦片 + const frameX = col * (this.tileSize + this.tileSpacing); + const frameY = row * (this.tileSize + this.tileSpacing); + tile.setCrop(frameX, frameY, this.tileSize, this.tileSize); + + // 缩放瓦片以适应地图的32x32图块 + tile.setScale(mapTileSize / this.tileSize); tile.setDepth(2); this.mapLayer.add(tile);