Files
CINC/scenes/TmpScene.js
T

427 lines
15 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
export default class TmpScene extends Phaser.Scene {
constructor() {
super({ key: 'TmpScene' });
this.selectedTile = null; // 当前选中的瓦片
this.mapLayer = null; // 地图层
this.mapWidth = 50; // 地图宽度(瓦片数量)
this.mapHeight = 50; // 地图高度(瓦片数量)
this.tileSize = 16; // 地图瓦片大小
this.tileColumns = 18; // 瓦片图列数
this.tileRows = 13; // 瓦片图行数
}
preload() {
// 加载资源
// 加载瓦片资源
this.loadTileAssets();
// 显示加载进度
this.createLoadingUI();
// 加载完成后移除加载UI
this.load.on('complete', () => {
this.loadingText.destroy();
this.progressBar.destroy();
this.progressFill.destroy();
});
}
create() {
// 设置输入处理
console.log('设置输入处理');
this.setupInput();
// 创建场景
// 物理世界和相机边界
const worldSize = this.mapWidth * this.tileSize;
this.physics.world.setBounds(0, 0, worldSize, worldSize);
this.cameras.main.setBounds(0, 0, worldSize, worldSize);
// 设置背景色
this.cameras.main.setBackgroundColor('#222222');
// 创建地图编辑区域
console.log('创建地图编辑区域');
this.createMapArea();
// 创建瓦片选择区域
console.log('创建瓦片选择区域');
this.createTileSelectionArea();
// 检查资源是否已加载
if (this.assetsLoaded) {
console.log('资源已加载,调用updateTileSelection');
this.updateTileSelection();
} else {
console.log('资源尚未加载,等待加载完成');
}
}
loadTileAssets() {
console.log('开始加载瓦片资源');
// 只加载单张瓦片图,替代多张瓦片资源
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) => {
console.log(`资源加载进度: ${Math.round(progress * 100)}%`);
});
// 文件加载完成回调
this.load.on('filecomplete', (key, type, data) => {
console.log(`文件加载完成: ${key} (${type})`);
});
// 加载完成回调
this.load.on('complete', () => {
console.log('所有资源加载完成!');
this.assetsLoaded = true;
this.loadingText.setText('资源加载完成!');
// 设置瓦片图的过滤模式为NEAREST
if (this.textures.exists(tilemapKey)) {
const texture = this.textures.get(tilemapKey);
texture.setFilter(Phaser.Textures.FilterMode.NEAREST);
console.log(`设置纹理 ${tilemapKey} 的过滤模式为NEAREST`);
}
// 初始化瓦片集合 - 只使用单张瓦片图键名
this.tileCount = this.tileColumns * this.tileRows; // 根据Tilesheet.txt,总瓦片数为18x13=234
this.tilemapKey = tilemapKey;
// 存储瓦片的位置信息,用于后续切割
this.tileImageSize = 16; // 瓦片大小16x16px
this.tileSpacing = 0; // 瓦片间距0px
this.tileColumns = 18; // 18列
this.tileRows = 13; // 13行
console.log(`瓦片图初始化完成,共 ${this.tileCount} 个瓦片`);
// 只有在tileSelectionContainer初始化后才调用updateTileSelection
if (this.tileSelectionContainer) {
console.log('tileSelectionContainer已初始化,调用updateTileSelection');
this.updateTileSelection();
} else {
console.log('tileSelectionContainer尚未初始化,等待create方法调用');
}
});
}
createLoadingUI() {
// 加载文本
this.loadingText = this.add.text(10, 10, '加载瓦片资源...', {
fontSize: '16px',
fill: '#ffffff',
fontFamily: 'Arial'
});
this.loadingText.setScrollFactor(0, 0);
this.loadingText.setDepth(100);
// 加载进度条
this.progressBar = this.add.rectangle(10, 40, 300, 20, 0x555555);
this.progressBar.setOrigin(0, 0);
this.progressBar.setScrollFactor(0, 0);
this.progressBar.setDepth(100);
this.progressFill = this.add.rectangle(10, 40, 0, 20, 0x00ff00);
this.progressFill.setOrigin(0, 0);
this.progressFill.setScrollFactor(0, 0);
this.progressFill.setDepth(100);
// 更新进度
this.load.on('progress', (progress) => {
this.progressFill.width = progress * 300;
this.loadingText.setText(`加载瓦片资源... ${Math.round(progress * 100)}%`);
});
}
updateTileSelection() {
console.log('开始更新瓦片选择显示');
console.log(`当前瓦片数量: ${this.tileCount}`);
// 清空当前瓦片选择
console.log('清空当前瓦片选择');
this.tileSelectionContainer.removeAll(true);
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);
console.log(`瓦片配置:大小${this.tileImageSize}x${this.tileImageSize},间距${this.tileSpacing},${this.tileColumns}x${this.tileRows}排列`);
// 为每个瓦片位置添加透明的交互式矩形,用于悬停高亮和点击选择
for (let i = 0; i < this.tileCount; i++) {
const col = i % this.tileColumns;
const row = Math.floor(i / this.tileColumns);
// 精确计算瓦片在实际图片中的位置(无间距)
const tileX = col * this.tileImageSize;
const tileY = row * this.tileImageSize;
console.log(`瓦片 ${i} 索引 -> 行列: (${col}, ${row}) -> 位置: (${tileX}, ${tileY}), 大小: ${this.tileImageSize}x${this.tileImageSize}`);
// 创建透明的交互式矩形,精确对齐瓦片
// 使用add.zone创建透明区域,专门用于交互
const tileZone = this.add.zone(tileX, tileY, this.tileImageSize, this.tileImageSize);
tileZone.setOrigin(0, 0);
tileZone.setInteractive({ useHandCursor: true });
this.tileSelectionContainer.add(tileZone);
// 瓦片点击事件
tileZone.on('pointerdown', () => {
console.log(`点击了瓦片 ${i},行列: (${col}, ${row})`);
this.selectTile(i);
});
// 悬停高亮效果
tileZone.on('pointerover', () => {
// 创建临时高亮矩形
if (!this.highlightRect) {
this.highlightRect = this.add.rectangle(tileX, tileY, this.tileImageSize, this.tileImageSize, 0xffffff, 0.3);
this.highlightRect.setOrigin(0, 0);
this.tileSelectionContainer.add(this.highlightRect);
} else {
this.highlightRect.setPosition(tileX, tileY);
}
});
tileZone.on('pointerout', () => {
// 移除高亮效果
if (this.highlightRect) {
this.highlightRect.destroy();
this.highlightRect = null;
}
});
}
console.log('瓦片选择区域已更新,直接显示完整瓦片图');
} else {
console.error(`纹理 ${this.tilemapKey} 不存在!`);
}
} catch (error) {
console.error('更新瓦片选择显示失败:', error);
}
}
setupInput() {
// 鼠标输入
this.input.on('pointerdown', (pointer) => {
// this.handleMouseDown(pointer);
// 开始绘制
this.isDrawing = true;
this.lastDrawnTile = null;
});
this.input.on('pointerup', (pointer) => {
// this.handleMouseUp(pointer);
// 停止绘制
this.isDrawing = false;
this.lastDrawnTile = null;
});
this.input.on('pointermove', (pointer) => {
// this.handleMouseMove(pointer);
// 拖动绘制:如果鼠标按下且不是在拖拽地图,则绘制瓦片
if (this.isDrawing && !this.isDragging) {
// this.placeTile(pointer);
}
});
// 键盘输入
// 空格键返回启动场景
this.input.keyboard.on('keydown-SPACE', () => {
this.scene.start('BootScene');
});
}
createMapArea() {
// 创建地图容器
this.mapContainer = this.add.container(0, 0);
this.mapContainer.setDepth(1);
// 创建背景网格
this.createGrid();
// 创建地图层(用于放置瓦片)
this.mapLayer = this.add.container(0, 0);
this.mapContainer.add(this.mapLayer);
// 初始化空地图
this.mapData = [];
for (let y = 0; y < this.mapHeight; y++) {
this.mapData[y] = [];
for (let x = 0; x < this.mapWidth; x++) {
this.mapData[y][x] = -1; // -1表示空瓦片
}
}
}
//创建背景网格
createGrid() {
// 创建网格线
const gridGraphics = this.add.graphics();
gridGraphics.lineStyle(1, 0x444444, 0.5);
// 绘制垂直线
for (let x = 0; x <= this.mapWidth; x++) {
gridGraphics.moveTo(x * this.tileSize, 0);
gridGraphics.lineTo(x * this.tileSize, this.mapHeight * this.tileSize);
}
// 绘制水平线
for (let y = 0; y <= this.mapHeight; y++) {
gridGraphics.moveTo(0, y * this.tileSize);
gridGraphics.lineTo(this.mapWidth * this.tileSize, y * this.tileSize);
}
this.mapContainer.add(gridGraphics);
}
createTileSelectionArea() {
// 瓦片选择区域位置
const tilePanelX = 10;
const tilePanelY = 10;
// 瓦片选择区域标题
this.add.text(tilePanelX, tilePanelY, '瓦片选择', {
fontSize: this.tileSize+'px',
fill: '#ffffff',
fontFamily: 'Arial',
fontWeight: 'bold'
}).setScrollFactor(0, 0).setDepth(11);
// 瓦片选择区域背景
const tilePanel = this.add.rectangle(tilePanelX, tilePanelY+this.tileSize, this.tileColumns*this.tileSize, this.tileRows*this.tileSize, 0x111111, 0.8);
tilePanel.setOrigin(0, 0);
tilePanel.setScrollFactor(0, 0);
tilePanel.setDepth(10);
// 瓦片选择容器 - 注意:这是一个Container对象,可以使用removeAll方法
this.tileSelectionContainer = this.add.container(tilePanelX, tilePanelY+this.tileSize);
this.tileSelectionContainer.setScrollFactor(0, 0);
this.tileSelectionContainer.setDepth(11);
// 当前选中瓦片显示 - 改为使用Container容器,而不是Rectangle,这样可以使用removeAll方法
this.selectedTileContainer = this.add.container(tilePanelX, tilePanelY+(this.tileRows+1)*this.tileSize+16);
this.selectedTileContainer.setScrollFactor(0, 0);
this.selectedTileContainer.setDepth(11);
// 添加选中瓦片背景
const selectedTileBg = this.add.rectangle(0, 0, 32, 32, 0x333333);
selectedTileBg.setOrigin(0, 0);
selectedTileBg.setDepth(10);
this.selectedTileContainer.add(selectedTileBg);
this.add.text(tilePanelX, tilePanelY+(this.tileRows+1)*this.tileSize, '当前选中瓦片:', {
fontSize: this.tileSize+'px',
fill: '#ffffff',
fontFamily: 'Arial'
}).setScrollFactor(0, 0).setDepth(11);
}
/**
* 选择瓦片
* @param {number} tileIndex - 瓦片索引
*/
selectTile(tileIndex) {
// 防御性编程:检查参数类型
if (typeof tileIndex !== 'number') {
console.error('selectTile: tileIndex 必须是数字类型');
return;
}
this.selectedTile = tileIndex;
console.log(`选择瓦片索引: ${tileIndex}`);
// 更新选中瓦片显示
// 注意:使用Container对象的removeAll方法,而不是Rectangle对象
try {
// 防御性编程:检查容器是否存在
if (this.selectedTileContainer && typeof this.selectedTileContainer.removeAll === 'function') {
this.selectedTileContainer.removeAll(true);
} else {
console.error('selectTile: selectedTileContainer 不存在或没有 removeAll 方法');
return;
}
} catch (error) {
console.error('selectTile: 清空选中瓦片容器失败:', error);
return;
}
if (this.selectedTile !== null && this.selectedTile !== -1) {
try {
// 防御性编程:检查瓦片索引是否在有效范围内
if (this.selectedTile >= 0 && this.selectedTile < this.tileCount) {
// 防御性编程:检查纹理是否存在
if (this.textures.exists(this.tilemapKey)) {
// 计算瓦片在大图中的位置
const col = this.selectedTile % this.tileColumns;
const row = Math.floor(this.selectedTile / this.tileColumns);
// 计算图块在大图中的精确左上角像素位置
const frameX = col * this.tileImageSize;
const frameY = row * this.tileImageSize;
// 创建一个新的image,专门用于显示选中的瓦片
const tile = this.add.image(0, 0, this.tilemapKey);
tile.setOrigin(0, 0);
// 先设置裁剪区域,使用图块在大图中的精确位置作为起始点
tile.setCrop(frameX, frameY, this.tileImageSize, this.tileImageSize);
// 调整瓦片位置,使其相对于容器(0,0)位置显示,而不是原图像位置
tile.setPosition(-frameX*2, -frameY*2);
// 然后设置缩放,放大显示
tile.setScale(2);
this.selectedTileContainer.add(tile);
// 添加选中边框,匹配放大后的瓦片大小
const border = this.add.rectangle(0, 0, this.tileImageSize*2, this.tileImageSize*2, 0x00ff00, 0);
border.setOrigin(0, 0);
border.setStrokeStyle(2, 0x00ff00, 1);
this.selectedTileContainer.add(border);
} else {
console.error(`selectTile: 纹理 ${this.tilemapKey} 不存在`);
}
} else {
console.error(`selectTile: 瓦片索引 ${this.selectedTile} 超出范围 (0-${this.tileCount-1})`);
}
} catch (error) {
console.error('selectTile: 显示选中瓦片失败:', error);
}
} else if (this.selectedTile === -1) {
// 显示删除模式
try {
const deleteText = this.add.text(0, 20, '删除模式', {
fontSize: '14px',
fill: '#ff0000',
fontFamily: 'Arial',
fontWeight: 'bold'
});
deleteText.setOrigin(0, 0);
this.selectedTileContainer.add(deleteText);
} catch (error) {
console.error('selectTile: 显示删除模式失败:', error);
}
}
}
}