test(TS) 测试场景备份

This commit is contained in:
chicrobot committed 2026-02-03 21:42:57 +08:00
1 parent 4205af8413
commit 5e53dc3ef3
5 files changed
+1364

No files matched your search

+7
View File
@@ -42,6 +42,11 @@ import MenuScene from './scenes/MenuScene.js';
import TmpScene from './scenes/TmpScene.js';
// 导入测试对象场景
import TestObjectsScene from './scenes/testScenes/TestObjectsScene.js';
// 导入角色类测试场景
import CharacterClassTestScene from './scenes/testScenes/CharacterClassTestScene.js';
// 导入武器测试场景
import WeaponTestScene from './scenes/testScenes/WeaponTestScene.js';
// 创建游戏的最终配置对象
const config = {
// 使用扩展运算符(...)将gameConfig中的所有配置项复制到当前对象中
@@ -51,6 +56,8 @@ const config = {
scene: [
MenuScene,
TmpScene,
WeaponTestScene,
CharacterClassTestScene,
TestObjectsScene,
BootScene,
GameScene,
+386
View File
@@ -0,0 +1,386 @@
// objects/Character.js
// 角色类,包含属性、动画、技能等系统
export default class Character extends Phaser.Physics.Arcade.Sprite {
constructor(scene, x, y, config) {
super(scene, x, y, config.texture || 'player0-0');
scene.add.existing(this);
scene.physics.add.existing(this);
// 配置
this.config = config;
// 设置角色原点为底部中点
this.setOrigin(0.5, 1);
// 设置角色深度,确保显示在指示器上方
this.setDepth(10);
// 启用圆形碰撞体
this.setCircle(config.collisionRadius || 14);
// 启用与世界边界的碰撞
this.setCollideWorldBounds(true);
// 初始化系统
this.initSystems();
// 初始化状态
this.state = {
isMoving: false,
isSelected: false,
currentSkill: null,
isCasting: false
};
// 移动控制
this.target = null;
this.canMove = true;
}
/**
* 初始化系统
*/
initSystems() {
// 属性系统
this.initAttributes();
// 动画系统
this.initAnimationSystem();
// 技能系统
this.initSkillSystem();
// 指示器系统
this.initIndicatorSystem();
}
/**
* 初始化属性系统
*/
initAttributes() {
this.attributes = {
health: this.config.health || 100,
maxHealth: this.config.health || 100,
mana: this.config.mana || 50,
maxMana: this.config.mana || 50,
speed: this.config.speed || 150,
attack: this.config.attack || 20,
defense: this.config.defense || 10
};
}
/**
* 初始化动画系统
*/
initAnimationSystem() {
this.animationSystem = {
currentAnimation: null,
animations: this.config.animations || {},
playAnimation: (key) => {
if (!this.anims.isPlaying || this.anims.currentAnim.key !== key) {
this.play(key);
this.animationSystem.currentAnimation = key;
}
},
stopAnimation: () => {
this.anims.stop();
this.animationSystem.currentAnimation = null;
}
};
}
/**
* 初始化技能系统
*/
initSkillSystem() {
this.skills = this.config.skills || [];
this.cooldowns = {};
}
/**
* 初始化指示器系统
*/
initIndicatorSystem() {
// 选中指示器
this.selectedIndicator = this.scene.add.circle(this.x, this.y, this.width * 1.5, 0x00ff00, 0.0);
this.selectedIndicator.setStrokeStyle(2, 0x00ff00, 1);
this.selectedIndicator.setVisible(false);
this.selectedIndicator.setOrigin(0.5, 0.5);
this.selectedIndicator.setScrollFactor(1, 1);
this.selectedIndicator.setDepth(5);
// 目标指示器
this.targetIndicator = null;
// 路径图形
this.pathGraphics = null;
}
/**
* 设置选中状态
* @param {boolean} isSelected
*/
setSelected(isSelected) {
this.state.isSelected = isSelected;
if (this.selectedIndicator) {
this.selectedIndicator.setVisible(isSelected);
}
}
/**
* 设置移动目标
* @param {number} x
* @param {number} y
*/
setTarget(x, y) {
// 获取世界边界
const worldBounds = this.scene.physics.world.bounds;
// 限制目标点在世界边界内
const clampedX = Math.max(worldBounds.x, Math.min(worldBounds.right, x));
const clampedY = Math.max(worldBounds.y, Math.min(worldBounds.bottom, y));
this.target = { x: clampedX, y: clampedY };
// 创建目标指示器
if (!this.targetIndicator) {
this.targetIndicator = this.scene.add.circle(0, 0, 8, 0xff0000, 1);
this.targetIndicator.setOrigin(0.5, 0.5);
this.targetIndicator.setScrollFactor(1, 1);
this.targetIndicator.setDepth(5);
}
// 更新目标指示器位置
this.targetIndicator.setPosition(this.target.x, this.target.y);
this.targetIndicator.setVisible(this.state.isSelected);
// 创建路径图形
if (!this.pathGraphics) {
this.pathGraphics = this.scene.add.graphics();
this.pathGraphics.setScrollFactor(1, 1);
this.pathGraphics.setDepth(5);
}
}
/**
* 清除目标
*/
clearTarget() {
this.target = null;
this.setVelocity(0, 0);
// 隐藏目标指示器
if (this.targetIndicator) {
this.targetIndicator.setVisible(false);
}
// 清除路径
if (this.pathGraphics) {
this.pathGraphics.clear();
}
}
/**
* 相对移动控制
* @param {number} x
* @param {number} y
*/
moveRelative(x, y) {
if (!this.canMove) {
this.setVelocity(0, 0);
return;
}
const speed = this.attributes.speed;
const magnitude = Math.sqrt(x * x + y * y);
if (magnitude > 0) {
this.clearTarget();
this.state.isMoving = true;
const normalizedX = x / magnitude;
const normalizedY = y / magnitude;
this.setVelocity(normalizedX * speed, normalizedY * speed);
// 处理朝向
if (normalizedX < -0.1) {
this.setFlipX(true);
} else if (normalizedX > 0.1) {
this.setFlipX(false);
}
// 播放移动动画
this.animationSystem.playAnimation(this.config.moveAnimation || 'player0-move');
} else {
this.setVelocity(0, 0);
this.state.isMoving = false;
// 停止动画,显示静止帧
this.animationSystem.stopAnimation();
this.setTexture(this.config.idleTexture || 'player0-0');
}
}
/**
* 施放技能
* @param {string} skillId
*/
castSkill(skillId) {
const skill = this.skills.find(s => s.id === skillId);
if (!skill) return false;
// 检查冷却
if (this.cooldowns[skillId] && this.cooldowns[skillId] > this.scene.time.now) {
return false;
}
// 检查 mana
if (this.attributes.mana < skill.cost) {
return false;
}
// 开始施放
this.state.isCasting = true;
this.state.currentSkill = skill;
this.attributes.mana -= skill.cost;
// 设置冷却
this.cooldowns[skillId] = this.scene.time.now + skill.cooldown;
// 播放技能动画
if (skill.animation) {
this.animationSystem.playAnimation(skill.animation);
}
// 执行技能效果
setTimeout(() => {
this.executeSkillEffect(skill);
this.state.isCasting = false;
this.state.currentSkill = null;
}, skill.castTime || 1000);
return true;
}
/**
* 执行技能效果
* @param {Object} skill
*/
executeSkillEffect(skill) {
// 这里可以实现具体的技能效果
console.log(`Executing skill: ${skill.name}`);
// 示例:创建技能特效
if (skill.effect) {
// 实现技能特效逻辑
}
}
/**
* 更新移动逻辑
*/
updateMovement() {
if (!this.target) return;
const dx = this.target.x - this.x;
const dy = this.target.y - this.y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 5) {
this.setPosition(this.target.x, this.target.y);
this.clearTarget();
this.state.isMoving = false;
// 停止动画,显示静止帧
this.animationSystem.stopAnimation();
this.setTexture(this.config.idleTexture || 'player0-0');
} else {
this.state.isMoving = true;
const speed = this.attributes.speed;
const angle = Math.atan2(dy, dx);
this.setVelocity(Math.cos(angle) * speed, Math.sin(angle) * speed);
// 处理朝向
if (Math.cos(angle) < -0.1) {
this.setFlipX(true);
} else if (Math.cos(angle) > 0.1) {
this.setFlipX(false);
}
// 播放移动动画
this.animationSystem.playAnimation(this.config.moveAnimation || 'player0-move');
}
}
/**
* 绘制路径
*/
drawPath() {
if (!this.pathGraphics || !this.target) return;
this.pathGraphics.clear();
this.pathGraphics.lineStyle(2, 0x00ff00, 0.8);
this.pathGraphics.beginPath();
this.pathGraphics.moveTo(this.x, this.y);
this.pathGraphics.lineTo(this.target.x, this.target.y);
this.pathGraphics.stroke();
}
/**
* 更新
*/
update() {
// 更新指示器
this.updateIndicators();
// 更新移动
this.updateMovement();
// 更新路径
if (this.state.isSelected && this.target) {
this.drawPath();
}
}
/**
* 更新指示器
*/
updateIndicators() {
// 更新选中指示器
if (this.selectedIndicator && this.state.isSelected) {
this.selectedIndicator.setPosition(this.x, this.y);
}
// 更新目标指示器
if (this.targetIndicator) {
this.targetIndicator.setVisible(this.state.isSelected && this.target);
}
}
/**
* 获取属性
* @param {string} key
*/
getAttribute(key) {
return this.attributes[key];
}
/**
* 设置属性
* @param {string} key
* @param {number} value
*/
setAttribute(key, value) {
this.attributes[key] = value;
}
/**
* 增加属性
* @param {string} key
* @param {number} value
*/
addAttribute(key, value) {
if (this.attributes[key] !== undefined) {
this.attributes[key] += value;
}
}
}
+2
View File
@@ -17,6 +17,8 @@ export default class BootScene extends Phaser.Scene {
// 测试场景列表
const testScenes = [
{ key: 'WeaponTestScene', name: '测试场景22:武器测试' },
{ key: 'CharacterClassTestScene', name: '测试场景21:角色类测试' },
{ key: 'MultiTouchTestScene', name: '测试场景20:多触摸测试' },
{ key: 'TestObjectsScene', name: '测试场景19:测试对象场景' },
{ key: 'TmpScene', name: '测试场景18:临时场景' },
@@ -0,0 +1,513 @@
// scenes/testScenes/CharacterClassTestScene.js
// 角色类测试场景
import { InputSystem } from '../../systems/InputSystem.js';
import Character from '../../objects/Character.js';
import { VirtualJoystick } from '../../ui/VirtualJoystick.js';
export default class CharacterClassTestScene extends Phaser.Scene {
constructor() {
super({ key: 'CharacterClassTestScene' });
this.character = null;
this.inputSystem = null;
this.cursors = null;
this.keys = null;
// 虚拟摇杆相关
this.virtualJoystick = null;
this.joysticks = [];
}
preload() {
// 加载玩家瓦片图片
console.log('加载角色资源...');
// 加载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的动画帧
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(-worldSize, -worldSize, worldSize * 2, worldSize * 2);
this.cameras.main.setBounds(-worldSize, -worldSize, worldSize * 2, worldSize * 2);
this.cameras.main.centerOn(0, 0);
// 设置背景色
this.cameras.main.setBackgroundColor('#222222');
// 创建地面网格
this.createGrid();
// 创建角色动画
this.createAnimations();
// 初始化输入系统
this.inputSystem = new InputSystem(this, {
keyboard: true,
mouse: true,
selection: true
});
// 创建单位组
this.unitGroup = this.add.group();
// 初始化技能轮盘
this.skillWheel = {
centerX: 0,
centerY: 0,
radius: 60,
isActive: false,
activeSkill: null,
activePointer: null,
skillButtons: [],
skillInfo: {
1: { key: 'skill1', name: '火球术', color: 0xff0000 },
2: { key: 'skill2', name: '治疗术', color: 0x00ff00 }
}
};
// 创建角色
this.createCharacter();
// 创建虚拟摇杆
this.createVirtualJoystick();
// 创建技能轮盘
this.createSkillWheel();
// 绑定技能轮盘事件
this.bindSkillWheelEvents();
// 设置输入控制
this.setupInput();
// 监听move-to-point事件,实现鼠标点击移动
this.events.on('move-to-point', (x, y) => {
if (this.character) {
this.character.setTarget(x, y);
}
});
// 监听select-unit事件
this.events.on('select-unit', (unit) => {
console.log('单位已选中:', unit);
});
// 显示提示信息
this.showInstructions();
}
/**
* 创建地面网格
*/
createGrid() {
const gridGraphics = this.add.graphics();
gridGraphics.lineStyle(1, 0x444444, 0.5);
// 绘制垂直线
for (let x = 0; x <= 2000; x += 16) {
gridGraphics.moveTo(x, 0);
gridGraphics.lineTo(x, 2000);
}
// 绘制水平线
for (let y = 0; y <= 2000; y += 16) {
gridGraphics.moveTo(0, y);
gridGraphics.lineTo(2000, y);
}
}
/**
* 创建角色动画
*/
createAnimations() {
console.log('创建角色动画...');
// 创建Player0的移动动画
this.anims.create({
key: 'player0-move',
frames: [
{ key: 'player0-1' },
{ key: 'player0-2' }
],
frameRate: 10,
repeat: -1
});
// 创建Player0的技能动画
this.anims.create({
key: 'player0-skill',
frames: [
{ key: 'player0-3' },
{ key: 'player0-4' },
{ key: 'player0-5' }
],
frameRate: 15,
repeat: 0
});
console.log('角色动画创建完成');
}
/**
* 创建角色
*/
createCharacter() {
console.log('创建角色...');
// 角色配置
const characterConfig = {
texture: 'player0-0',
idleTexture: 'player0-0',
moveAnimation: 'player0-move',
health: 100,
mana: 50,
speed: 150,
attack: 20,
defense: 10,
collisionRadius: 14,
skills: [
{
id: 'skill1',
name: '火球术',
cost: 10,
cooldown: 3000,
castTime: 1000,
animation: 'player0-skill'
},
{
id: 'skill2',
name: '治疗术',
cost: 15,
cooldown: 5000,
castTime: 1500,
animation: 'player0-skill'
}
]
};
// 创建角色
this.character = new Character(this, 100, 100, characterConfig);
this.character.setScale(2);
// 将角色添加到单位组
this.unitGroup.add(this.character);
// 自动选中角色
this.character.setSelected(true);
console.log('角色创建完成');
}
/**
* 设置输入控制
*/
setupInput() {
// 键盘控制
this.cursors = this.input.keyboard.createCursorKeys();
// 添加WASD键监听
this.keys = {
a: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.A),
d: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.D),
w: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.W),
s: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.S),
space: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE)
};
// 技能按键
this.input.keyboard.on('keydown-Q', () => {
this.character.castSkill('skill1');
});
this.input.keyboard.on('keydown-W', () => {
this.character.castSkill('skill2');
});
// 鼠标点击设置目标由InputSystem处理,通过move-to-point事件
}
/**
* 创建虚拟摇杆
*/
createVirtualJoystick() {
// 创建左侧移动摇杆
this.virtualJoystick = new VirtualJoystick(this, true);
this.virtualJoystick.centerX = 150;
this.virtualJoystick.centerY = this.scale.height - 150;
this.virtualJoystick.base.setPosition(this.virtualJoystick.centerX, this.virtualJoystick.centerY);
this.virtualJoystick.knob.setPosition(this.virtualJoystick.centerX, this.virtualJoystick.centerY);
this.joysticks.push(this.virtualJoystick);
// 监听虚拟摇杆移动事件
this.events.on('move-relative', (direction) => {
if (this.character) {
this.character.moveRelative(direction.x, direction.y);
}
});
}
/**
* 创建技能轮盘
*/
createSkillWheel() {
// 技能轮盘基础位置(右下角)
this.skillWheel.centerX = this.scale.width - 100;
this.skillWheel.centerY = this.scale.height - 100;
// 创建技能轮盘基础(默认隐藏,选中技能时显示)
this.skillWheel.base = this.add.circle(this.skillWheel.centerX, this.skillWheel.centerY, this.skillWheel.radius, 0x444444, 0.5);
this.skillWheel.base.setScrollFactor(0); // 不随相机移动
this.skillWheel.base.setDepth(100);
this.skillWheel.base.setVisible(false);
// 创建技能按钮(扇形排列:技能1-2在右下角左上方,大半径扇形分布)
const skills = [1, 2];
const startAngle = -Math.PI; // 起始角度(-90度,左)
const endAngle = -Math.PI / 2; // 结束角度(0度,上)
const angleRange = endAngle - startAngle;
const angleStep = angleRange / (skills.length - 1);
this.skillWheel.skillButtons = [];
for (let i = 0; i < skills.length; i++) {
const skillIndex = skills[i];
// 计算技能按钮的角度(扇形排列)
const angle = startAngle + i * angleStep;
const distance = 120; // 增大技能按钮距离中心的距离
const x = this.skillWheel.centerX + Math.cos(angle) * distance;
const y = this.skillWheel.centerY + Math.sin(angle) * distance;
// 创建技能按钮
const button = this.add.circle(x, y, 25, this.skillWheel.skillInfo[skillIndex].color, 0.6);
button.setScrollFactor(0);
button.setDepth(100);
// 添加技能按键文本
const text = this.add.text(x, y, skillIndex.toString(), {
fontSize: '14px',
fill: '#000000',
fontFamily: 'Arial',
fontWeight: 'bold'
})
.setOrigin(0.5, 0.5)
.setScrollFactor(0)
.setDepth(101);
// 保存技能信息
button.skillIndex = skillIndex;
button.skillKey = this.skillWheel.skillInfo[skillIndex].key;
button.x = x;
button.y = y;
// 添加点击事件
button.setInteractive({ useHandCursor: true });
button.on('pointerdown', (pointer) => {
// 选中技能后,将轮盘中心设置为技能按钮的中心位置
this.skillWheel.centerX = x;
this.skillWheel.centerY = y;
this.skillWheel.base.setPosition(x, y);
this.skillWheel.base.setVisible(true);
this.skillWheel.activeSkill = skillIndex;
this.startSkillCast(pointer);
});
this.skillWheel.skillButtons.push(button);
}
// 创建轮盘旋钮
this.skillWheel.knob = this.add.circle(this.skillWheel.centerX, this.skillWheel.centerY, this.skillWheel.radius * 0.5, 0xff0000, 0.8);
this.skillWheel.knob.setScrollFactor(0);
this.skillWheel.knob.setDepth(101);
this.skillWheel.knob.setVisible(false);
}
/**
* 绑定技能轮盘事件
*/
bindSkillWheelEvents() {
// 鼠标移动事件
this.input.on('pointermove', (ptr) => {
// 只有在技能轮盘激活时才处理
if (!this.skillWheel.isActive || this.skillWheel.activePointer !== ptr) {
return;
}
// 更新旋钮位置
const dx = ptr.x - this.skillWheel.centerX;
const dy = ptr.y - this.skillWheel.centerY;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance > this.skillWheel.radius) {
// 限制在圆内
const angle = Math.atan2(dy, dx);
const knobX = this.skillWheel.centerX + Math.cos(angle) * this.skillWheel.radius;
const knobY = this.skillWheel.centerY + Math.sin(angle) * this.skillWheel.radius;
this.skillWheel.knob.setPosition(knobX, knobY);
} else {
this.skillWheel.knob.setPosition(ptr.x, ptr.y);
}
});
// 鼠标释放事件
this.input.on('pointerup', (ptr) => {
// 只有在技能轮盘激活时才处理
if (!this.skillWheel.isActive || this.skillWheel.activePointer !== ptr) {
return;
}
// 完成技能释放
this.finishSkillCast();
});
}
/**
* 开始技能施法
*/
startSkillCast(pointer) {
// 设置技能轮盘状态
this.skillWheel.isActive = true;
this.skillWheel.activePointer = pointer;
// 显示旋钮和轮盘基础
this.skillWheel.knob.setVisible(true);
this.skillWheel.base.setVisible(true);
// 设置旋钮初始位置为轮盘中心
this.skillWheel.knob.setPosition(this.skillWheel.centerX, this.skillWheel.centerY);
// 根据技能索引改变旋钮颜色
if (this.skillWheel.activeSkill && this.skillWheel.skillInfo[this.skillWheel.activeSkill]) {
this.skillWheel.knob.fillColor = this.skillWheel.skillInfo[this.skillWheel.activeSkill].color;
}
}
/**
* 完成技能释放
*/
finishSkillCast() {
// 检查是否有激活的技能和角色
if (!this.skillWheel.activeSkill || !this.character) {
return;
}
// 计算技能释放方向
const dx = this.skillWheel.knob.x - this.skillWheel.centerX;
const dy = this.skillWheel.knob.y - this.skillWheel.centerY;
const distance = Math.sqrt(dx * dx + dy * dy);
// 只有当旋钮移动到一定距离时才释放技能
if (distance > 10) {
// 归一化方向向量
const directionX = dx / distance;
const directionY = dy / distance;
// 释放技能
this.character.castSkill(this.skillWheel.skillInfo[this.skillWheel.activeSkill].key);
}
// 重置技能轮盘状态
this.skillWheel.isActive = false;
this.skillWheel.activeSkill = null;
this.skillWheel.activePointer = null;
// 隐藏旋钮和轮盘基础
this.skillWheel.knob.setVisible(false);
this.skillWheel.base.setVisible(false);
}
/**
* 显示提示信息
*/
showInstructions() {
// 标题
this.add.text(20, 20, '角色类测试场景', {
fontSize: '20px',
fill: '#ffffff',
fontFamily: 'Arial',
fontWeight: 'bold'
}).setScrollFactor(0, 0).setDepth(11);
// 操作提示
const instructions = [
'使用左侧虚拟摇杆移动角色',
'鼠标点击设置移动目标',
'右侧红色按钮:施放火球术',
'右侧绿色按钮:施放治疗术',
'角色会自动播放移动动画',
'按空格键返回启动场景'
];
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.add.text(20, 200, '角色属性:', {
fontSize: '16px',
fill: '#00ff00',
fontFamily: 'Arial',
fontWeight: 'bold'
}).setScrollFactor(0, 0).setDepth(11);
}
update() {
// 更新输入系统
if (this.inputSystem) {
this.inputSystem.update();
}
// 更新虚拟摇杆
if (this.virtualJoystick) {
this.virtualJoystick.update();
}
// 键盘移动控制
if (this.cursors && this.keys) {
let moveX = 0;
let moveY = 0;
if (this.cursors.left.isDown || this.keys.a.isDown) {
moveX = -1;
} else if (this.cursors.right.isDown || this.keys.d.isDown) {
moveX = 1;
}
if (this.cursors.up.isDown || this.keys.w.isDown) {
moveY = -1;
} else if (this.cursors.down.isDown || this.keys.s.isDown) {
moveY = 1;
}
// 只有在虚拟摇杆未激活时才使用键盘控制
if (this.character && (!this.virtualJoystick || !this.virtualJoystick.isActive)) {
this.character.moveRelative(moveX, moveY);
}
}
// 更新角色
if (this.character) {
this.character.update();
}
// 按空格键返回启动场景
if (this.keys && this.keys.space.isDown) {
this.scene.start('BootScene');
}
}
}
+456
View File
@@ -0,0 +1,456 @@
// 武器测试场景
// 以角色动画场景为基础,使用\assets\PNG\Weapons\Tiles目录下的武器图片
// 导入系统和UI组件
import { InputSystem } from '../../systems/InputSystem.js';
import { SelectionSystem } from '../../systems/SelectionSystem.js';
import { CommandSystem } from '../../systems/CommandSystem.js';
// 导入Unit类
import Unit from '../../objects/Unit.js';
export default class WeaponTestScene extends Phaser.Scene {
constructor() {
super({ key: 'WeaponTestScene' });
this.tileSize = 16; // 瓦片大小
this.player = null; // 玩家角色
this.inputSystem = null; // 输入系统
this.selectionSystem = null; // 选择系统
this.commandSystem = null; // 命令系统
this.weapons = []; // 武器列表
this.currentWeaponIndex = 0; // 当前选中的武器索引
this.weaponDisplay = null; // 武器展示
}
preload() {
// 加载玩家瓦片图片
console.log('加载玩家瓦片图片...');
// 加载Player0的动画帧
for (let i = 0; i < 8; i++) {
this.load.image(`player0-${i}`, `assets/PNG/Players/Tiles/tile_${String(i).padStart(4, '0')}.png`);
}
// 加载武器图片
console.log('加载武器图片...');
for (let i = 0; i < 40; i++) {
this.load.image(`weapon-${i}`, `assets/PNG/Weapons/Tiles/tile_${String(i).padStart(4, '0')}.png`);
}
console.log('图片加载完成');
}
create() {
// 物理世界和相机边界
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.cameras.main.setBackgroundColor('#222222');
// 创建地面网格
this.createGrid();
// 创建角色动画
this.createCharacterAnimations();
// 初始化系统
this.inputSystem = new InputSystem(this, {
keyboard: true,
mouse: true,
selection: true
});
this.selectionSystem = new SelectionSystem(this);
this.commandSystem = new CommandSystem(this);
// 创建单位组
this.unitGroup = this.add.group();
// 初始化武器列表
this.initWeapons();
// 创建玩家角色
this.createPlayer();
// 设置输入控制
this.setupInput();
// 添加事件监听器
this.addEventListeners();
// 添加碰撞检测
this.physics.add.collider(this.unitGroup, this.unitGroup);
// 显示提示信息
this.showInstructions();
}
/**
* 添加事件监听器
*/
addEventListeners() {
// 监听相对移动事件(键盘控制)
this.events.on('move-relative', (dir) => {
if (this.player) {
this.player.moveRelative(dir.x, dir.y);
}
});
// 监听移动到指定点事件(鼠标点击)
this.events.on('move-to-point', (x, y) => {
if (this.player) {
this.player.setTarget(x, y);
}
});
}
/**
* 创建地面网格
*/
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-1' },
{ key: 'player0-2' }
],
frameRate: 10,
repeat: -1
});
console.log('角色动画创建完成');
}
/**
* 创建玩家角色
*/
createPlayer() {
console.log('创建玩家角色...');
// 创建玩家角色使用Unit类
this.player = new Unit(this, 0, 0, 'player0-0');
this.player.setScale(2); // 放大角色
this.player.setBounce(0.2); // 反弹效果
// 自动选中玩家
this.events.emit('select-unit', this.player);
// 将玩家添加到单位组
this.unitGroup.add(this.player);
// 创建武器展示
this.createWeaponDisplay();
console.log('玩家角色创建完成');
}
/**
* 初始化武器列表
*/
initWeapons() {
console.log('初始化武器列表...');
// 初始化武器数据
for (let i = 0; i < 40; i++) {
this.weapons.push({
id: i,
name: `武器 ${i}`,
texture: `weapon-${i}`,
damage: 10 + i,
range: 1 + Math.floor(i / 10)
});
}
console.log('武器列表初始化完成,共', this.weapons.length, '件武器');
}
/**
* 创建武器展示
*/
createWeaponDisplay() {
// 武器展示背景
const displayBg = this.add.rectangle(100, 300, 180, 100, 0x333333);
displayBg.setOrigin(0.5, 0.5);
displayBg.setScrollFactor(0, 0);
displayBg.setDepth(10);
// 武器图片
this.weaponDisplay = this.add.image(100, 280, `weapon-${this.currentWeaponIndex}`);
this.weaponDisplay.setOrigin(0.5, 0.5);
this.weaponDisplay.setScale(2);
this.weaponDisplay.setScrollFactor(0, 0);
this.weaponDisplay.setDepth(11);
// 武器名称
this.weaponNameText = this.add.text(10, 330, `当前武器: ${this.weapons[this.currentWeaponIndex].name}`, {
fontSize: '14px',
fill: '#ffffff',
fontFamily: 'Arial'
}).setScrollFactor(0, 0).setDepth(11);
// 武器属性
this.weaponStatsText = this.add.text(10, 350, `伤害: ${this.weapons[this.currentWeaponIndex].damage}\n范围: ${this.weapons[this.currentWeaponIndex].range}`, {
fontSize: '12px',
fill: '#cccccc',
fontFamily: 'Arial'
}).setScrollFactor(0, 0).setDepth(11);
}
/**
* 更新武器展示
*/
updateWeaponDisplay() {
const weapon = this.weapons[this.currentWeaponIndex];
this.weaponDisplay.setTexture(weapon.texture);
this.weaponNameText.setText(`当前武器: ${weapon.name}`);
this.weaponStatsText.setText(`伤害: ${weapon.damage}\n范围: ${weapon.range}`);
}
/**
* 设置输入控制
*/
setupInput() {
// 切换武器按钮
this.createButton(this.sys.game.config.width - 200, 100, '上一件武器', () => {
this.previousWeapon();
});
this.createButton(this.sys.game.config.width - 200, 150, '下一件武器', () => {
this.nextWeapon();
});
// 装备武器按钮
this.createButton(this.sys.game.config.width - 200, 200, '装备武器', () => {
this.equipWeapon();
});
// 攻击按钮
this.createButton(this.sys.game.config.width - 200, 250, '攻击', () => {
this.attack();
});
// 返回启动场景按钮
this.createButton(this.sys.game.config.width - 200, 300, '返回启动场景', () => {
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);
});
}
/**
* 切换到上一件武器
*/
previousWeapon() {
this.currentWeaponIndex = (this.currentWeaponIndex - 1 + this.weapons.length) % this.weapons.length;
this.updateWeaponDisplay();
console.log('切换到上一件武器:', this.weapons[this.currentWeaponIndex].name);
}
/**
* 切换到下一件武器
*/
nextWeapon() {
this.currentWeaponIndex = (this.currentWeaponIndex + 1) % this.weapons.length;
this.updateWeaponDisplay();
console.log('切换到下一件武器:', this.weapons[this.currentWeaponIndex].name);
}
/**
* 装备武器
*/
equipWeapon() {
const weapon = this.weapons[this.currentWeaponIndex];
this.player.equippedWeapon = weapon;
console.log('装备武器:', weapon.name);
// 显示装备成功提示
const equipText = this.add.text(this.sys.game.config.width / 2, 100, `已装备: ${weapon.name}`, {
fontSize: '16px',
fill: '#00ff00',
fontFamily: 'Arial',
fontWeight: 'bold'
});
equipText.setOrigin(0.5, 0.5);
equipText.setScrollFactor(0, 0);
equipText.setDepth(12);
// 2秒后移除提示
this.time.delayedCall(2000, () => {
equipText.destroy();
});
}
/**
* 攻击
*/
attack() {
if (!this.player.equippedWeapon) {
console.log('请先装备武器');
return;
}
console.log('使用武器攻击:', this.player.equippedWeapon.name);
// 播放攻击动画
this.player.anims.stop();
this.player.setTexture('player0-1');
// 1秒后恢复
this.time.delayedCall(500, () => {
this.player.setTexture('player0-0');
});
// 显示攻击效果
const attackEffect = this.add.circle(this.player.x + 30, this.player.y, 20, 0xff6600, 0.5);
this.tweens.add({
targets: attackEffect,
scale: { from: 1, to: 2 },
alpha: { from: 0.5, to: 0 },
duration: 500,
onComplete: () => {
attackEffect.destroy();
}
});
}
/**
* 显示提示信息
*/
showInstructions() {
// 标题
this.add.text(20, 20, '武器测试场景', {
fontSize: '20px',
fill: '#ffffff',
fontFamily: 'Arial',
fontWeight: 'bold'
}).setScrollFactor(0, 0).setDepth(11);
// 操作提示
const instructions = [
'WASD或方向键移动角色',
'角色移动时播放动画',
'使用按钮切换和装备武器',
'点击攻击按钮测试武器效果',
'按空格键返回启动场景'
];
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.add.text(20, 200, `武器总数: ${this.weapons.length}`, {
fontSize: '14px',
fill: '#00ff00',
fontFamily: 'Arial'
}).setScrollFactor(0, 0).setDepth(11);
}
update() {
// 更新输入系统
this.inputSystem.update();
// 更新所有单位
this.unitGroup.getChildren().forEach(unit => {
if (unit.update) {
unit.update();
}
unit.updateMovement();
// 处理角色动画
this.updateCharacterAnimation(unit);
});
// 按空格键返回启动场景
if (this.input.keyboard.checkDown(this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE), 100)) {
this.scene.start('BootScene');
}
}
/**
* 更新角色动画
* @param {Object} unit - 单位对象
*/
updateCharacterAnimation(unit) {
// 检查单位是否在移动
const isMoving = Math.abs(unit.body.velocity.x) > 10 || Math.abs(unit.body.velocity.y) > 10;
if (isMoving) {
// 处理角色朝向
if (unit.body.velocity.x < -10) {
unit.setFlipX(true); // 向左翻转
} else if (unit.body.velocity.x > 10) {
unit.setFlipX(false); // 向右不翻转
}
// 播放移动动画
if (!unit.anims.isPlaying || !unit.anims.currentAnim.key.includes('move')) {
unit.play('player0-move');
}
} else {
// 静止状态,显示图片0
unit.anims.stop();
unit.setTexture('player0-0');
}
}
}