You can nest states by setting another state machine within a state, containing its own states. Swapping from a state to its nested state can be done with this._setState('MyStateName.MyNestedStateName')
. The advantage of nesting is that it allows us to stay in one state
, while having the benefits of a sub-state
.
Below an example of nesting states. When pressing right you will $enter()
the blue state, when pressing right again you will $enter()
its nested state, the green cube.
class BasicUsageExample extends lng.Application {
static _template() {
return {
ExamplanationText:{ x: 50, y: 28, w: 590, text:{ text: '', fontSize: 22, wordWrap: true, wordWrapWidth: 590, lineHeight: 30 }},
MyBlueCube:{
x: 100, y: 200, w: 100, h: 100, rect: true, color: 0xFF0034DD
},
MyGreenCube:{
x: 400, y: 200, w: 100, h: 100, rect: true, color: 0xFF24DD00
}
}
}
_init(){
this._blueCubeAnimation = this.tag('MyBlueCube').animation({
duration: 3, repeat: -1, stopMethod: 'immediate',
actions: [{ p: 'rotation', v: { 0: { v: 0, sm: 0 }, 1: { v: -Math.PI * 2, sm: 0 } } }]
});
this._greenCubeAnimation = this.tag('MyGreenCube').animation({
duration: 3, repeat: -1, stopMethod: 'immediate',
actions: [{ p: 'rotation', v: { 0: { v: 0, sm: 0 }, 1: { v: Math.PI * 2, sm: 0 } } }]
});
this._setState('MyIdleState');
}
static _states(){
return [
class MyBlueState extends this{
$enter(){
this.tag('ExamplanationText').patch({ text:{ text: 'I am in my Blue state now! \n (Press Left or Right)'}});
this._blueCubeAnimation.play();
}
$exit(){
this._blueCubeAnimation.pause();
}
_handleLeft(){
this._setState('MyIdleState');
}
_handleRight(){
this._setState('MyBlueState.MyNestedGreenState');
}
static _states(){
return [
class MyNestedGreenState extends MyBlueState{
$enter(){
this.tag('ExamplanationText').patch({ text:{ text: 'I am in Blue\'s nested Green state now! \n (Press Left)'}});
this._greenCubeAnimation.play();
}
$exit(){
this.tag('ExamplanationText').patch({ text:{ text: 'I am back in my Blue state now, \nbut did not $enter(), because I was there all along! \n (Press Left or Right)'}});
this._greenCubeAnimation.pause();
}
_handleLeft(){
this._setState('MyBlueState');
}
}
]
}
},
class MyIdleState extends this{
$enter(){
this.tag('ExamplanationText').patch({ text:{ text: 'I am in my Idle state now! \n (Press Right)'}});
this._blueCubeAnimation.pause();
this._greenCubeAnimation.pause();
}
_handleRight(){
this._setState('MyBlueState');
}
}
];
}
}
const app = new BasicUsageExample({stage: {w: window.innerWidth, h: window.innerHeight, useImageWorker: false}});
document.body.appendChild(app.stage.getCanvas());