mirror of
http://junepve.top:3000/chicrobot/CINC.git
synced 2026-10-30 01:51:29 +08:00
test(TS) 测试场景备份
This commit is contained in:
1 parent
4205af8413
commit
5e53dc3ef3
5 files changed
+1364
No files matched your search
@@ -42,6 +42,11 @@ import MenuScene from './scenes/MenuScene.js';
|
|||||||
import TmpScene from './scenes/TmpScene.js';
|
import TmpScene from './scenes/TmpScene.js';
|
||||||
// 导入测试对象场景
|
// 导入测试对象场景
|
||||||
import TestObjectsScene from './scenes/testScenes/TestObjectsScene.js';
|
import TestObjectsScene from './scenes/testScenes/TestObjectsScene.js';
|
||||||
|
// 导入角色类测试场景
|
||||||
|
import CharacterClassTestScene from './scenes/testScenes/CharacterClassTestScene.js';
|
||||||
|
// 导入武器测试场景
|
||||||
|
import WeaponTestScene from './scenes/testScenes/WeaponTestScene.js';
|
||||||
|
|
||||||
// 创建游戏的最终配置对象
|
// 创建游戏的最终配置对象
|
||||||
const config = {
|
const config = {
|
||||||
// 使用扩展运算符(...)将gameConfig中的所有配置项复制到当前对象中
|
// 使用扩展运算符(...)将gameConfig中的所有配置项复制到当前对象中
|
||||||
@@ -51,6 +56,8 @@ const config = {
|
|||||||
scene: [
|
scene: [
|
||||||
MenuScene,
|
MenuScene,
|
||||||
TmpScene,
|
TmpScene,
|
||||||
|
WeaponTestScene,
|
||||||
|
CharacterClassTestScene,
|
||||||
TestObjectsScene,
|
TestObjectsScene,
|
||||||
BootScene,
|
BootScene,
|
||||||
GameScene,
|
GameScene,
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,6 +17,8 @@ export default class BootScene extends Phaser.Scene {
|
|||||||
|
|
||||||
// 测试场景列表
|
// 测试场景列表
|
||||||
const testScenes = [
|
const testScenes = [
|
||||||
|
{ key: 'WeaponTestScene', name: '测试场景22:武器测试' },
|
||||||
|
{ key: 'CharacterClassTestScene', name: '测试场景21:角色类测试' },
|
||||||
{ key: 'MultiTouchTestScene', name: '测试场景20:多触摸测试' },
|
{ key: 'MultiTouchTestScene', name: '测试场景20:多触摸测试' },
|
||||||
{ key: 'TestObjectsScene', name: '测试场景19:测试对象场景' },
|
{ key: 'TestObjectsScene', name: '测试场景19:测试对象场景' },
|
||||||
{ key: 'TmpScene', name: '测试场景18:临时场景' },
|
{ 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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user