Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Excalibur Scene Transitions & Loaders #2790

Merged
merged 71 commits into from
Jan 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
bd073e2
WIP: async init
eonarheim Sep 30, 2023
9e587a6
WIP magic to allow both sync/async to coexist
eonarheim Sep 30, 2023
2193dc6
Refactor, no need for magic
eonarheim Oct 2, 2023
3a4a554
feat: Scene transitions work
eonarheim Oct 5, 2023
31d6b5c
Loaders mostly work in transitions
eonarheim Oct 7, 2023
e8551ff
Loader is working
eonarheim Oct 7, 2023
64c7b6d
Boot loader works
eonarheim Oct 7, 2023
1fdd909
Refactor sample
eonarheim Oct 7, 2023
093a590
fix lint
eonarheim Oct 7, 2023
c0ca71d
Refactor scene management to router
eonarheim Oct 8, 2023
b1db177
Update docs
eonarheim Oct 8, 2023
a1be79c
Refactor + only load once
eonarheim Oct 8, 2023
823accf
Fix lint
eonarheim Oct 8, 2023
ba41887
Refactor Loader to avoid breaking change
eonarheim Oct 8, 2023
4af740e
Refactor names
eonarheim Oct 10, 2023
a4a76a2
fix router options parsing
eonarheim Oct 10, 2023
fc4cc2f
Refactor and add start scene transition
eonarheim Oct 11, 2023
526f00c
Refactoring and documentation
eonarheim Oct 11, 2023
3270499
Wire up preload event
eonarheim Oct 11, 2023
05fc71a
Fix lint
eonarheim Oct 11, 2023
f8115be
Switch up direction terminology to match use to prevent confusion
eonarheim Oct 11, 2023
3ae836c
Quick refactor
eonarheim Oct 11, 2023
33b9e07
Remove async init of entities/actors
eonarheim Oct 12, 2023
0ce743d
fix import
eonarheim Oct 12, 2023
d920acb
Add back mark resource complete
eonarheim Oct 12, 2023
a4813f9
fix a bunch of tests
eonarheim Oct 12, 2023
d8b1f7a
Remove collider
eonarheim Oct 12, 2023
9b8cf97
Merge branch 'main' of https://github.com/excaliburjs/Excalibur into …
eonarheim Jan 7, 2024
77c2a49
fix sandbox
eonarheim Jan 7, 2024
ce93f4a
Refactor per feedback and rename to "Director"
eonarheim Jan 7, 2024
a1f6ef1
fix lint
eonarheim Jan 7, 2024
a44e8d3
remove dunder
eonarheim Jan 7, 2024
719f304
Small refactor
eonarheim Jan 7, 2024
afe27a0
Lots of tweaks per feedback
eonarheim Jan 8, 2024
3342182
Rename to DefaultLoader
eonarheim Jan 8, 2024
dad9454
Allow loader constructors
eonarheim Jan 8, 2024
a2a98fd
Fix lint
eonarheim Jan 8, 2024
bf4c18c
Few tweaks
eonarheim Jan 8, 2024
2f446c6
Add missing signatures
eonarheim Jan 8, 2024
9e424be
fix base loader references
eonarheim Jan 8, 2024
4f04f9f
Clean up start!
eonarheim Jan 8, 2024
715556b
Clean up interface for extending loaders
eonarheim Jan 8, 2024
9f5d038
Refactor imports to be specific
eonarheim Jan 8, 2024
4684156
cleanup todo
eonarheim Jan 8, 2024
7e1db95
refactor imports
eonarheim Jan 8, 2024
82feb19
Refactor imports
eonarheim Jan 8, 2024
42e7ee6
Refactor imports
eonarheim Jan 8, 2024
8e2bc9e
Wallaby issue
eonarheim Jan 8, 2024
b03a273
fix test build
eonarheim Jan 8, 2024
dc99f92
fix tests
eonarheim Jan 9, 2024
5576646
Fix signature on default loader
eonarheim Jan 9, 2024
df67307
Apply wallaby fixes
eonarheim Jan 9, 2024
8530955
Fix remaining barrel imports
eonarheim Jan 9, 2024
3a0b4f4
Fix test utils with new loader
eonarheim Jan 9, 2024
458de35
cb corrector working
eonarheim Jan 9, 2024
7ea6148
remove todo
eonarheim Jan 9, 2024
c77f2bb
init director before calling custom init
eonarheim Jan 9, 2024
3fbe9de
Entity init is still sync for now
eonarheim Jan 9, 2024
42b412d
Theoretically fix tests
eonarheim Jan 9, 2024
fe583ef
fix lint
eonarheim Jan 9, 2024
8a3edbc
Merge branch 'main' of https://github.com/excaliburjs/Excalibur into …
eonarheim Jan 9, 2024
70af4a0
Add transition spec
eonarheim Jan 10, 2024
be609ce
Merge branch 'main' of https://github.com/excaliburjs/Excalibur into …
eonarheim Jan 11, 2024
7240642
Start loader spec
eonarheim Jan 11, 2024
df40960
Merge branch 'main' of https://github.com/excaliburjs/Excalibur into …
eonarheim Jan 11, 2024
df1b4a8
Add default loader tests
eonarheim Jan 11, 2024
82d38f5
add tests for built in transitions
eonarheim Jan 11, 2024
5a3b85d
Merge branch 'main' of https://github.com/excaliburjs/Excalibur into …
eonarheim Jan 14, 2024
83d3c04
Add test
eonarheim Jan 14, 2024
03635d8
Add changelog
eonarheim Jan 14, 2024
157af03
fix tests
eonarheim Jan 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"no-unused-labels": "error",
"no-var": "error",
"prefer-const": "error",
"require-await": "warn",
"radix": "error",
"max-len": ["error", { "code": 140 }],
"semi": ["error", "always"],
Expand Down
44 changes: 43 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,49 @@ This project adheres to [Semantic Versioning](http://semver.org/).

### Added

-
- Scene Transition & Loader API, this gives you the ability to have first class support for individual scene resource loading and scene transitions.
* Add or remove scenes by constructor
* Add loaders by constructor
* New `ex.DefaultLoader` type that allows for easier custom loader creation
* New `ex.Transition` type for building custom transitions
* New scene lifecycle to allow scene specific resource loading
* `onTransition(direction: "in" | "out") {...}`
* `onPreLoad(loader: DefaultLoader) {...}`
* New async goto API that allows overriding loaders/transitions between scenes
* Scenes now can have `async onInitialize` and `async onActivate`!
* New scenes director API that allows upfront definition of scenes/transitions/loaders

* Example:
Defining scenes upfront
```typescript
const game = new ex.Engine({
scenes: {
scene1: {
scene: scene1,
transitions: {
out: new ex.FadeInOut({duration: 1000, direction: 'out', color: ex.Color.Black}),
in: new ex.FadeInOut({duration: 1000, direction: 'in'})
}
},
scene2: {
scene: scene2,
loader: ex.DefaultLoader, // Constructor only option!
transitions: {
out: new ex.FadeInOut({duration: 1000, direction: 'out'}),
in: new ex.FadeInOut({duration: 1000, direction: 'in', color: ex.Color.Black })
}
},
scene3: ex.Scene // Constructor only option!
}
})

// Specify the boot loader & first scene transition from loader
game.start('scene1',
{
inTransition: new ex.FadeInOut({duration: 500, direction: 'in', color: ex.Color.ExcaliburBlue})
loader: boot,
});
```

### Fixed

Expand Down
46 changes: 0 additions & 46 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@
"typedoc": "0.25.3",
"typescript": "5.3.3",
"url-loader": "4.1.1",
"wallaby-webpack": "3.9.16",
"webpack": "5.89.0",
"webpack-cli": "5.1.4"
},
Expand Down
22 changes: 11 additions & 11 deletions sandbox/src/game.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,16 +128,16 @@ cards2.draw(game.graphicsContext, 0, 0);

jump.volume = 0.3;

var loader = new ex.Loader();
loader.addResource(heartImageSource);
loader.addResource(heartTex);
loader.addResource(imageRun);
loader.addResource(imageJump);
loader.addResource(imageBlocks);
loader.addResource(spriteFontImage);
loader.addResource(cards);
loader.addResource(cloud);
loader.addResource(jump);
var boot = new ex.Loader();
boot.addResource(heartImageSource);
boot.addResource(heartTex);
boot.addResource(imageRun);
boot.addResource(imageJump);
boot.addResource(imageBlocks);
boot.addResource(spriteFontImage);
boot.addResource(cards);
boot.addResource(cloud);
boot.addResource(jump);

// Set background color
game.backgroundColor = new ex.Color(114, 213, 224);
Expand Down Expand Up @@ -942,6 +942,6 @@ game.currentScene.camera.strategy.lockToActorAxis(player, ex.Axis.X);
game.currentScene.camera.y = 200;

// Run the mainloop
game.start(loader).then(() => {
game.start(boot).then(() => {
logger.info('All Resources have finished loading');
});
18 changes: 12 additions & 6 deletions sandbox/tests/gotoscene/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
class Scene1 extends ex.Scene {
onInitialize(_engine: ex.Engine): void {
async onInitialize(_engine: ex.Engine) {
console.log('before async');
await ex.Util.delay(1000);
console.log('after async');
const actor = new ex.Actor({
x: _engine.halfDrawWidth,
y: _engine.halfDrawHeight,
Expand All @@ -11,30 +14,33 @@ class Scene1 extends ex.Scene {

_engine.input.pointers.primary.on(
"down",
(event: ex.PointerEvent): void => {
_engine.goToScene("scene2");
async (event: ex.PointerEvent) => {
await _engine.goToScene("scene2");
}
);
}

onActivate(): void {
async onActivate() {
console.log('Scene 1 Activate')
}
}


class Scene2 extends ex.Scene {
onInitialize(_engine: ex.Engine): void {
async onInitialize(_engine: ex.Engine) {
await ex.Util.delay(1000);
// _engine.start();
const actor = new ex.Actor({
pos: ex.Vector.Zero,
width: 1000,
height: 1000,
color: ex.Color.Cyan,
});
actor.angularVelocity = 1;
_engine.add(actor);
}
onActivate(): void {
async onActivate() {
await ex.Util.delay(1000);
console.log('Scene 2 Activate')
}
}
Expand Down
12 changes: 12 additions & 0 deletions sandbox/tests/router/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Router Test</title>
</head>
<body>
<script src="../../lib/excalibur.js"></script>
<script src="index.js"></script>
</body>
</html>
139 changes: 139 additions & 0 deletions sandbox/tests/router/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/// <reference path='../../lib/excalibur.d.ts' />
var scene1 = new ex.Scene();
scene1.add(new ex.Label({
pos: ex.vec(100, 100),
color: ex.Color.Green,
text: 'Scene 1',
z: 99
}))
var scene2 = new ex.Scene();
scene2.add(new ex.Label({
pos: ex.vec(100, 100),
color: ex.Color.Violet,
text: 'Scene 2',
z: 99
}))

class MyCustomScene extends ex.Scene {
onTransition(direction: "in" | "out") {
return new ex.FadeInOut({
direction,
color: ex.Color.Violet,
duration: 2000
});
}
onPreLoad(loader: ex.DefaultLoader): void {
const image1 = new ex.ImageSource('./spritefont.png?=1');
const image2 = new ex.ImageSource('./spritefont.png?=2');
const image3 = new ex.ImageSource('./spritefont.png?=3');
const image4 = new ex.ImageSource('./spritefont.png?=4');
const sword = new ex.ImageSource('https://cdn.rawgit.com/excaliburjs/Excalibur/7dd48128/assets/sword.png');
loader.addResource(image1);
loader.addResource(image2);
loader.addResource(image3);
loader.addResource(image4);
loader.addResource(sword);
}
onActivate(context: ex.SceneActivationContext<unknown>): void {
console.log(context.data);
}
}

let scenes = {
scene1: {
scene: scene1,
transitions: {
in: new ex.FadeInOut({duration: 500, direction: 'in'})
}
},
scene2: {
scene: scene2,
loader: ex.DefaultLoader,
transitions: {
out: new ex.FadeInOut({duration: 500, direction: 'out'}),
in: new ex.CrossFade({duration: 2500, direction: 'in', blockInput: true})
}
},
scene3: MyCustomScene
} satisfies ex.SceneMap<any>;

var gameWithTransitions = new ex.Engine({
width: 800,
height: 600,
displayMode: ex.DisplayMode.FitScreenAndFill,
scenes
});


var actor = new ex.Actor({
width: 100,
height: 100,
pos: ex.vec(100, 100),
color: ex.Color.Red
})
actor.addChild(new ex.Actor({
width: 100,
height: 100,
pos: ex.vec(100, 100),
color: ex.Color.Black
}));
scene1.add(actor);


scene2.onPreLoad = (loader) => {
const image1 = new ex.ImageSource('./spritefont.png?=1');
const image2 = new ex.ImageSource('./spritefont.png?=2');
const image3 = new ex.ImageSource('./spritefont.png?=3');
const image4 = new ex.ImageSource('./spritefont.png?=4');
const sword = new ex.ImageSource('https://cdn.rawgit.com/excaliburjs/Excalibur/7dd48128/assets/sword.png');
loader.addResource(image1);
loader.addResource(image2);
loader.addResource(image3);
loader.addResource(image4);
loader.addResource(sword);
}
scene1.onActivate = () => {
setTimeout(() => {
gameWithTransitions.goto('scene2');
// router.goto('scene2', {
// outTransition: new ex.FadeOut({duration: 1000, direction: 'in'}),
// inTransition: new ex.FadeOut({duration: 1000, direction: 'out'})
// });
}, 1000);
}
scene2.add(new ex.Actor({
width: 100,
height: 100,
pos: ex.vec(400, 400),
color: ex.Color.Blue
}));

var boot = new ex.Loader();
const image1 = new ex.ImageSource('./spritefont.png?=1');
const image2 = new ex.ImageSource('./spritefont.png?=2');
const image3 = new ex.ImageSource('./spritefont.png?=3');
const image4 = new ex.ImageSource('./spritefont.png?=4');
const sword = new ex.ImageSource('https://cdn.rawgit.com/excaliburjs/Excalibur/7dd48128/assets/sword.png');
boot.addResource(image1);
boot.addResource(image2);
boot.addResource(image3);
boot.addResource(image4);
boot.addResource(sword);
gameWithTransitions.input.keyboard.on('press', evt => {
gameWithTransitions.goto('scene3', {
sceneActivationData: { data: 1 }
});
});
gameWithTransitions.input.pointers.primary.on('down', () => {
gameWithTransitions.goto('scene1');
});
var startTransition = new ex.FadeInOut({duration: 500, direction: 'in', color: ex.Color.ExcaliburBlue});
// startTransition.events.on('kill', () => {
// console.log(game.currentScene.entities);
// console.log('killed!');
// })
gameWithTransitions.start('scene1',
{
inTransition: startTransition,
loader: boot
});
Binary file added sandbox/tests/router/spritefont.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion sandbox/tests/scene/lifecycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class MyGame2 extends ex.Engine {
console.log("scene deactivate");
}
}
onInitialize() {
async onInitialize() {
console.log("engine init");
}
}
Expand Down
Loading