mirror of
http://junepve.top:3000/chicrobot/CINC.git
synced 2026-10-29 21:41:29 +08:00
feat(fog) 添加迷雾场景
This commit is contained in:
1 parent
556d576060
commit
c09770753f
4 files changed
+286
-3
No files matched your search
@@ -32,6 +32,8 @@ import FarmingTestScene from './scenes/testScenes/FarmingTestScene.js';
|
||||
import SkillTestScene from './scenes/testScenes/SkillTestScene.js';
|
||||
// 导入攻击技能测试场景
|
||||
import AttackSkillTestScene from './scenes/testScenes/AttackSkillTestScene.js';
|
||||
// 导入迷雾测试场景
|
||||
import FogOfWarTestScene from './scenes/testScenes/FogOfWarTestScene.js';
|
||||
// 导入菜单场景
|
||||
import MenuScene from './scenes/MenuScene.js';
|
||||
|
||||
@@ -60,7 +62,8 @@ const config = {
|
||||
MapEditTestScene,
|
||||
FarmingTestScene,
|
||||
SkillTestScene,
|
||||
AttackSkillTestScene
|
||||
AttackSkillTestScene,
|
||||
FogOfWarTestScene
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ export default class BootScene extends Phaser.Scene {
|
||||
|
||||
// 测试场景列表
|
||||
const testScenes = [
|
||||
{ key: 'FogOfWarTestScene', name: '测试场景17:迷雾系统测试' },
|
||||
{ key: 'AttackSkillTestScene', name: '测试场景16:攻击技能测试' },
|
||||
{ key: 'SkillTestScene', name: '测试场景15:技能移动效果测试' },
|
||||
{ key: 'FarmingTestScene', name: '测试场景14:种田功能测试' },
|
||||
|
||||
+28
-2
@@ -417,6 +417,13 @@ export default class MenuScene extends Phaser.Scene {
|
||||
// 添加开始按钮点击事件
|
||||
startClickArea.on('pointerdown', () => {
|
||||
console.log('Start game clicked');
|
||||
|
||||
// 清除所有与涟漪相关的延迟调用,避免场景切换后仍然执行
|
||||
this.rippleTimeouts.forEach(timeoutId => {
|
||||
clearTimeout(timeoutId);
|
||||
});
|
||||
this.rippleTimeouts = [];
|
||||
|
||||
// 添加进入场景前的过渡动画
|
||||
this.cameras.main.fadeOut(500, 0, 0, 0);
|
||||
this.cameras.main.once('camerafadeoutcomplete', () => {
|
||||
@@ -582,7 +589,10 @@ export default class MenuScene extends Phaser.Scene {
|
||||
for (let i = 0; i < rippleCount; i++) {
|
||||
// 随机延迟开始
|
||||
const timeoutId = setTimeout(() => {
|
||||
this.createSingleRipple(screenWidth, screenHeight);
|
||||
// 确保场景仍然存在且 rippleGroup 存在
|
||||
if (this.scene && this.rippleGroup) {
|
||||
this.createSingleRipple(screenWidth, screenHeight);
|
||||
}
|
||||
}, Phaser.Math.Between(0, 3000));
|
||||
|
||||
// 将timeout ID保存到数组中
|
||||
@@ -609,7 +619,7 @@ export default class MenuScene extends Phaser.Scene {
|
||||
// 延迟创建后续的涟漪层
|
||||
const timeoutId = setTimeout(() => {
|
||||
// 只有在雨天效果开启时,才创建新的涟漪
|
||||
if (this.isRainEnabled) {
|
||||
if (this.isRainEnabled && this.rippleGroup) {
|
||||
// 创建涟漪圆圈(只保留边框)
|
||||
const ripple = this.add.circle(
|
||||
x,
|
||||
@@ -662,4 +672,20 @@ export default class MenuScene extends Phaser.Scene {
|
||||
this.rippleTimeouts.push(timeoutId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 场景关闭时的清理工作
|
||||
*/
|
||||
shutdown() {
|
||||
// 清除所有与涟漪相关的延迟调用
|
||||
this.rippleTimeouts.forEach(timeoutId => {
|
||||
clearTimeout(timeoutId);
|
||||
});
|
||||
|
||||
// 清空timeout数组
|
||||
this.rippleTimeouts = [];
|
||||
|
||||
// 调用父类的shutdown方法
|
||||
super.shutdown();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,253 @@
|
||||
// 测试场景:迷雾测试
|
||||
import Unit from '../../objects/Unit.js';
|
||||
import { InputSystem } from '../../systems/InputSystem.js';
|
||||
import { SelectionSystem } from '../../systems/SelectionSystem.js';
|
||||
import { CommandSystem } from '../../systems/CommandSystem.js';
|
||||
|
||||
export default class FogOfWarTestScene extends Phaser.Scene {
|
||||
constructor() {
|
||||
super({ key: 'FogOfWarTestScene' });
|
||||
}
|
||||
|
||||
create() {
|
||||
// 创建玩家纹理
|
||||
if (!this.textures.exists('player')) {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = 32;
|
||||
canvas.height = 32;
|
||||
const ctx = canvas.getContext('2d');
|
||||
ctx.fillStyle = '#000000ff';
|
||||
ctx.beginPath();
|
||||
ctx.arc(16, 16, 14, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
this.textures.addCanvas('player', canvas);
|
||||
}
|
||||
|
||||
// 创建敌人纹理
|
||||
if (!this.textures.exists('enemy')) {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = 32;
|
||||
canvas.height = 32;
|
||||
const ctx = canvas.getContext('2d');
|
||||
ctx.fillStyle = '#ff0000ff';
|
||||
ctx.beginPath();
|
||||
ctx.arc(16, 16, 14, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
this.textures.addCanvas('enemy', canvas);
|
||||
}
|
||||
|
||||
// 物理世界和相机边界
|
||||
const worldSize = 2000;
|
||||
this.physics.world.setBounds(-worldSize, -worldSize, worldSize * 2, worldSize * 2);
|
||||
this.cameras.main.setBounds(-worldSize, -worldSize, worldSize * 2, worldSize * 2);
|
||||
this.cameras.main.centerOn(0, 0);
|
||||
|
||||
// 初始化系统 - 开启鼠标移动和框选
|
||||
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.playerUnit = new Unit(this, 0, 0, 'player');
|
||||
this.playerUnit.setDepth(2); // 确保玩家在迷雾之上
|
||||
this.unitGroup.add(this.playerUnit);
|
||||
|
||||
// 自动选中玩家单位
|
||||
this.events.emit('select-unit', this.playerUnit);
|
||||
|
||||
// 创建多个敌人单位,分布在不同位置
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const x = Math.random() * 1600 - 800;
|
||||
const y = Math.random() * 1600 - 800;
|
||||
const enemyUnit = new Unit(this, x, y, 'enemy');
|
||||
enemyUnit.setDepth(2); // 确保敌人在迷雾之上
|
||||
this.unitGroup.add(enemyUnit);
|
||||
}
|
||||
|
||||
// 添加碰撞检测
|
||||
this.physics.add.collider(this.unitGroup, this.unitGroup);
|
||||
|
||||
// 创建迷雾系统
|
||||
this.createFogOfWar(worldSize);
|
||||
|
||||
// 添加场景说明文本
|
||||
const titleText = this.add.text(10, 10, '测试场景:迷雾测试', {
|
||||
fontSize: '20px',
|
||||
fill: '#ffffff'
|
||||
});
|
||||
titleText.setScrollFactor(0, 0); // 固定在屏幕上,不随相机移动
|
||||
titleText.setDepth(10); // 设置深度,确保显示在游戏元素上方
|
||||
|
||||
const fogText = this.add.text(10, 40, '玩家周围会显示视野,迷雾会随玩家移动而变化', {
|
||||
fontSize: '16px',
|
||||
fill: '#ffffff'
|
||||
});
|
||||
fogText.setScrollFactor(0, 0); // 固定在屏幕上,不随相机移动
|
||||
fogText.setDepth(10); // 设置深度,确保显示在游戏元素上方
|
||||
|
||||
const controlsText = this.add.text(10, 70, 'WASD或方向键移动视角,鼠标右键移动单位', {
|
||||
fontSize: '16px',
|
||||
fill: '#ffffff'
|
||||
});
|
||||
controlsText.setScrollFactor(0, 0); // 固定在屏幕上,不随相机移动
|
||||
controlsText.setDepth(10); // 设置深度,确保显示在游戏元素上方
|
||||
|
||||
const spaceText = this.add.text(10, 100, '按空格键返回菜单', {
|
||||
fontSize: '16px',
|
||||
fill: '#ffffff'
|
||||
});
|
||||
spaceText.setScrollFactor(0, 0); // 固定在屏幕上,不随相机移动
|
||||
spaceText.setDepth(10); // 设置深度,确保显示在游戏元素上方
|
||||
|
||||
// 空格键切换场景
|
||||
this.input.keyboard.on('keydown-SPACE', () => {
|
||||
this.scene.start('BootScene');
|
||||
});
|
||||
|
||||
// 添加返回菜单按钮
|
||||
this.createReturnButton();
|
||||
|
||||
// 添加相机移动控制
|
||||
this.cameraSpeed = 2;
|
||||
this.cameraKeys = this.input.keyboard.addKeys({
|
||||
up: Phaser.Input.Keyboard.KeyCodes.W,
|
||||
down: Phaser.Input.Keyboard.KeyCodes.S,
|
||||
left: Phaser.Input.Keyboard.KeyCodes.A,
|
||||
right: Phaser.Input.Keyboard.KeyCodes.D
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建返回菜单按钮
|
||||
*/
|
||||
createReturnButton() {
|
||||
// 创建按钮背景
|
||||
const button = this.add.rectangle(10, 130, 150, 40, 0x333333);
|
||||
button.setOrigin(0, 0);
|
||||
button.setScrollFactor(0, 0);
|
||||
button.setDepth(10);
|
||||
button.setInteractive({ useHandCursor: true });
|
||||
|
||||
// 按钮文本
|
||||
const buttonText = this.add.text(25, 140, '返回菜单', {
|
||||
fontSize: '16px',
|
||||
fill: '#ffffff',
|
||||
fontFamily: 'Arial'
|
||||
});
|
||||
buttonText.setScrollFactor(0, 0);
|
||||
buttonText.setDepth(11);
|
||||
|
||||
// 按钮事件
|
||||
button.on('pointerdown', () => {
|
||||
this.scene.start('BootScene');
|
||||
});
|
||||
|
||||
button.on('pointerover', () => {
|
||||
button.setFillStyle(0x555555);
|
||||
});
|
||||
|
||||
button.on('pointerout', () => {
|
||||
button.setFillStyle(0x333333);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建迷雾系统
|
||||
* @param {number} worldSize - 世界大小
|
||||
*/
|
||||
createFogOfWar(worldSize) {
|
||||
// 创建迷雾纹理
|
||||
if (!this.textures.exists('fogTexture')) {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = 64;
|
||||
canvas.height = 64;
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
// 创建渐变效果
|
||||
const gradient = ctx.createRadialGradient(32, 32, 0, 32, 32, 32);
|
||||
gradient.addColorStop(0, 'rgba(0, 0, 0, 0)'); // 中心透明
|
||||
gradient.addColorStop(0.7, 'rgba(0, 0, 0, 0.8)'); // 边缘不透明
|
||||
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.fillRect(0, 0, 64, 64);
|
||||
|
||||
this.textures.addCanvas('fogTexture', canvas);
|
||||
}
|
||||
|
||||
// 创建迷雾图层
|
||||
this.fogLayer = this.add.graphics();
|
||||
this.fogLayer.setDepth(1); // 迷雾在单位之下
|
||||
|
||||
// 视野范围
|
||||
this.viewRange = 300;
|
||||
|
||||
// 更新迷雾
|
||||
this.updateFogOfWar();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新迷雾
|
||||
*/
|
||||
updateFogOfWar() {
|
||||
if (!this.playerUnit) return;
|
||||
|
||||
// 清除当前迷雾
|
||||
this.fogLayer.clear();
|
||||
|
||||
// 获取玩家位置
|
||||
const playerX = this.playerUnit.x;
|
||||
const playerY = this.playerUnit.y;
|
||||
|
||||
// 创建迷雾遮罩
|
||||
this.fogLayer.fillStyle(0x000000, 0.8);
|
||||
this.fogLayer.fillRect(-2000, -2000, 4000, 4000);
|
||||
|
||||
// 创建视野区域(圆形)
|
||||
this.fogLayer.fillStyle(0x000000, 0);
|
||||
this.fogLayer.setBlendMode(Phaser.BlendModes.ERASE);
|
||||
|
||||
// 绘制视野圆
|
||||
this.fogLayer.beginPath();
|
||||
this.fogLayer.arc(playerX, playerY, this.viewRange, 0, Math.PI * 2);
|
||||
this.fogLayer.fillPath();
|
||||
|
||||
// 重置混合模式
|
||||
this.fogLayer.setBlendMode(Phaser.BlendModes.NORMAL);
|
||||
}
|
||||
|
||||
update() {
|
||||
this.inputSystem.update();
|
||||
|
||||
// 更新相机移动
|
||||
if (this.cameraKeys.left.isDown) {
|
||||
this.cameras.main.scrollX -= this.cameraSpeed;
|
||||
}
|
||||
if (this.cameraKeys.right.isDown) {
|
||||
this.cameras.main.scrollX += this.cameraSpeed;
|
||||
}
|
||||
if (this.cameraKeys.up.isDown) {
|
||||
this.cameras.main.scrollY -= this.cameraSpeed;
|
||||
}
|
||||
if (this.cameraKeys.down.isDown) {
|
||||
this.cameras.main.scrollY += this.cameraSpeed;
|
||||
}
|
||||
|
||||
this.unitGroup.getChildren().forEach(unit => {
|
||||
if (unit.update) {
|
||||
unit.update();
|
||||
}
|
||||
unit.updateMovement();
|
||||
});
|
||||
|
||||
// 更新迷雾
|
||||
this.updateFogOfWar();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user