This commit is contained in:
walkpan
2025-02-01 00:14:25 +08:00
parent c5c01c6cf4
commit bffbb9077e
91 changed files with 2067 additions and 1327 deletions

View File

@@ -0,0 +1,9 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "c10720f1-7ee0-426a-aaa8-15344c003fb1",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,37 @@
import { ecs } from "../../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
/** 战斗组件 */
@ecs.register('Combat')
export class Combat extends ecs.Comp {
/** 攻击力 */
attackPower: number = 10;
/** 攻击范围(像素) */
attackRange: number = 100;
/** 攻击间隔(秒) */
attackInterval: number = 1;
/** 当前攻击计时 */
attackTimer: number = 0;
/** 攻击目标 */
target: ecs.Entity | null = null;
init(attack: number, range: number) {
this.attackPower = attack;
this.attackRange = range;
}
/** 攻击结束回调 */
onAttackEnd() {
// 重置攻击目标
this.target = null;
// 触发攻击结束事件
oops.message.dispatch('AttackEnd', this.ent);
}
reset() {
this.attackPower = 10;
this.attackRange = 100;
this.attackInterval = 1;
this.attackTimer = 0;
this.target = null;
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "4470e6fb-5c92-486b-851e-1842bc8f2ff5",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,6 @@
export enum HeroAnimState {
IDLE = "Idle",
WALKING = "Walking",
ATTACKING = "Attacking",
TAUNT = "Taunt"
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "426117c2-67a7-4c89-b6b1-4f1074448b29",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,40 @@
import { ecs } from "../../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { HeroConfig } from "../../config/HeroConfig";
@ecs.register('HeroModel')
export class HeroModel extends ecs.Comp {
/** 角色配置ID */
configId: number = 0;
/** 当前生命值 */
hp: number = 0;
/** 最大生命值 */
maxHp: number = 0;
/** 基础攻击力 */
attack: number = 0;
/** 防御力 */
defense: number = 0;
/** 暴击率 0-100 */
critRate: number = 5;
/** 闪避率 0-100 */
dodgeRate: number = 5;
init(config: HeroConfig) {
this.configId = config.id;
this.maxHp = config.hp;
this.hp = config.hp;
this.attack = config.attack;
this.defense = config.defense;
this.critRate = config.critRate || 5;
this.dodgeRate = config.dodgeRate || 5;
}
reset() {
this.configId = 0;
this.hp = 0;
this.maxHp = 0;
this.attack = 0;
this.defense = 0;
this.critRate = 5;
this.dodgeRate = 5;
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "1d8dd962-7f0e-4601-82d1-f371f816bd21",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,13 @@
import { HeroAnimState } from "./HeroAnimState";
import { HeroViewComp } from "./HeroView";
export class HeroStateMachine {
private _currentState: HeroAnimState = HeroAnimState.IDLE;
changeState(newState: HeroAnimState, view: HeroViewComp) {
if (this._currentState !== newState) {
view.playAnimation(newState);
this._currentState = newState;
}
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "8af7a4d9-a1d8-4fca-bb8f-4c0198e3f837",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,19 @@
import { HeroView } from "./HeroView";
import { HeroAnimState } from "./HeroState";
/** 英雄动画状态机 */
export class HeroStateMachine {
private _currentState: HeroAnimState = HeroAnimState.IDLE;
/**
* 切换状态
* @param newState 新状态
* @param view 视图组件
*/
changeState(newState: HeroAnimState, view: HeroView) {
if (this._currentState !== newState) {
view.playAnimation(newState);
this._currentState = newState;
}
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "940cfabd-66b2-44dc-aa05-8247bfafc907",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,52 @@
import { _decorator, Component, Node, Prefab, instantiate, Vec3, resources, sp } from "cc";
import { ecs } from "../../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { CCComp } from "../../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
import { SpineComp } from "./SpineComp";
const { ccclass, property } = _decorator;
/** 英雄视图组件 */
@ccclass('HeroViewComp')
@ecs.register('HeroView', false)
export class HeroViewComp extends CCComp {
private _node: Node = null!;
private _spineComp: SpineComp = null!;
/** 加载角色模型 */
async load(spinePath: string) {
// 加载Spine预制体
const prefab = await this.loadSpinePrefab(spinePath);
// 实例化节点
this._node = instantiate(prefab);
this.node.addChild(this._node);
// 添加Spine组件
const spine = this._node.getComponent(sp.Skeleton)!;
this._spineComp = this.ent.add(SpineComp).init(spine);
}
private loadSpinePrefab(path: string): Promise<Prefab> {
return new Promise((resolve, reject) => {
resources.load(path, Prefab, (err, prefab) => {
err ? reject(err) : resolve(prefab!);
});
});
}
/** 更新位置 */
setPosition(pos: Vec3) {
this.node.position = pos;
}
/** 播放动画 */
playAnimation(name: string) {
this._spineComp.play(name);
}
/** 重置组件 */
reset() {
this._node.destroy();
this.ent.remove(SpineComp);
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "fe44963c-f45c-42cf-9564-220332438687",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,19 @@
import { ecs } from "../../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { Vec3 } from "cc";
/** 移动组件 */
@ecs.register('Movement')
export class Movement extends ecs.Comp {
/** 移动速度(像素/秒) */
speed: number = 200;
/** 目标位置 */
target: Vec3 = new Vec3();
/** 当前移动方向 */
direction: Vec3 = new Vec3();
reset() {
this.speed = 200;
this.target.set();
this.direction.set();
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "05f87dbf-e598-448c-953a-30cc66ff24f8",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,41 @@
import { _decorator, Component, sp } from 'cc';
import { ecs } from "../../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { HeroAnimState } from "./HeroAnimState";
@ecs.register('SpineComp')
export class SpineComp extends ecs.Comp {
private _skeleton: sp.Skeleton = null!;
/** 设置动画过渡混合时间 */
setMix(from: string, to: string, duration: number) {
this._skeleton.setMix(from, to, duration);
}
/** 初始化Spine组件 */
init(node: sp.Skeleton): this {
this._skeleton = node;
// 根据实际动画配置过渡
this.setMix("Walking", "Attacking", 0.2);
this.setMix("Attacking", "Walking", 0.3);
this.setMix("Attacking", "Idle", 0.1);
return this;
}
/**
* 播放动画
* @param animationName 动画名称
* @param loop 是否循环
*/
play(animationName: string, loop: boolean = true) {
this._skeleton.setAnimation(0, animationName, loop);
}
/** 设置皮肤 */
setSkin(skinName: string) {
this._skeleton.setSkin(skinName);
}
reset() {
this._skeleton = null!;
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "0c91a304-611d-4cd1-9245-0410812a0a64",
"files": [],
"subMetas": {},
"userData": {}
}