From ce4e04740a5c53bc659425b3d805b3139f157af1 Mon Sep 17 00:00:00 2001 From: chicrobot Date: Fri, 9 Jan 2026 18:58:23 +0800 Subject: [PATCH] =?UTF-8?q?feat(FTS)=20=E6=96=B0=E5=A2=9E=E7=A7=8D?= =?UTF-8?q?=E7=94=B0=E7=B3=BB=E7=BB=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- data/items.json | 92 +++ items/Item.js | 29 + main.js | 5 +- objects/Crop.js | 161 +++++ scenes/BootScene.js | 1 + ...stScene.js.js => AutoMovementTestScene.js} | 0 scenes/testScenes/FarmingTestScene.js | 645 ++++++++++++++++++ 8 files changed, 933 insertions(+), 2 deletions(-) create mode 100644 objects/Crop.js rename scenes/testScenes/{AutoMovementTestScene.js.js => AutoMovementTestScene.js} (100%) create mode 100644 scenes/testScenes/FarmingTestScene.js diff --git a/README.md b/README.md index e12f86f..4657d5c 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ python -m http.server 8000 2. 在浏览器中访问: ``` -http://localhost:8000 +http://localhost:3173 ``` ## 游戏操作 diff --git a/data/items.json b/data/items.json index fe0f21d..32dadef 100644 --- a/data/items.json +++ b/data/items.json @@ -23,6 +23,98 @@ "hydration": 50 } }, + { + "id": "wheat_seed", + "name": "小麦种子", + "description": "可以种植小麦的种子。", + "type": "seed", + "weight": 0.1, + "volume": 0.5, + "value": 2, + "gridSize": { + "width": 1, + "height": 1 + }, + "sprite": { + "width": 16, + "height": 16, + "color": 16766720 + }, + "properties": { + "plantable": true, + "crop_type": "wheat", + "growth_time": 10000 + } + }, + { + "id": "wheat", + "name": "小麦", + "description": "成熟的小麦,可以用来制作食物。", + "type": "food", + "weight": 0.5, + "volume": 1.0, + "value": 10, + "gridSize": { + "width": 1, + "height": 1 + }, + "sprite": { + "width": 16, + "height": 16, + "color": 16774656 + }, + "properties": { + "edible": true, + "nutrition": 30, + "hydration": 5 + } + }, + { + "id": "carrot_seed", + "name": "胡萝卜种子", + "description": "可以种植胡萝卜的种子。", + "type": "seed", + "weight": 0.1, + "volume": 0.5, + "value": 3, + "gridSize": { + "width": 1, + "height": 1 + }, + "sprite": { + "width": 16, + "height": 16, + "color": 16711680 + }, + "properties": { + "plantable": true, + "crop_type": "carrot", + "growth_time": 8000 + } + }, + { + "id": "carrot", + "name": "胡萝卜", + "description": "新鲜的胡萝卜,可以直接食用。", + "type": "food", + "weight": 0.3, + "volume": 0.8, + "value": 8, + "gridSize": { + "width": 1, + "height": 1 + }, + "sprite": { + "width": 16, + "height": 16, + "color": 16737792 + }, + "properties": { + "edible": true, + "nutrition": 25, + "hydration": 10 + } + }, { "id": "canned_food", "name": "罐头食品", diff --git a/items/Item.js b/items/Item.js index 8300548..eb896ea 100644 --- a/items/Item.js +++ b/items/Item.js @@ -189,11 +189,40 @@ export default class Item extends Phaser.GameObjects.Sprite { case 'weapon': this.equipWeapon(user); break; + case 'seed': + this.useSeed(user); + break; default: console.log(`无法使用物品:${this.name}`); } } + /** + * 使用种子物品 + * @param {Object} user - 使用物品的单位 + */ + useSeed(user) { + console.log('DEBUG: useSeed 方法被调用'); + if (this.properties.plantable) { + console.log(`DEBUG: ${user.name} 准备种植 ${this.name}`); + + // 触发种植事件,让场景处理具体的种植逻辑 + console.log('DEBUG: 触发 plant-seed 事件'); + this.scene.events.emit('plant-seed', this, user); + + // 从背包中移除种子 + if (user.inventory) { + console.log(`DEBUG: 从背包中移除种子 ${this.id}`); + user.inventory.removeItem(this.id); + } + + // 显示种植提示 + this.scene.events.emit('show-message', `准备种植 ${this.name}`); + } else { + console.log('DEBUG: 种子不可种植'); + } + } + /** * 使用食物物品 * @param {Object} user - 使用物品的单位 diff --git a/main.js b/main.js index ec2902a..f24b205 100644 --- a/main.js +++ b/main.js @@ -26,6 +26,8 @@ import MapEditSinglePicTestScene from './scenes/testScenes/MapEditSinglePicTestS import CharacterAnimationTestScene from './scenes/testScenes/CharacterAnimationTestScene.js'; // 导入临时场景 import MapEditTestScene from './scenes/testScenes/MapEditTestScene.js'; +// 导入种田功能测试场景 +import FarmingTestScene from './scenes/testScenes/FarmingTestScene.js'; // 创建游戏的最终配置对象 const config = { @@ -48,7 +50,8 @@ const config = { ResourceTestScene, MapEditSinglePicTestScene, CharacterAnimationTestScene, - MapEditTestScene + MapEditTestScene, + FarmingTestScene ] }; diff --git a/objects/Crop.js b/objects/Crop.js new file mode 100644 index 0000000..fa3c3dc --- /dev/null +++ b/objects/Crop.js @@ -0,0 +1,161 @@ +// 作物类:表示游戏中的农作物 + +export default class Crop extends Phaser.GameObjects.Sprite { + constructor(scene, x, y, cropType, growthTime) { + super(scene, x, y, 'crop'); + + // 设置作物属性 + this.cropType = cropType; + this.growthTime = growthTime; // 生长时间(毫秒) + this.plantedTime = Date.now(); + this.isHarvestable = false; + this.growthStage = 0; // 0: 种子, 1: 幼苗, 2: 成长中, 3: 成熟 + + // 创建作物纹理 + this.createCropTexture(); + + // 添加到场景 + scene.add.existing(this); + + // 设置碰撞体 + this.setSize(16, 16); + + // 设置交互性 + this.setInteractive({ + useHandCursor: true + }); + + // 绑定点击事件 + this.on('pointerdown', () => { + this.onCropClicked(); + }); + + // 开始生长计时器 + this.startGrowthTimer(); + } + + /** + * 创建作物纹理 + */ + createCropTexture() { + // 根据作物类型和生长阶段创建不同的纹理 + const textureKey = `${this.cropType}_${this.growthStage}`; + + if (!this.scene.textures.exists(textureKey)) { + const canvas = document.createElement('canvas'); + canvas.width = 16; + canvas.height = 16; + const ctx = canvas.getContext('2d'); + + // 根据作物类型设置基础颜色 + let baseColor; + switch (this.cropType) { + case 'wheat': + baseColor = '#FFFF00'; // 黄色 + break; + case 'carrot': + baseColor = '#FF6B35'; // 橙色 + break; + default: + baseColor = '#00FF00'; // 绿色 + } + + // 根据生长阶段绘制不同的形状 + ctx.fillStyle = baseColor; + + switch (this.growthStage) { + case 0: // 种子 + ctx.fillRect(6, 10, 4, 4); + break; + case 1: // 幼苗 + ctx.fillRect(7, 8, 2, 6); + ctx.fillRect(5, 6, 6, 2); + break; + case 2: // 成长中 + ctx.fillRect(6, 5, 4, 8); + ctx.fillRect(3, 3, 10, 3); + break; + case 3: // 成熟 + ctx.fillRect(5, 2, 6, 10); + ctx.fillRect(2, 0, 12, 4); + break; + } + + // 添加边框 + ctx.strokeStyle = '#000000'; + ctx.lineWidth = 1; + ctx.strokeRect(0, 0, 16, 16); + + // 将canvas添加为纹理 + this.scene.textures.addCanvas(textureKey, canvas); + } + + // 设置纹理 + this.setTexture(textureKey); + } + + /** + * 开始生长计时器 + */ + startGrowthTimer() { + // 计算每个生长阶段的时间 + const stageTime = this.growthTime / 4; + + // 设置每个生长阶段的定时器 + for (let i = 1; i <= 3; i++) { + this.scene.time.delayedCall(stageTime * i, () => { + this.updateGrowthStage(i); + }); + } + + // 设置成熟定时器 + this.scene.time.delayedCall(this.growthTime, () => { + this.isHarvestable = true; + }); + } + + /** + * 更新生长阶段 + */ + updateGrowthStage(stage) { + this.growthStage = stage; + this.createCropTexture(); + } + + /** + * 作物被点击时的处理函数 + */ + onCropClicked() { + if (this.isHarvestable) { + this.harvest(); + } else { + // 显示生长进度 + const growthProgress = Math.min(100, Math.floor(((Date.now() - this.plantedTime) / this.growthTime) * 100)); + this.scene.events.emit('show-message', `作物正在生长中: ${growthProgress}%`); + } + } + + /** + * 收获作物 + */ + harvest() { + // 触发收获事件 + this.scene.events.emit('crop-harvested', this); + + // 销毁作物 + this.destroy(); + } + + /** + * 获取作物信息 + */ + getInfo() { + return { + type: this.cropType, + growthStage: this.growthStage, + isHarvestable: this.isHarvestable, + plantedTime: this.plantedTime, + growthTime: this.growthTime + }; + } +} \ No newline at end of file diff --git a/scenes/BootScene.js b/scenes/BootScene.js index 9b371bd..a83a84d 100644 --- a/scenes/BootScene.js +++ b/scenes/BootScene.js @@ -19,6 +19,7 @@ export default class BootScene extends Phaser.Scene { // 测试场景列表 const testScenes = [ + { key: 'FarmingTestScene', name: '测试场景14:种田功能测试' }, { key: 'CharacterAnimationTestScene', name: '测试场景13:角色动画测试' }, { key: 'MapEditTestScene', name: '测试场景12:地图编辑测试' }, { key: 'MapEditSinglePicTestScene', name: '测试场景11:地图编辑单瓦片图资源测试' }, diff --git a/scenes/testScenes/AutoMovementTestScene.js.js b/scenes/testScenes/AutoMovementTestScene.js similarity index 100% rename from scenes/testScenes/AutoMovementTestScene.js.js rename to scenes/testScenes/AutoMovementTestScene.js diff --git a/scenes/testScenes/FarmingTestScene.js b/scenes/testScenes/FarmingTestScene.js new file mode 100644 index 0000000..8babd08 --- /dev/null +++ b/scenes/testScenes/FarmingTestScene.js @@ -0,0 +1,645 @@ +// 种田功能测试场景 + +import Unit from '../../objects/Unit.js'; +import Crop from '../../objects/Crop.js'; +import { InputSystem } from '../../systems/InputSystem.js'; +import { SelectionSystem } from '../../systems/SelectionSystem.js'; +import { CommandSystem } from '../../systems/CommandSystem.js'; +import { ItemManager } from '../../items/ItemManager.js'; +import { Inventory } from '../../items/Inventory.js'; +import { InventoryUI } from '../../ui/InventoryUI.js'; + +export default class FarmingTestScene extends Phaser.Scene { + constructor() { + super({ key: 'FarmingTestScene' }); + this.isPlantingMode = false; + this.selectedSeed = null; + } + + preload() { + // 加载物品数据 + this.load.json('items', './data/items.json'); + } + + create() { + // 物理世界和相机边界 + const worldSize = 1000; + this.physics.world.setBounds(-worldSize, -worldSize, worldSize * 2, worldSize * 2); + this.cameras.main.setBounds(-worldSize, -worldSize, worldSize * 2, worldSize * 2); + + // 初始化系统 + this.inputSystem = new InputSystem(this, { + keyboard: true, + mouse: true, + joystick: false, + selection: true + }); + this.selectionSystem = new SelectionSystem(this); + this.commandSystem = new CommandSystem(this); + + // 创建单位组 + this.unitGroup = this.add.group(); + + // 创建背景 + this.createBackground(); + + // 创建玩家 + this.createPlayer(); + + // 初始化物品管理器 + this.itemManager = new ItemManager(this); + + // 初始化背包系统 + this.initInventory(); + + // 创建作物组 + this.cropGroup = this.add.group(); + + // 设置输入处理 + this.setupInput(); + + // 创建侧边栏UI + this.createSidebar(); + + // 显示提示信息 + this.showInstructions(); + + // 显示单位状态 + this.updateUnitStatus(this.player); + + // 显示默认提示 + this.generalInfoText.setText('欢迎使用种田功能测试场景'); + + // 监听种植事件 + this.events.on('plant-seed', (seed, user) => { + console.log('DEBUG: FarmingTestScene 收到 plant-seed 事件'); + this.startPlantingMode(seed, user); + }); + + // 监听作物收获事件 + this.events.on('crop-harvested', (crop) => { + console.log('DEBUG: FarmingTestScene 收到 crop-harvested 事件'); + this.harvestCrop(crop); + }); + + // 监听显示消息事件 + this.events.on('show-message', (message) => { + console.log(`DEBUG: FarmingTestScene 收到 show-message 事件: ${message}`); + this.showMessage(message); + }); + + // 初始化测试物品 + this.itemManager.onDataLoaded(() => { + this.initTestItems(); + }); + } + + /** + * 创建背景 + */ + createBackground() { + // 创建纯色背景 + this.add.rectangle(0, 0, this.sys.game.config.width, this.sys.game.config.height, 0x1a1a2e); + + // 创建网格地面 + const gridGraphics = this.add.graphics(); + gridGraphics.lineStyle(1, 0x333333, 0.5); + + const gridSize = 32; + const gridCount = 50; + + for (let x = -gridCount; x <= gridCount; x++) { + gridGraphics.moveTo(x * gridSize, -gridCount * gridSize); + gridGraphics.lineTo(x * gridSize, gridCount * gridSize); + } + + for (let y = -gridCount; y <= gridCount; y++) { + gridGraphics.moveTo(-gridCount * gridSize, y * gridSize); + gridGraphics.lineTo(gridCount * gridSize, y * gridSize); + } + + gridGraphics.stroke(); + } + + /** + * 创建玩家 + */ + createPlayer() { + // 为玩家创建纯色纹理 + if (!this.textures.exists('player')) { + const canvas = document.createElement('canvas'); + canvas.width = 32; + canvas.height = 32; + const ctx = canvas.getContext('2d'); + ctx.fillStyle = '#4a90e2'; + ctx.beginPath(); + ctx.arc(16, 16, 16, 0, Math.PI * 2); + ctx.fill(); + this.textures.addCanvas('player', canvas); + } + + // 创建玩家单位 + this.player = new Unit(this, 0, 0, 'player'); + + // 设置玩家属性 + this.player.name = '测试玩家'; + this.player.health = 100; + this.player.nutrition = 100; + this.player.hydration = 100; + this.player.equipWeapon = function(weapon) { + this.weapon = weapon; + console.log(`${this.name} 装备了 ${weapon.name}`); + }; + + // 添加到单位组 + this.unitGroup.add(this.player); + + // 自动选中玩家 + this.events.emit('select-unit', this.player); + + // 添加碰撞检测 + this.physics.add.collider(this.unitGroup, this.unitGroup); + + // 保持相机中心在世界原点 + this.cameras.main.centerOn(0, 0); + } + + /** + * 初始化背包系统 + */ + initInventory() { + // 创建背包(6x4网格) + this.player.inventory = new Inventory(6, 4); + + // 创建背包UI + this.inventoryUI = new InventoryUI(this, this.player.inventory, 40); + } + + /** + * 初始化测试物品 + */ + initTestItems() { + // 给玩家添加一些种子 + const wheatSeed = this.itemManager.createItem('wheat_seed', 0, 0); + const carrotSeed = this.itemManager.createItem('carrot_seed', 0, 0); + + // 将种子添加到玩家背包 + if (wheatSeed) { + this.player.inventory.addItem(wheatSeed); + wheatSeed.destroy(); + } + + if (carrotSeed) { + this.player.inventory.addItem(carrotSeed); + carrotSeed.destroy(); + } + + // 更新背包UI + this.inventoryUI.updateUI(); + } + + /** + * 设置输入处理 + */ + setupInput() { + console.log('DEBUG: setupInput 方法被调用'); + + // 键盘输入 + this.cursors = this.input.keyboard.createCursorKeys(); + + // 背包快捷键(B键) + this.input.keyboard.on('keydown-B', () => { + console.log('DEBUG: B键被按下,切换背包显示'); + this.inventoryUI.toggle(); + }); + + // 空格键返回启动场景 + this.input.keyboard.on('keydown-SPACE', () => { + console.log('DEBUG: 空格键被按下,返回启动场景'); + this.scene.start('BootScene'); + }); + + // 鼠标左键点击地面种植作物 + this.input.on('pointerdown', (pointer) => { + console.log(`DEBUG: 鼠标点击事件触发,按键: ${pointer.button}, 位置: x=${pointer.x}, y=${pointer.y}`); + console.log(`DEBUG: 当前种植模式状态: isPlantingMode=${this.isPlantingMode}, selectedSeed=${this.selectedSeed ? this.selectedSeed.name : 'null'}`); + + if (this.isPlantingMode && this.selectedSeed) { + console.log('DEBUG: 满足种植条件,调用 plantSeedAt 方法'); + this.plantSeedAt(pointer); + } + }); + + // 鼠标右键取消种植模式 + this.input.on('pointerdown', (pointer) => { + if (pointer.rightButtonDown()) { + console.log('DEBUG: 鼠标右键点击,取消种植模式'); + this.cancelPlantingMode(); + } + }); + + // 创建交互按钮 + this.createButtons(); + console.log('DEBUG: 输入处理设置完成'); + } + + /** + * 创建交互按钮 + */ + createButtons() { + const buttonWidth = 200; + const buttonHeight = 40; + const buttonY = this.sys.game.config.height - 100; + + // 创建随机物品按钮 + this.createButton(this.sys.game.config.width - buttonWidth - 10, buttonY, '创建随机种子', () => { + const seedTypes = ['wheat_seed', 'carrot_seed']; + const randomSeedType = seedTypes[Math.floor(Math.random() * seedTypes.length)]; + this.itemManager.createItem(randomSeedType, this.player.x + 50, this.player.y); + }); + } + + /** + * 创建按钮 + */ + createButton(x, y, text, callback) { + // 创建按钮背景 + const button = this.add.rectangle(x, y, 200, 40, 0x333333); + button.setOrigin(0.5, 0.5); + button.setScrollFactor(0, 0); + button.setDepth(15); + + // 创建按钮文本 + const buttonText = this.add.text(x, y, text, { + fontSize: '16px', + fill: '#ffffff', + fontFamily: 'Arial' + }); + buttonText.setOrigin(0.5, 0.5); + buttonText.setScrollFactor(0, 0); + buttonText.setDepth(16); + + // 设置按钮交互 + button.setInteractive({ + useHandCursor: true + }); + + // 按钮事件 + button.on('pointerdown', callback); + + button.on('pointerover', () => { + button.setFillStyle(0x555555); + }); + + button.on('pointerout', () => { + button.setFillStyle(0x333333); + }); + } + + /** + * 开始种植模式 + */ + startPlantingMode(seed, user) { + console.log('DEBUG: startPlantingMode 方法被调用'); + console.log(`DEBUG: 种子信息: ${JSON.stringify(seed.getInfo())}`); + + this.isPlantingMode = true; + this.selectedSeed = seed; + console.log(`DEBUG: 设置 isPlantingMode = ${this.isPlantingMode}, selectedSeed = ${this.selectedSeed.name}`); + + this.generalInfoText.setText(`点击地面种植 ${seed.name}`); + console.log(`DEBUG: 更新提示信息: 点击地面种植 ${seed.name}`); + + // 显示种植光标,初始位置设置为当前鼠标位置 + console.log(`DEBUG: 当前鼠标位置: x=${this.input.mousePointer.x}, y=${this.input.mousePointer.y}`); + this.plantingCursor = this.add.text(this.input.mousePointer.x, this.input.mousePointer.y, '🌱', { + fontSize: '24px' + }); + + console.log(`DEBUG: 种植光标创建结果: ${this.plantingCursor ? '成功' : '失败'}`); + + this.plantingCursor.setOrigin(0.5, 0.5); + this.plantingCursor.setScrollFactor(0, 0); + this.plantingCursor.setDepth(100); + + console.log(`DEBUG: 种植光标属性设置完成: origin=${this.plantingCursor.originX},${this.plantingCursor.originY}, scrollFactor=${this.plantingCursor.scrollFactorX}, depth=${this.plantingCursor.depth}`); + + // 存储当前场景引用,确保回调函数中this指向正确 + const scene = this; + + // 跟随鼠标移动 - 使用命名的事件监听器,方便后续移除 + this.mouseMoveListener = (pointer) => { + console.log(`DEBUG: 鼠标移动事件触发,指针位置: x=${pointer.x}, y=${pointer.y}`); + scene.plantingCursor.setPosition(pointer.x, pointer.y); + }; + + // 添加鼠标移动事件监听 + console.log('DEBUG: 添加鼠标移动事件监听'); + this.input.on('pointermove', this.mouseMoveListener); + console.log('DEBUG: 种植模式启动完成'); + } + + /** + * 取消种植模式 + */ + cancelPlantingMode() { + console.log('DEBUG: cancelPlantingMode 方法被调用'); + + this.isPlantingMode = false; + this.selectedSeed = null; + console.log(`DEBUG: 重置种植模式状态: isPlantingMode=${this.isPlantingMode}, selectedSeed=${this.selectedSeed}`); + + this.generalInfoText.setText('欢迎使用种田功能测试场景'); + console.log('DEBUG: 重置提示信息'); + + if (this.plantingCursor) { + console.log('DEBUG: 销毁种植光标'); + this.plantingCursor.destroy(); + this.plantingCursor = null; + console.log(`DEBUG: 种植光标销毁结果: ${this.plantingCursor ? '失败' : '成功'}`); + } + + // 移除鼠标移动事件监听 - 使用存储的监听器引用 + if (this.mouseMoveListener) { + console.log('DEBUG: 移除鼠标移动事件监听'); + this.input.off('pointermove', this.mouseMoveListener); + this.mouseMoveListener = null; + console.log(`DEBUG: 鼠标移动监听器移除结果: ${this.mouseMoveListener ? '失败' : '成功'}`); + } + + console.log('DEBUG: 种植模式取消完成'); + } + + /** + * 在指定位置种植种子 + */ + plantSeedAt(pointer) { + console.log('DEBUG: plantSeedAt 方法被调用'); + + // 将屏幕坐标转换为世界坐标 + const worldPoint = this.cameras.main.getWorldPoint(pointer.x, pointer.y); + console.log(`DEBUG: 屏幕坐标转世界坐标: 屏幕(${pointer.x},${pointer.y}) -> 世界(${worldPoint.x},${worldPoint.y})`); + + // 创建作物 + console.log(`DEBUG: 准备创建作物,类型: ${this.selectedSeed.properties.crop_type}, 生长时间: ${this.selectedSeed.properties.growth_time}`); + + const crop = new Crop( + this, + worldPoint.x, + worldPoint.y, + this.selectedSeed.properties.crop_type, + this.selectedSeed.properties.growth_time + ); + + console.log(`DEBUG: 作物创建结果: ${crop ? '成功' : '失败'}`); + + // 添加到作物组 + this.cropGroup.add(crop); + console.log(`DEBUG: 作物已添加到作物组,当前作物数量: ${this.cropGroup.getLength()}`); + + // 显示种植成功消息 + this.showMessage(`已种植 ${this.selectedSeed.name}`); + console.log(`DEBUG: 显示种植成功消息: 已种植 ${this.selectedSeed.name}`); + + // 取消种植模式 + this.cancelPlantingMode(); + console.log('DEBUG: 种植完成,取消种植模式'); + } + + /** + * 收获作物 + */ + harvestCrop(crop) { + // 创建对应的作物物品 + const cropItemId = crop.cropType; + const cropItem = this.itemManager.createItem(cropItemId, crop.x, crop.y); + + // 尝试将作物添加到玩家背包 + if (cropItem) { + if (this.player.inventory) { + const success = this.player.inventory.addItem(cropItem); + if (success) { + // 更新背包UI + this.inventoryUI.updateUI(); + this.showMessage(`收获了 ${cropItem.name}`); + cropItem.destroy(); // 从地面移除,已添加到背包 + } else { + // 背包满了,作物掉在地上 + this.showMessage(`背包已满,${cropItem.name} 掉在地上了`); + } + } + } + } + + /** + * 显示提示信息 + */ + showInstructions() { + const titleText = this.add.text(10, 10, '种田功能测试场景', { + fontSize: '20px', + fill: '#ffffff' + }); + titleText.setScrollFactor(0, 0); + titleText.setDepth(10); + + const moveText = this.add.text(10, 40, 'WASD或方向键移动单位,左键点击选择单位', { + fontSize: '16px', + fill: '#ffffff' + }); + moveText.setScrollFactor(0, 0); + moveText.setDepth(10); + + const inventoryText = this.add.text(10, 70, '按B键打开/关闭背包', { + fontSize: '16px', + fill: '#ffffff' + }); + inventoryText.setScrollFactor(0, 0); + inventoryText.setDepth(10); + + const plantingText = this.add.text(10, 100, '在背包中使用种子,然后点击地面种植', { + fontSize: '16px', + fill: '#ffffff' + }); + plantingText.setScrollFactor(0, 0); + plantingText.setDepth(10); + + const harvestText = this.add.text(10, 130, '点击成熟的作物进行收获', { + fontSize: '16px', + fill: '#ffffff' + }); + harvestText.setScrollFactor(0, 0); + harvestText.setDepth(10); + + const spaceText = this.add.text(10, 160, '按空格键返回启动场景', { + fontSize: '16px', + fill: '#ffffff' + }); + spaceText.setScrollFactor(0, 0); + spaceText.setDepth(10); + } + + /** + * 创建侧边栏UI + */ + createSidebar() { + // 侧边栏宽度 + const sidebarWidth = 300; + const sidebarDepth = 5; + + // 创建侧边栏背景 + this.sidebar = this.add.rectangle( + this.sys.game.config.width - sidebarWidth, + 0, + sidebarWidth, + this.sys.game.config.height, + 0x111111, + 0.9 + ); + this.sidebar.setOrigin(0, 0); + this.sidebar.setScrollFactor(0, 0); + this.sidebar.setDepth(sidebarDepth); + + // 添加侧边栏边框 + this.sidebarBorder = this.add.rectangle( + this.sys.game.config.width - sidebarWidth, + 0, + sidebarWidth, + this.sys.game.config.height, + 0x444444, + 0 + ); + this.sidebarBorder.setOrigin(0, 0); + this.sidebarBorder.setStrokeStyle(2, 0x444444, 1); + this.sidebarBorder.setScrollFactor(0, 0); + this.sidebarBorder.setDepth(sidebarDepth + 1); + + // 侧边栏标题 + const title = this.add.text( + this.sys.game.config.width - sidebarWidth + 20, + 20, + '游戏信息面板', + { + fontSize: '20px', + fill: '#ffffff', + fontWeight: 'bold' + } + ); + title.setScrollFactor(0, 0); + title.setDepth(sidebarDepth + 2); + + // 通用信息区域标题 + const generalTitle = this.add.text( + this.sys.game.config.width - sidebarWidth + 20, + 50, + '通用信息:', + { + fontSize: '16px', + fill: '#4CAF50', + fontWeight: 'bold' + } + ); + generalTitle.setScrollFactor(0, 0); + generalTitle.setDepth(sidebarDepth + 2); + + this.generalInfoText = this.add.text( + this.sys.game.config.width - sidebarWidth + 20, + 75, + '', + { + fontSize: '14px', + fill: '#ffffff', + wordWrap: { + width: sidebarWidth - 40 + } + } + ); + this.generalInfoText.setScrollFactor(0, 0); + this.generalInfoText.setDepth(sidebarDepth + 2); + + // 角色属性区域标题 + const characterTitle = this.add.text( + this.sys.game.config.width - sidebarWidth + 20, + 120, + '角色属性:', + { + fontSize: '16px', + fill: '#2196F3', + fontWeight: 'bold' + } + ); + characterTitle.setScrollFactor(0, 0); + characterTitle.setDepth(sidebarDepth + 2); + + this.unitStatusText = this.add.text( + this.sys.game.config.width - sidebarWidth + 20, + 145, + '', + { + fontSize: '14px', + fill: '#ffffff', + wordWrap: { + width: sidebarWidth - 40 + } + } + ); + this.unitStatusText.setScrollFactor(0, 0); + this.unitStatusText.setDepth(sidebarDepth + 2); + } + + /** + * 更新单位状态显示 + */ + updateUnitStatus(unit) { + let statusText = `${unit.name} 状态:\n`; + statusText += `生命值: ${unit.health}\n`; + statusText += `营养值: ${unit.nutrition}\n`; + statusText += `水分值: ${unit.hydration}\n`; + if (unit.weapon) { + statusText += `武器: ${unit.weapon.name}`; + } + + this.unitStatusText.setText(statusText); + } + + /** + * 显示消息 + */ + showMessage(message) { + // 创建消息 + const messageText = this.add.text( + this.player.x, + this.player.y - 50, + message, + { + font: '20px Arial', + fill: '#ffffff', + backgroundColor: '#000000', + padding: { x: 10, y: 5 } + } + ); + messageText.setOrigin(0.5, 0.5); + messageText.setDepth(20); + messageText.setScrollFactor(1); + + // 3秒后自动移除消息 + this.time.delayedCall(3000, () => { + if (messageText) { + messageText.destroy(); + } + }); + } + + update() { + this.inputSystem.update(); + + // 更新所有单位 + this.unitGroup.getChildren().forEach(unit => { + if (unit.update) { + unit.update(); + } + unit.updateMovement(); + // 更新单位状态显示 + this.updateUnitStatus(unit); + }); + } +} \ No newline at end of file