mirror of
http://junepve.top:3000/chicrobot/CINC.git
synced 2026-10-29 21:21:29 +08:00
387 lines
9.0 KiB
JavaScript
387 lines
9.0 KiB
JavaScript
// 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;
|
|
}
|
|
}
|
|
}
|