Files

201 lines
7.3 KiB
JavaScript
Raw Permalink 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.
// 游戏场景文件:这是游戏的主要场景,包含了游戏的核心逻辑和玩法实现
// 导入单位类:用于创建游戏中的角色/单位
import Unit from '../objects/Unit.js';
// 导入输入系统:处理玩家的键盘和鼠标输入
import { InputSystem } from '../systems/InputSystem.js';
// 导入选择系统:处理单位的选择逻辑
import { SelectionSystem } from '../systems/SelectionSystem.js';
// 导入命令系统:处理玩家对单位的命令(如移动、攻击等)
import { CommandSystem } from '../systems/CommandSystem.js';
// 导入虚拟摇杆:用于移动设备上的操作控制
import { VirtualJoystick } from '../ui/VirtualJoystick.js';
// 导入小地图:显示游戏世界的缩略图
import { MiniMap } from '../ui/MiniMap.js';
// 定义GameScene类,继承自Phaser.Scene(Phaser框架的场景类)
export default class GameScene extends Phaser.Scene {
// 构造函数:初始化场景,设置场景的唯一键值
constructor() {
super({ key: 'GameScene' });
}
// create方法:当场景创建时自动调用,用于初始化游戏元素
create() {
// 设置背景颜色
this.cameras.main.setBackgroundColor('#333333')
// === 0. 添加窗口大小变化监听 ===
// 监听浏览器窗口大小变化事件,当窗口大小改变时调用resizeGame方法
window.addEventListener('resize', this.resizeGame.bind(this));
// === 1. 创建玩家纹理===
// 检查是否已经存在名为'player'的纹理,如果不存在则创建
if (!this.textures.exists('player')) {
// 创建一个32x32像素的HTML5 Canvas元素
const canvas = document.createElement('canvas');
canvas.width = 32; // 设置Canvas宽度
canvas.height = 32; // 设置Canvas高度
// 获取Canvas的2D绘图上下文
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#000000ff'; // 设置填充颜色为完全不透明的黑色
ctx.beginPath(); // 开始绘制路径
// 绘制一个圆形:圆心(16,16),半径14,从0到2π(完整圆形)
ctx.arc(16, 16, 14, 0, Math.PI * 2);
ctx.fill(); // 填充圆形
// 将创建的Canvas添加到Phaser的纹理管理器中,命名为'player'
this.textures.addCanvas('player', canvas);
}
// === 2. 物理世界和相机边界===
// 定义游戏世界的大小
const worldSize = 2000;
// 设置物理世界的边界:从(-worldSize,-worldSize)到(worldSize*2, worldSize*2)
// 这样游戏世界的中心就是(0,0),范围是从-2000到2000,总共4000x4000大小
this.physics.world.setBounds(-worldSize, -worldSize, worldSize * 2, worldSize * 2);
// 设置相机的边界,与物理世界边界相同
this.cameras.main.setBounds(-worldSize, -worldSize, worldSize * 2, worldSize * 2);
// 设置相机起始位置在地图中心
// 使用centerOn方法将相机中心定位在地图坐标(0, 0)
this.cameras.main.centerOn(0, 0); // 地图中心坐标是(0, 0)
// === 3. 初始化系统 ===
// 创建输入系统实例
this.inputSystem = new InputSystem(this);
// 创建选择系统实例
this.selectionSystem = new SelectionSystem(this);
// 创建命令系统实例
this.commandSystem = new CommandSystem(this);
// 创建虚拟摇杆实例
this.virtualJoystick = new VirtualJoystick(this);
// === 4. 创建单位组 ===
// 创建一个单位组,用于管理游戏中的所有单位
this.unitGroup = this.add.group();
// 创建5个玩家单位
for (let i = 0; i < 5; i++) {
// 计算单位的初始位置
const worldSizePersent = worldSize/100; // 世界大小的1%
// 每个单位的x坐标递增2%世界大小,y坐标固定为2%世界大小
const unit = new Unit(this, worldSizePersent + 2*i * worldSizePersent, 2 * worldSizePersent, 'player');
// 将创建的单位添加到单位组中
this.unitGroup.add(unit);
}
// === 5. 添加角色之间的碰撞检测 ===
// 为单位组添加碰撞检测,使得单位之间可以相互碰撞
this.physics.add.collider(this.unitGroup, this.unitGroup);
// === 6. 创建小地图 ===
// 创建小地图实例,设置其位置和大小
this.miniMap = new MiniMap(this, {
worldSize: worldSize, // 游戏世界大小
mapSize: 200, // 小地图显示大小
x: this.sys.game.config.width - 200 - 10, // 小地图在屏幕上的x坐标
y: 10 // 小地图在屏幕上的y坐标
});
// === 7. 添加菜单按钮 ===
// 添加返回菜单按钮
const menuButton = this.add.text(
20, // x坐标
20, // y坐标
'返回菜单', // 文本内容
{ fontSize: '16px', color: '#ffffff' } // 样式
).setOrigin(0, 0);
// 为返回菜单按钮添加点击区域
const menuClickArea = this.add.rectangle(
menuButton.x + menuButton.width / 2,
menuButton.y + menuButton.height / 2,
menuButton.width + 20,
menuButton.height + 10,
0x000000,
0 // 透明
).setOrigin(0.5, 0.5);
// 设置返回菜单按钮可交互
menuClickArea.setInteractive({ useHandCursor: true });
// 添加返回菜单按钮点击事件
menuClickArea.on('pointerdown', () => {
console.log('Return to menu clicked');
// 直接切换到菜单场景
this.scene.start('MenuScene');
});
// 添加进入boot菜单按钮
const bootButton = this.add.text(
20, // x坐标
60, // y坐标
'进入Boot菜单', // 文本内容
{ fontSize: '16px', color: '#ffffff' } // 样式
).setOrigin(0, 0);
// 为进入boot菜单按钮添加点击区域
const bootClickArea = this.add.rectangle(
bootButton.x + bootButton.width / 2,
bootButton.y + bootButton.height / 2,
bootButton.width + 20,
bootButton.height + 10,
0x000000,
0 // 透明
).setOrigin(0.5, 0.5);
// 设置进入boot菜单按钮可交互
bootClickArea.setInteractive({ useHandCursor: true });
// 添加进入boot菜单按钮点击事件
bootClickArea.on('pointerdown', () => {
console.log('Enter boot menu clicked');
// 直接切换到boot场景
this.scene.start('BootScene');
});
}
// update方法:每帧自动调用(约60次/秒),用于更新游戏状态
update() {
// 更新输入系统,处理玩家的键盘和鼠标输入
this.inputSystem.update();
// 更新所有单位的移动逻辑和选中状态
// 获取单位组中的所有子元素(即所有单位)
this.unitGroup.getChildren().forEach(unit => {
// 如果单位有自己的update方法,则调用它
if (unit.update) {
unit.update();
}
// 调用单位的updateMovement方法,更新单位的移动状态
unit.updateMovement();
});
// 更新小地图显示
if (this.miniMap) {
this.miniMap.update();
}
// 更新虚拟摇杆状态
if (this.virtualJoystick) {
this.virtualJoystick.update();
}
}
/**
* 窗口大小变化时的处理函数
* 当浏览器窗口大小改变时,调整游戏画布的大小以适应新窗口
*/
resizeGame() {
// 调用Phaser的scale.resize方法,将游戏画布大小调整为当前窗口大小
this.scale.resize(window.innerWidth, window.innerHeight);
}
}