This commit is contained in:
sli97
2022-12-01 22:26:41 +08:00
parent 1a27f478d0
commit bdead4a6d1
256 changed files with 7972 additions and 387 deletions

View File

@@ -0,0 +1,23 @@
import { _decorator, Component } from 'cc';
import { EntityStateEnum } from '../Enum';
import StateMachine from './StateMachine';
const { ccclass, property } = _decorator;
@ccclass('EntityManager')
export abstract class EntityManager extends Component {
fsm: StateMachine
private _state: EntityStateEnum
get state() {
return this._state
}
set state(newState) {
this._state = newState
this.fsm.setParams(newState, true)
}
abstract init(...args: any[]): void
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "2e4eed53-d1b9-42ef-97aa-8d0a8da927f7",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,13 @@
export default class Singleton {
private static _instance: any = null
static GetInstance<T>(): T {
if (this._instance === null) {
this._instance = new this()
}
return this._instance
}
protected constructor() {
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "0ee5b84a-8971-410f-a39d-2cf96597dd45",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,48 @@
import { animation, AnimationClip, Sprite, SpriteFrame } from 'cc'
import DataManager from '../Global/DataManager'
import { ResourceManager } from '../Global/ResourceManager'
import { sortSpriteFrame } from '../Utils'
import StateMachine from './StateMachine'
/***
* unit:milisecond
*/
export const ANIMATION_SPEED = 1 / 10
/***
* 状态每组动画的承载容器持有SpriteAnimation组件执行播放
*/
export default class State {
private animationClip: AnimationClip
constructor(
private fsm: StateMachine,
private path: string,
private wrapMode: AnimationClip.WrapMode = AnimationClip.WrapMode.Normal,
private force: boolean = false,
) {
//生成动画轨道属性
const track = new animation.ObjectTrack()
track.path = new animation.TrackPath().toComponent(Sprite).toProperty('spriteFrame')
const spriteFrames = DataManager.Instance.textureMap.get(this.path)
const frames: Array<[number, SpriteFrame]> = sortSpriteFrame(spriteFrames).map((item, index) => [
index * ANIMATION_SPEED,
item,
])
track.channel.curve.assignSorted(frames)
//动画添加轨道
this.animationClip = new AnimationClip()
this.animationClip.name = this.path
this.animationClip.duration = frames.length * ANIMATION_SPEED
this.animationClip.addTrack(track)
this.animationClip.wrapMode = this.wrapMode
}
run() {
if (this.fsm.animationComponent.defaultClip?.name === this.animationClip.name && !this.force) {
return
}
this.fsm.animationComponent.defaultClip = this.animationClip
this.fsm.animationComponent.play()
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "226c1921-1459-4764-82e6-b1a11c5a73c2",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,91 @@
import { _decorator, Animation, Component } from 'cc'
import { EntityTypeEnum, FsmParamTypeEnum } from '../Enum'
const { ccclass } = _decorator
import State from './State'
import SubStateMachine from './SubStateMachine'
type ParamsValueType = boolean | number
export interface IParamsValue {
type: FsmParamTypeEnum
value: ParamsValueType
}
export const getInitParamsTrigger = () => {
return {
type: FsmParamTypeEnum.Trigger,
value: false,
}
}
export const getInitParamsNumber = () => {
return {
type: FsmParamTypeEnum.Number,
value: 0,
}
}
/***
* 流动图
* 1.entity的state或者direction改变触发setter
* 2.setter里触发fsm的setParams方法
* 3.setParams执行run方法run方法由子类重写
* 4.run方法会更改currentState然后触发currentState的setter
* 5-1.如果currentState是子状态机继续执行他的run方法run方法又会设置子状态机的currentState触发子状态run方法
* 5-2.如果是子状态run方法就是播放动画
*/
/***
* 有限状态机基类
*/
@ccclass('StateMachine')
export default abstract class StateMachine extends Component {
private _currentState: State | SubStateMachine = null
params: Map<string, IParamsValue> = new Map()
stateMachines: Map<string, SubStateMachine | State> = new Map()
animationComponent: Animation
type: EntityTypeEnum
getParams(paramName: string) {
if (this.params.has(paramName)) {
return this.params.get(paramName).value
}
}
setParams(paramName: string, value: ParamsValueType) {
if (this.params.has(paramName)) {
this.params.get(paramName).value = value
this.run()
this.resetTrigger()
}
}
get currentState() {
return this._currentState
}
set currentState(newState) {
if (!newState) {
return
}
this._currentState = newState
this._currentState.run()
}
/***
* 清空所有trigger
*/
resetTrigger() {
for (const [, value] of this.params) {
if (value.type === FsmParamTypeEnum.Trigger) {
value.value = false
}
}
}
/***
* 由子类重写方法目标是根据当前状态和参数修改currentState
*/
abstract init(...args: any[]): void
abstract run(): void
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "66538d45-0fcf-4ed2-8e47-a0a688ddaf3c",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,30 @@
import State from './State'
import StateMachine from './StateMachine'
/***
* 子有限状态机基类
* 用处例如有个idle的state但是有多个方向为了让主状态机更整洁可以把同类型的但具体不同的state都封装在子状态机中
*/
export default abstract class SubStateMachine {
private _currentState: State = null
stateMachines: Map<string, State> = new Map()
constructor(public fsm: StateMachine) {}
get currentState() {
return this._currentState
}
set currentState(newState) {
if (!newState) {
return
}
this._currentState = newState
this._currentState.run()
}
/***
* 具体类实现
*/
abstract run(): void
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "7f9fac71-9820-41b2-8b4d-2dc4185414ef",
"files": [],
"subMetas": {},
"userData": {}
}