Skip to content
This repository has been archived by the owner on Mar 17, 2021. It is now read-only.

Commit

Permalink
CGPROD 1537 multi level demo (#281)
Browse files Browse the repository at this point in the history
* Automatically pass transientData through screens
* Add missing achievement files to second theme
* Add additional test for default transientData object
* Missing elements from second theme
  • Loading branch information
FostUK authored Jul 29, 2019
1 parent ac97323 commit e6b3b00
Show file tree
Hide file tree
Showing 18 changed files with 150 additions and 95 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

| Version | Description |
|---------|-------------|
| 2.0.2 | |
| | transientData automatically passed between screens. |
| | Fix Chrome race condition with removed DOM elements triggering blur event with accessible elements.. |
| | Add level id to stats if present. |
| | Adds validation tool for achievement config files. |
Expand Down
9 changes: 9 additions & 0 deletions UPGRADE-NOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Upgrade Notes

## Genie 2.0.2
Screens now automatically pass their transientData to the next screen.
Previously data needed to be passed as a parameter to the navigation routes e.g:

```javascript
this.navigation.next(data)
```
Instead now the data should be mutated in place by changing `this.transientData`

## Genie 2.0.1
`"genie": "git+ssh://[email protected]/bbc/childrens-games-genie.git#v2.0.1"`

Expand Down
90 changes: 42 additions & 48 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"jest": "^24.8.0",
"jest-canvas-mock": "^2.0.0",
"jest-webpack": "^0.5.1",
"jsdoc": "^3.6.2",
"jsdoc": "^3.6.3",
"jsdom": "^13.2.0",
"local-web-server": "^2.6.0",
"prettier": "1.17.0",
Expand Down
13 changes: 6 additions & 7 deletions src/components/select.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,15 @@ export class Select extends Screen {

create() {
this.scene.addToBackground(this.game.add.image(0, 0, this.getAsset("background")));
this.scene.addToBackground(this.game.add.image(0, -150, this.getAsset("title")));
createTestHarnessDisplay(this.game, this.context, this.scene);

const theme = this.context.config.theme[this.game.state.current];
this.currentIndex = 1;
this.choiceSprites = this.createChoiceSprites(theme.choices);
this.scene.addToBackground(this.game.add.image(0, -170, this.getAsset("title")));

// TODO the following line should be added back once the overlap issue is resolved NT:04:02:19
const showAchievements = false; //!!this.context.config.theme.game.achievements;
const defaultButtons = ["home", "audio", "pauseNoReplay", "previous", "next", "continue"];
const buttons = showAchievements ? defaultButtons.concat("achievements") : defaultButtons;
this.scene.addLayout(["home", "audio", "pauseNoReplay", "previous", "next", "continue"]);

this.scene.addLayout(buttons);
this.accessibleElements = accessibleCarouselElements.create(
this.visibleLayer,
this.choiceSprites,
Expand Down Expand Up @@ -88,7 +84,10 @@ export class Select extends Screen {
const metaData = { metadata: `ELE=[${theme.choices[this.currentIndex - 1].asset}]` };
const screenType = this.game.state.current.split("-")[0];
gmi.sendStatsEvent(screenType, "select", metaData);
this.navigation.next({ characterSelected: this.currentIndex });

const choice = this.context.config.theme[this.key].choices[this.currentIndex];
this.transientData[this.key] = { index: this.currentIndex, choice };
this.navigation.next();
}

addSignalSubscriptions() {
Expand Down
3 changes: 2 additions & 1 deletion src/core/layout/gel-defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import * as pause from "../../components/overlays/pause.js";
import { settings, settingsChannel } from "../../core/settings.js";
import { gmi } from "../../core/gmi/gmi.js";
import * as signal from "../signal-bus.js";
import fp from "../../../lib/lodash/fp/fp.js";

const pushLevelId = (game, params) => {
const levelId = game.state.states[game.state.current].transientData.levelId;
const levelId = fp.get("transientData.level-select.choice.title", game.state.states[game.state.current]);
return levelId ? [...params, { source: levelId }] : params;
};

Expand Down
4 changes: 4 additions & 0 deletions src/core/screen.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import * as signal from "../core/signal-bus.js";
import * as GameSound from "../core/game-sound.js";
import * as a11y from "../core/accessibility/accessibility-layer.js";
import * as VisibleLayer from "../core/visible-layer.js";
import fp from "../../lib/lodash/fp/fp.js";

/**
* The `Screen` class extends `Phaser.State`, providing the `Context` to objects that extend from it.
Expand Down Expand Up @@ -41,6 +42,9 @@ export class Screen extends Phaser.State {
a11y.clearAccessibleButtons();
a11y.clearElementsFromDom();
this.overlaySetup();

const routes = navigation[this.game.state.current].routes;
this.navigation = fp.mapValues(value => () => value(this.transientData || {}), routes);
}

overlaySetup() {
Expand Down
35 changes: 18 additions & 17 deletions test/components/select.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,25 +32,25 @@ describe("Select Screen", () => {
image: jest.fn().mockImplementation((x, y, imageName) => imageName),
button: jest.fn(),
sprite: jest.fn().mockImplementation((x, y, assetName) => {
if (assetName === "characterSelect.character1") {
if (assetName === "test-select.character1") {
return characterSprites[0];
}
if (assetName === "characterSelect.character2") {
if (assetName === "test-select.character2") {
return characterSprites[1];
}
if (assetName === "characterSelect.character3") {
if (assetName === "test-select.character3") {
return characterSprites[2];
}
}),
},
state: { current: "characterSelect" },
state: { current: "test-select" },
canvas: { parentElement: {} },
};

mockContext = {
config: {
theme: {
characterSelect: {
"test-select": {
choices: [{ asset: "character1" }, { asset: "character2" }, { asset: "character3" }],
},
game: {},
Expand All @@ -70,6 +70,8 @@ describe("Select Screen", () => {
};

selectScreen.game = mockGame;
selectScreen.transientData = {};
selectScreen.key = "test-select";
selectScreen.context = mockContext;
selectScreen.navigation = { next: jest.fn() };
});
Expand All @@ -80,13 +82,13 @@ describe("Select Screen", () => {
beforeEach(() => selectScreen.create());

test("adds a background image", () => {
expect(mockGame.add.image).toHaveBeenCalledWith(0, 0, "characterSelect.background");
expect(selectScreen.scene.addToBackground).toHaveBeenCalledWith("characterSelect.background");
expect(mockGame.add.image).toHaveBeenCalledWith(0, 0, "test-select.background");
expect(selectScreen.scene.addToBackground).toHaveBeenCalledWith("test-select.background");
});

test("adds a title image", () => {
expect(mockGame.add.image).toHaveBeenCalledWith(0, -150, "characterSelect.title");
expect(selectScreen.scene.addToBackground).toHaveBeenCalledWith("characterSelect.title");
expect(mockGame.add.image).toHaveBeenCalledWith(0, -170, "test-select.title");
expect(selectScreen.scene.addToBackground).toHaveBeenCalledWith("test-select.title");
});

test("adds GEL buttons to layout", () => {
Expand All @@ -104,9 +106,9 @@ describe("Select Screen", () => {

test("creates sprites for each choice", () => {
expect(mockGame.add.sprite).toHaveBeenCalledTimes(3);
expect(mockGame.add.sprite.mock.calls[0]).toEqual([0, 0, "characterSelect.character1"]);
expect(mockGame.add.sprite.mock.calls[1]).toEqual([0, 0, "characterSelect.character2"]);
expect(mockGame.add.sprite.mock.calls[2]).toEqual([0, 0, "characterSelect.character3"]);
expect(mockGame.add.sprite.mock.calls[0]).toEqual([0, 0, "test-select.character1"]);
expect(mockGame.add.sprite.mock.calls[1]).toEqual([0, 0, "test-select.character2"]);
expect(mockGame.add.sprite.mock.calls[2]).toEqual([0, 0, "test-select.character3"]);
});

test("adds each sprite to the background", () => {
Expand All @@ -121,10 +123,10 @@ describe("Select Screen", () => {

test("creates an accessible carousel for the choices", () => {
expect(accessibleCarouselElements.create).toHaveBeenCalledWith(
"characterSelect",
"test-select",
selectScreen.choiceSprites,
mockGame.canvas.parentElement,
mockContext.config.theme.characterSelect.choices,
mockContext.config.theme["test-select"].choices,
);
});
});
Expand All @@ -150,15 +152,14 @@ describe("Select Screen", () => {
});

test("moves to the next game screen when the continue button is pressed", () => {
selectScreen.currentIndex = 1;
signal.bus.subscribe.mock.calls[2][0].callback();
expect(selectScreen.navigation.next).toHaveBeenCalledWith({ characterSelected: 1 });
expect(selectScreen.navigation.next).toHaveBeenCalled();
});

test("fires a score stat to the GMI with when you select an item ", () => {
selectScreen.currentIndex = 1;
signal.bus.subscribe.mock.calls[2][0].callback();
expect(mockGmi.sendStatsEvent).toHaveBeenCalledWith("characterSelect", "select", {
expect(mockGmi.sendStatsEvent).toHaveBeenCalledWith("test", "select", {
metadata: "ELE=[character1]",
});
});
Expand Down
Loading

0 comments on commit e6b3b00

Please sign in to comment.