Skip to content

Commit

Permalink
Merge pull request #4 from kodikos/multiple-scenes
Browse files Browse the repository at this point in the history
Enable multiple scenes
  • Loading branch information
kodikos committed May 25, 2019
2 parents bd2f5e2 + d3f1df5 commit 00dfe50
Show file tree
Hide file tree
Showing 8 changed files with 238 additions and 4 deletions.
10 changes: 10 additions & 0 deletions README.md
Expand Up @@ -85,3 +85,13 @@ I have gone for minimizing the interaction by passing an event to the [Quiz](htt
Something extra that I have to do is disable event bubbling. This is because I listen for clicks anywhere in the scene, and the buttons on the quiz are in the scene. I add the `e.stopPropagation()` to prevent the event being fired for the scene as well.

The quiz mechanism can potentially be used for introducing alternative story narratives and a choice of sub-scene. This is where the flexibility of the `decideNextSubScene()` comes in handy to manage this.

## Scenes

A good way to organize the game is to have each of the scenes on a different URL. This can help with things like navigating through to different parts of a game.

This introduces the `react-router-dom` package, a.k.a React Router v4. If you look in the [main App class](https://github.com/kodikos/houndville/blob/master/src/App.js), you see the `BrowserRouter`, `Switch`, and `Route` classes being used. This simple set up allows us to define a component to sit on a URL (web address), the _exact_ keyword and `Switch` class help make it a specific URL. This is set out a lot like a web server that you might set up with Express, page routing is typically something that's only done by a web server.

We have to do something a little different from normal HTML to move around between scenes.. wait, what? A React app is not necessarily rendering a page, it's a javascript application that can be rendered on the server or in your browser, you may not even be aware which way it's doing it! When it's running from a browser, it doesn't need to go back to the server because it already has everything it needs. It uses URLs as a consistent way to refer to different parts of the app no matter which mode it's running in. Because of this it needs to abstract the way you use routing.

The two extra components provided for changing the URL are `Link` and `Redirect`. A `Link` component sets up a special anchor tag so that you can click on a link and it takes you elsewhere in the app. `Redirect` works a little differently, when it is rendered it will cause the app to go elsewhere in the app. It is normally within a conditional so that it appears when you need it to. You can see `Redirect` used in this app in the last subscene of the [valley scene](https://github.com/kodikos/houndville/blob/master/src/ValleyScene/index.js). The ChangeScene component defined in [StoryScene](https://github.com/kodikos/houndville/blob/master/src/shared/StoryScene.js) sets up a special type of SubScene so that when it switches from the `under-the-bridge` subscene to `next-scene` it renders the `Redirect` component and causes the switch to the entrance scene.
161 changes: 161 additions & 0 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Expand Up @@ -7,6 +7,7 @@
"gh-pages": "^2.0.1",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-router-dom": "^5.0.0",
"react-scripts": "3.0.1",
"styled-components": "^4.2.0"
},
Expand Down
9 changes: 8 additions & 1 deletion src/App.js
@@ -1,8 +1,10 @@
import React from 'react';
import { BrowserRouter, Switch, Route } from 'react-router-dom';
import styled from 'styled-components';

import HoundHeader from './shared/HoundHeader';
import ValleyScene from './ValleyScene';
import EntranceScene from './EntranceScene';

const Screen = styled.div`
display: flex;
Expand All @@ -14,7 +16,12 @@ function App() {
return (
<Screen>
<HoundHeader />
<ValleyScene />
<BrowserRouter>
<Switch>
<Route exact path="/" component={ValleyScene} />
<Route exact path="/entrance" component={EntranceScene} />
</Switch>
</BrowserRouter>
</Screen>
);
}
Expand Down
Binary file added src/EntranceScene/background.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 39 additions & 0 deletions src/EntranceScene/index.js
@@ -0,0 +1,39 @@
import React, { Component } from 'react';
import styled from 'styled-components';

import StoryScene from '../shared/StoryScene';
import { TextBox as BaseTextBox, Backdrop } from '../shared/Common';
import { Quiz, Question, Choice } from '../shared/Quiz';
import BackgroundImage from './background.png';

const Background = styled(Backdrop)`
background-image: url(${BackgroundImage});
`;

const TextBox = styled(BaseTextBox)`
top: auto;
bottom: 2vh;
`;

export default class EntranceScene extends StoryScene {

decideNextSubScene(currentScene) {
switch(currentScene) {
default: return 'init';
}
}

render() {
const { SubScene, SceneWrapper } = this;
return (
<SceneWrapper>
<Background />
<SubScene name="init">
<TextBox>
I can't believe it, no one is guarding the entrance
</TextBox>
</SubScene>
</SceneWrapper>
);
}
}
6 changes: 4 additions & 2 deletions src/ValleyScene/index.js
Expand Up @@ -22,7 +22,7 @@ export default class ValleyScene extends StoryScene {
case 'quiz-moat' :
case 'quiz-portcullis' :
return 'quiz-gate-name';
case 'over-the-bridge' : return 'over-the-bridge';
case 'over-the-bridge' : return 'next-scene';
default: return 'init';
}
}
Expand All @@ -32,7 +32,7 @@ export default class ValleyScene extends StoryScene {
}

render() {
const { SubScene, SceneWrapper } = this;
const { SubScene, SceneWrapper, ChangeScene } = this;
return (
<SceneWrapper>
<Background />
Expand Down Expand Up @@ -92,6 +92,8 @@ export default class ValleyScene extends StoryScene {
You go over the bridge and stand before the drawbridge...
</TextBox>
</SubScene>

<ChangeScene name="next-scene" to="entrance" />
</SceneWrapper>
);
}
Expand Down

0 comments on commit 00dfe50

Please sign in to comment.