Skip to content

Commit d6e1546

Browse files
committed
修复帧时间不准确问题
预新增fsm (简单状态机)
1 parent f84cc19 commit d6e1546

8 files changed

Lines changed: 160 additions & 33 deletions

File tree

.vscode/launch.json

Lines changed: 0 additions & 17 deletions
This file was deleted.

README.md

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
# egret-BehaviourTree
22
基于Egret开发的AI(BehaviourTree、UtilityAI)系统,一套已经非常完整的系统。大家可以自行看源代码来学习,项目当中也有好几个示例,如果对项目你有更多的解决方案可发起 `pull request`请求或者有任何疑问可发起`issue`
33

4-
## 加入我们
5-
如果需要任何帮助,或者有任何疑问可以加入以下信息:
6-
7-
QQ群: 711978707
8-
94
## 目录结构
105

116
- src `源目录`

manifest.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,16 @@
3939
"bin-debug/behaviourTree/decorators/Inverter.js",
4040
"bin-debug/behaviourTree/decorators/Repeater.js",
4141
"bin-debug/behaviourTree/decorators/UntilFail.js",
42+
"bin-debug/behaviourTree/decorators/UntilSuccess.js",
4243
"bin-debug/LoadingUI.js",
43-
"bin-debug/core/ArrayExt.js",
4444
"bin-debug/core/Assert.js",
4545
"bin-debug/core/Mathf.js",
4646
"bin-debug/core/Random.js",
4747
"bin-debug/core/Timer.js",
4848
"bin-debug/core/TimerItem.js",
49+
"bin-debug/fsm/SimpleStateMachine.js",
50+
"bin-debug/fsm/State.js",
51+
"bin-debug/fsm/StateMachine.js",
4952
"bin-debug/test/LowPriorityAbortTree.js",
5053
"bin-debug/test/SelfAbortTree.js",
5154
"bin-debug/test/State.js",
@@ -69,6 +72,6 @@
6972
"bin-debug/utilityAI/considerations/appraisals/IAppraisal.js",
7073
"bin-debug/utilityAI/reasoners/FirstScoreReasoner.js",
7174
"bin-debug/utilityAI/reasoners/HighestScoreReasoner.js",
72-
"bin-debug/behaviourTree/decorators/UntilSuccess.js"
75+
"bin-debug/core/ArrayExt.js"
7376
]
7477
}

src/Main.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,9 @@ class Main extends eui.UILayer {
114114
}
115115

116116
private onEnterFrame(){
117-
// this.selfAbortTreeSample.update();
117+
this.selfAbortTreeSample.update();
118118
// this.lowerPriorityAbortTreeSample.update();
119-
this.utilitySample.update();
119+
// this.utilitySample.update();
120120
}
121121

122122
/**

src/behaviourTree/BehaviorTree.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ class BehaviorTree<T>{
77
* 更新周期为0.2将使树每秒更新5次。
88
*/
99
public updatePeriod: number;
10+
public lastUpdate: number = 0;
11+
public stepUpdateCounter: number = 0;
1012
/**
1113
* 上下文应包含运行树所需的所有数据
1214
*/
@@ -22,21 +24,21 @@ class BehaviorTree<T>{
2224
this._root = rootNode;
2325

2426
this.updatePeriod = this._elapsedTime = updatePeriod;
27+
this.lastUpdate = egret.getTimer();
2528
}
2629

2730
public tick(){
31+
let now = egret.getTimer();
32+
let dt = now - this.lastUpdate;
33+
this.lastUpdate = now;
34+
this.stepUpdateCounter += dt;
2835
/**
2936
* 小于或等于0的updatePeriod将标记每一帧
3037
*/
3138
if (this.updatePeriod > 0){
32-
// TODO: 这里是需要优化的地方.
33-
this._elapsedTime -= Number((1000 / Timer.deltaTime).toFixed(5)) / 10000;
34-
// this._elapsedTime -= Timer.deltaTime;
35-
if (this._elapsedTime <= 0){
36-
while (this._elapsedTime <= 0)
37-
this._elapsedTime += this.updatePeriod;
38-
39+
if (this.stepUpdateCounter >= this.updatePeriod){
3940
this._root.tick(this._context);
41+
this.stepUpdateCounter -= this.updatePeriod;
4042
}
4143
}
4244
else{

src/fsm/SimpleStateMachine.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
module fsm{
2+
/**
3+
* 具有字符串约束的简单状态机。 使用此功能时必须遵循一些规则:
4+
* - 在调用update之前必须设置initialState(使用构造函数)
5+
* - 如果在子类中实现更新,则必须调用super.update()
6+
*
7+
* @abstract
8+
* @class SimpleStateMachine
9+
* @template TEnum
10+
*/
11+
export abstract class SimpleStateMachine{
12+
protected elapsedTimeInState: number = 0;
13+
protected previousState: string;
14+
private _stateCache: {[key: string]: StateMethodCache};
15+
private _stateMethods: StateMethodCache;
16+
17+
private _currentState: string;
18+
public get currentState(): string{
19+
return this._currentState;
20+
}
21+
22+
public set currentState(value: string){
23+
if (this._currentState == value)
24+
return;
25+
26+
this.previousState = this._currentState;
27+
this._currentState = value;
28+
29+
if (this._stateMethods.exitState != null)
30+
this._stateMethods.exitState();
31+
32+
this.elapsedTimeInState = 0;
33+
this._stateMethods = this._stateCache[this._currentState];
34+
35+
if (this._stateMethods.enterState != null)
36+
this._stateMethods.enterState();
37+
}
38+
39+
protected set initialState(value: string){
40+
this._currentState = value;
41+
this._stateMethods = this._stateCache[this._currentState];
42+
43+
if (this._stateMethods.enterState != null)
44+
this._stateMethods.enterState();
45+
}
46+
47+
constructor(){
48+
this._stateCache = {};
49+
}
50+
51+
public update(){
52+
if (this._stateMethods.tick != null)
53+
this._stateMethods.tick();
54+
}
55+
56+
public setEnterMethod(stateName: string, enterState: Function, tickState: Function, exitState: Function){
57+
let state = new StateMethodCache();
58+
state.enterState = enterState;
59+
state.tick = tickState;
60+
state.exitState = exitState;
61+
62+
this._stateCache[stateName] = state;
63+
}
64+
}
65+
66+
export class StateMethodCache{
67+
public enterState: Function;
68+
public tick: Function;
69+
public exitState: Function;
70+
}
71+
}

src/fsm/State.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
module fsm{
2+
export abstract class State<T>{
3+
protected _machine: StateMachine<T>;
4+
protected _context: T;
5+
6+
public setMachineAndContext(machine: StateMachine<T>, context: T){
7+
this._machine = machine;
8+
this._context = context;
9+
this.onInitialized();
10+
}
11+
12+
/**
13+
* 在设置machine和context之后直接调用,允许状态执行任何所需的设置
14+
*
15+
* @memberof State
16+
*/
17+
public onInitialized(){}
18+
19+
/**
20+
* 当状态变为活动状态时调用
21+
*
22+
* @memberof State
23+
*/
24+
public begin(){}
25+
26+
/**
27+
* 在更新之前调用,允许状态最后一次机会改变状态
28+
*
29+
* @memberof State
30+
*/
31+
public reason(){}
32+
33+
/**
34+
* 每个帧调用此状态为活动状态
35+
*
36+
* @abstract
37+
* @param {number} deltaTime
38+
* @memberof State
39+
*/
40+
public abstract update(deltaTime: number);
41+
42+
/**
43+
* 此状态不再是活动状态时调用
44+
*
45+
* @memberof State
46+
*/
47+
public end(){}
48+
}
49+
}

src/fsm/StateMachine.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
module fsm{
2+
export class StateMachine<T>{
3+
public onStateChanged: Function;
4+
5+
6+
public get currentState(): State<T>{
7+
return this._currentState;
8+
}
9+
public previousState: State<T>;
10+
public elapsedTimeInState: number = 0;
11+
protected _currentState: State<T>;
12+
protected _context: T;
13+
private _states: {[key: number]: State<T>} = {};
14+
15+
constructor(context: T, initialState: State<T>){
16+
this._context = context;
17+
this.addState(initialState);
18+
}
19+
20+
public addState(state: State<T>){
21+
state.setMachineAndContext(this, this._context);
22+
}
23+
}
24+
}

0 commit comments

Comments
 (0)