constgameOver: Scene = (like, scenes) => ({ titleCard:like.gfx.newImage(path); spawnTime: like.timer.getTime(); draw() { // draw 'game over' over the lower scene like.gfx.draw(this.titleCard); scenes.get(-2)?.draw(); } update() { // back to title screen after 3 seconds // (assuming title screen is using callback pattern) if (like.timer.getTime() > spawnTime + 3) { while(scenes.pop()); } } })
For configurable scenes, it is reccommended to use a function
that returns a Scene.
Just like the like object, scenes have handleEvent on them.
So, you could layer them like this, for example:
// Composing scenes lets us know about the children. // This allows communication, for example: typeUISceneInstance = SceneInstance & { // Sending events to child scene buttonClicked(name: string): void; // Getting info from child scene getStatus(): string; }; typeUIScene = SceneEx<UISceneInstance>;
constuiScene = (game: UIScene): Scene=> (like, scenes) => { constchildScene = scenes.instantiate(game); return { handleEvent(event) { // Block mouse events in order to create a top bar. // Otherwise, propogate them. constmouseY = like.mouse.getPosition()[1]; if (!event.type.startsWith('mouse') || mouseY > 100) { // Use likeDispatch so that nested handleEvent can fire, // if relevant. likeDispatch(childScene, event); } // Then, call my own callbacks. // Using likeDispatch here will result in an infinite loop. callOwnHandlers(this, event); }, mousepressed(pos) { if (buttonClicked(pos)) { childScene.buttonClicked('statusbar') } }, draw() { drawStatus(like, childScene.getStatus()); } }; }
The main advance of composing scenes versus the stack-overlay
technique is that the parent scene knows about its child.
Because there's a known interface, the two scenes
can communicate.
This makes it perfect for reusable UI,
level editors, debug viewers, and more.
Scene stacking
Higher on the stack is the upper scene, and lower on it
is the lower. We use the term overlay to refer to an
upper scene that passes draw events to a lower one.
You might assume that the purpose of a scene stack is
visual: first push the BG, then the FG, etc.
Actually, composing scenes (above) is a
better pattern for that, since it's both explicit
and the parent can have a known interface on its child.
Here, the upper scene only knows that the
lower scene is a scene.
That's the tradeoff. Overlay scenes are good for things
like pause screens or gamepad overlays. Anything where
the upper doesn't care what the lower is, and where
the upper scene should be easily addable/removable.
Using like.getScene(-2), the overlay scene can see
the lower scene and choose how to propagate events.
The only technical difference between overlay and
opaque is whether or not the scene we've pushed
on top of stays loaded.
Creating your own scenes
Scenes are a factory function that receives
LikeandSceneManagerand returns a scene instance with event handlers.Examples
Minimal usage:
For configurable scenes, it is reccommended to use a function that returns a Scene.
Of course, a class pattern is also possible.
Or a configurable class:
Converting from Callbacks
When converting from global callbacks to a scene:
Composing scenes
A
parentscene contains achildscene, calls it, and lifecycle via SceneManager.instantiate and SceneManager.deinstance.Just like the
likeobject, scenes have handleEvent on them. So, you could layer them like this, for example:The main advance of composing scenes versus the stack-overlay technique is that the parent scene knows about its child. Because there's a known interface, the two scenes can communicate.
This makes it perfect for reusable UI, level editors, debug viewers, and more.
Scene stacking
Higher on the stack is the
upperscene, and lower on it is thelower. We use the termoverlayto refer to an upper scene that passesdrawevents to a lower one.You might assume that the purpose of a scene stack is visual: first push the BG, then the FG, etc.
Actually, composing scenes (above) is a better pattern for that, since it's both explicit and the parent can have a known interface on its child. Here, the upper scene only knows that the lower scene is a scene.
That's the tradeoff. Overlay scenes are good for things like pause screens or gamepad overlays. Anything where the upper doesn't care what the lower is, and where the upper scene should be easily addable/removable.
Using
like.getScene(-2), the overlay scene can see the lower scene and choose how to propagate events.The only technical difference between overlay and opaque is whether or not the scene we've pushed on top of stays loaded.