Skip to content

Commit

Permalink
feat(sound): add sounds for games
Browse files Browse the repository at this point in the history
  • Loading branch information
Gerd Müller committed Jun 30, 2020
1 parent 09a9a2d commit 3466583
Show file tree
Hide file tree
Showing 14 changed files with 136 additions and 39 deletions.
28 changes: 17 additions & 11 deletions apps/demol/src/app/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -297,8 +297,15 @@
"type": "image",
"option": "third",
"value": "2-1781_Seite135"
},
{
}
]
},
{
"grouped": true,
"row": false,
"character": "Karl",
"background": "02_1455_(147)",
"content": [{
"type": "text",
"value": "Karl ist für diese Gruppe noch zu jung, aber es gibt auch eine sozialistische Vereinigung für Kinder: die Kinderfreunde, die auch eine Ortsgruppe in seiner Nähe haben. Karl will sich das einmal anschauen, denn bei den Kinderfreunden ist viel los. Es gibt Spielenachmittage, Zeltlager und auch Themennachmittage."
},
Expand Down Expand Up @@ -369,7 +376,6 @@
"grouped": true,
"row": false,
"character": "Karl",
"background": "02_1455_(147)",
"content": [{
"type": "text",
"value": "Karl hat einen Stadtplan mit dem eingezeichneten Weg zur Ortsgruppe bekommen. Nur leider ist dieser in mehrere Teile zerrissen."
Expand Down Expand Up @@ -1002,7 +1008,7 @@
"row": false,
"character": "Anna",
"background": "02_2424_(1)",
"info": "Tipp: Manche Dinge werden in der Kinderrepublik dringend benötigt, andere gab es Ende der 1920er Jahre noch gar nicht. Wenn du fertig gepackt hast, kommst du zum nächsten Kapitel.",
"info": "Tipp: Manche Dinge werden in der Kinderrepublik dringend benötigt, andere gab es Ende der 1920er Jahre noch gar nicht.",
"content": [{
"type": "text",
"option": "third",
Expand All @@ -1011,7 +1017,7 @@
{
"type": "text",
"option": "third",
"value": "Um einen Gegenstand einzupacken, ziehe ihn direkt auf den Rucksack."
"value": "Um einen Gegenstand einzupacken, ziehe ihn direkt auf den Rucksack.Wenn du fertig gepackt hast, kommst du zum nächsten Kapitel."
},
{
"type": "suitcase",
Expand Down Expand Up @@ -1089,14 +1095,14 @@
"row": false,
"character": "Karl",
"background": "02_2424_(1)",
"info": "Tipp: Manche Dinge werden in der Kinderrepublik dringend benötigt, andere gab es Ende der 1920er Jahre noch gar nicht. Wenn du fertig gepackt hast, kommst du zum nächsten Kapitel.",
"info": "Tipp: Manche Dinge werden in der Kinderrepublik dringend benötigt, andere gab es Ende der 1920er Jahre noch gar nicht.",
"content": [{
"type": "text",
"value": "Hilf Karl beim Packen seines Rucksacks. Welche Dinge wird er in der Kinderrepublik benötigen?"
},
{
"type": "text",
"value": "Um einen Gegenstand einzupacken, ziehe ihn direkt auf den Rucksack."
"value": "Um einen Gegenstand einzupacken, ziehe ihn direkt auf den Rucksack. Wenn du fertig gepackt hast, kommst du zum nächsten Kapitel."
},
{
"type": "suitcase",
Expand Down Expand Up @@ -1169,7 +1175,7 @@
"row": false,
"character": "Gerda",
"background": "02_2424_(1)",
"info": "Tipp: Manche Dinge werden in der Kinderrepublik dringend benötigt, andere gab es Ende der 1920er Jahre noch gar nicht. Wenn du fertig gepackt hast, kommst du zum nächsten Kapitel.",
"info": "Tipp: Manche Dinge werden in der Kinderrepublik dringend benötigt, andere gab es Ende der 1920er Jahre noch gar nicht.",
"content": [{
"type": "text",
"option": "third",
Expand All @@ -1178,7 +1184,7 @@
{
"type": "text",
"option": "third",
"value": "Um einen Gegenstand einzupacken, ziehe ihn direkt auf den Rucksack."
"value": "Um einen Gegenstand einzupacken, ziehe ihn direkt auf den Rucksack. Wenn du fertig gepackt hast, kommst du zum nächsten Kapitel."
},
{
"type": "suitcase",
Expand Down Expand Up @@ -2496,7 +2502,7 @@
},
{
"type": "daily",
"value": "daily"
"value": "Tagesplan"
}
]
},
Expand Down Expand Up @@ -2913,7 +2919,7 @@
{
"type": "redirect",
"value": "endkapitel",
"option": "full",
"option": "primary",
"title": "Du hast genug gespielt und hast langsam Heimweh...."
}
]
Expand Down
2 changes: 2 additions & 0 deletions apps/demol/src/app/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import './app.scss';

import app from './app.json';

(window as any).soundManager.setup({debugMode: false});

export const App = () => {
const [character, setCharacter] = usePersistedState('character', 'default');

Expand Down
Binary file added apps/demol/src/assets/sounds/game_lost.mp3
Binary file not shown.
Binary file added apps/demol/src/assets/sounds/game_won.mp3
Binary file not shown.
32 changes: 25 additions & 7 deletions libs/home/src/lib/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,22 @@ const home:ChapterProps = {
"grouped": true,
"row": false,
"content": [{
"type": "redirect",
"value": "chapter/daheim",
"option": "big",
"title": "Beginne hier das Abenteuer!"
},
{
"type": "image",
"value": "02_1455_(114)",
"option": "third"
},
{
}
]
},
{
"grouped": true,
"row": false,
"content": [{
"type": "text",
"value": "Die Reise zur Kinderrepublik wäre für Anna, Karl und Gerda ohne Anne Mühlich und Gerd Müller nicht möglich gewesen. Im Rahmen des Kulturhackathons 'Coding da Vinci Westfalen-Ruhrgebiet' 2019 entwickelten die beiden diese Scrollytelling-Website, die auf Fotos und Material des Archivs der Arbeiterjugendbewegung basiert. 2020 haben sie im Rahmen eines Stipendiums des Coding da Vinci die Website für die Zwecke des Archivs ergänzt und ausgebaut."
}]
Expand Down Expand Up @@ -53,12 +64,19 @@ const home:ChapterProps = {
"content": [{
"type": "text",
"value": "Die Website richtet sich an all jene, die sich spielerisch mit dem Thema „Kinderrepublik“ und partizipativer Jugendarbeit in der ersten Hälfte des 20. Jahrhunderts beschäftigen wollen und erfahren möchten, wie solche Zeltlager als Form früher und praktischer Demokratiebildung funktioniert haben. In Zeiten wie jetzt, wo mehr und mehr Menschen sich von den demokratischen Institutionen abwenden, lohnt es sich, einen Blick zurückzuwerfen und zu schauen, wie Demokratiebildung insbesondere für bildungsfernere Schichten in der Vergangenheit funktioniert hat und inwiefern wir dafür etwas für unsere heutige Zeit lernen können."
}]
},
{
"grouped": true,
"row": true,
"content": [{
"type": "text",
"option": "link",
"value": "Diese Website entstand im Rahmen des <a href='https://codingdavinci.de/' target='_blank' rel='noopener noreferrer'>Coding da Vinci Stipendiums</a> zwischen April und Juni 2020. Die Fotografien und Bildkärtchen wurden vom <a href='https://arbeiterjugend.de/' target='_blank' rel='noopener noreferrer'>Archiv der Arbeiterjugendbewegung</a> unter einer CC BY-SA 3.0 DE Lizenz zur Verfügung gestellt. Genutzt wurden zudem Sounds aus der Sammlung des <a href='http://www.soundsofchanges.eu/' target='_blank' rel='noopener noreferrer'>Sounds of Changes</a> Projektes (CC BY 4.0 Lizenz), der <a href='https://www.hoerspielbox.de/' target='_blank' rel='noopener noreferrer'>Hörspielbox</a> sowie dem <a href='http://bbcsfx.acropolis.org.uk/' target='_blank' rel='noopener noreferrer'>BBC Sound Effects</a> Archiv. Genutzt ildmaterial von <a href='https://commons.wikimedia.org' target='_blank' rel='noopener noreferrer'>Wikimedia Commons</a>."
},
{
"type": "redirect",
"value": "chapter/daheim",
"option": "big",
"title": "Beginne hier das Abenteuer!"
{
"type": "text",
"value":"Der Quellcode läuft unter einer MIT license. Die eigens für das Projekt erstellten Mediendateien sind unter einer CC BY-SA 3.0 Lizenz veröffentlicht."
}]
}
]
Expand Down
14 changes: 7 additions & 7 deletions libs/ui/src/lib/chapter/chapter.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { Fragment, useContext} from 'react';
import { InView } from 'react-intersection-observer'
import Sound from 'react-sound';

import Header from '../header/header';
import Group from '../group/group';
Expand All @@ -13,12 +14,6 @@ export const Chapter = (props: ChapterProps) => {

const [character, setCharacter] = useContext(AppContext);

const audio = new Audio(`./assets/sounds/${props.link}.mp3`);
audio.loop = true;
const startAudio = (inView) => {
inView ? audio.play() : audio.pause();
};

const renderChapterGroups = () => {
return props.groups.map((group, index) =>
<Fragment key={index}>
Expand All @@ -35,7 +30,12 @@ export const Chapter = (props: ChapterProps) => {
}

return (
<InView as="div" onChange={(inView, entry) => audio && startAudio(inView)}>
<InView as="div">
<Sound
url={`./assets/sounds/${props.link}.mp3`}
loop={true}
playStatus={Sound.status.PLAYING}
/>
<div className='parallax'>
<Header {...props}/>
{props.groups && renderChapterGroups()}
Expand Down
7 changes: 5 additions & 2 deletions libs/ui/src/lib/memory/memory.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useState, useEffect } from "react";
import { Redirect } from 'react-router-dom';
import Sound from 'react-sound';
import { makeStyles } from '@material-ui/core/styles';

import Image from "../image/image";
Expand All @@ -18,6 +19,7 @@ export const Memory = (props: MemoryProps) => {
const [visibleItems, setVisibleItems] = useState([]);
const [finishedItems, setFinishedItems] = useState([]);
const [winner, setWinner] = useState(false);
const [winningSound, setWinningSound] = useState(false);

const checkItems = (firstIndex, secondIndex) => {
if (
Expand Down Expand Up @@ -49,8 +51,8 @@ export const Memory = (props: MemoryProps) => {
useEffect(
() => {
if (finishedItems.length > 0 && finishedItems.length === list.length) {
//TODO: Sound for winning the game
setTimeout(() => setWinner(true), 1500);
setWinningSound(true);
setTimeout(() => setWinner(true), 2500);
}
},
[finishedItems, list]
Expand All @@ -65,6 +67,7 @@ export const Memory = (props: MemoryProps) => {
finishedItems={finishedItems}
checkItems={checkItems}
/>
{winningSound && <Sound url={`./assets/sounds/game_won.mp3`} playStatus={Sound.status.PLAYING} />}
{winner && <Redirect exact to="endkapitel" />}
</div>
);
Expand Down
18 changes: 13 additions & 5 deletions libs/ui/src/lib/puzzle/puzzle.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { Component } from "react";
import { Redirect } from 'react-router-dom';
import Sound from 'react-sound';

import './puzzle.scss';

Expand All @@ -9,7 +10,9 @@ class Puzzle extends Component {
shuffled: [],
solved: [],
winner: false,
chance: false
winningSound: false,
chance: false,
playStatus: Sound.status.PLAYING
};

componentDidMount() {
Expand Down Expand Up @@ -58,10 +61,9 @@ class Puzzle extends Component {
const finished = this.state.solved.find((piece, index) => piece.order !== index);

if (finished === undefined) {
//TODO: Sound for winning the game
setTimeout(() => this.setState({ winner: true }), 1500);
this.setState({ winningSound: true })
setTimeout(() => this.setState({ winner: true }), 2500);
} else {
//TODO: Sound for losing the game
this.setState({ chance: true })
}
}
Expand All @@ -76,9 +78,15 @@ class Puzzle extends Component {
<ol className='puzzle__solved-board' style={{ backgroundImage: `url(./assets/daheim_puzzle.webp)` }}>
{this.state.solved.map((piece, i) => this.renderPieceContainer(piece, i, "solved"))}
</ol>
{this.state.winningSound && <Sound url={`./assets/sounds/game_won.mp3`} playStatus={Sound.status.PLAYING} />}
{this.state.winner && <Redirect exact to="ortsgruppe" />}
</div>
{this.state.chance && <p>Der Weg scheint noch nicht ganz richtig. Versuch es noch einmal!</p>}
{this.state.chance &&
<>
<p>Der Weg scheint noch nicht ganz richtig. Versuch es noch einmal!</p>
<Sound url={`./assets/sounds/game_lost.mp3`} playStatus={this.state.playStatus}
onFinishedPlaying={() => this.setState({ playStatus: Sound.status.STOPPED })} />
</>}
</>
);
}
Expand Down
19 changes: 16 additions & 3 deletions libs/ui/src/lib/suitcase/suitcase.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React, { useState, useContext } from "react";
import React, { useState, useContext, useEffect } from "react";
import { Redirect } from 'react-router-dom';
import { DragDropContainer, DropTarget } from "react-drag-drop-container";
import Shake from 'react-reveal/Shake';
import Jump from 'react-reveal/Jump';
import Sound from 'react-sound';

import Image from '../image/image';
import {AppContext } from '../chapter/context';
Expand All @@ -16,21 +17,30 @@ export const Suitcase = (props) => {
const [drag, setDrag] = useState("");
const [bagCounter, setBagCounter] = useState(0);
const [showResult, setShowResult] = useState(false);
const [winningSound, setWinningSound] = useState(false);
const [lostSound, setLostSound] = useState(false);
const [playStatus, setPlayStatus] = useState(Sound.status.PLAYING);
const [falseCounter, setFalseCounter] = useState(0);

useEffect(
() => {
setPlayStatus(Sound.status.PLAYING);
}, [falseCounter]
);

const dropped = (e) => {
e.containerElem.style.visibility = "hidden";
setBagCounter(bagCounter +1);
setDrag(`${character} packt ${e.dragData.label} ein.`);
if (bagCounter === 4) {
//TODO: Sound for winning the game
setWinningSound(true);
setTimeout(() => setShowResult(true), 1500);
}
};

const droppedFalseItem = (e) => {
setDrag(`${character} braucht ${e.dragData.label} wohl eher nicht.`);
//TODO: Sound for losing the game
setLostSound(true);
setFalseCounter(falseCounter+1);
};

Expand Down Expand Up @@ -60,6 +70,9 @@ export const Suitcase = (props) => {
</Jump>
</DropTarget>
</DropTarget>
{winningSound && <Sound url={`./assets/sounds/game_won.mp3`} playStatus={Sound.status.PLAYING} />}
{lostSound && <Sound url={`./assets/sounds/game_lost.mp3`} playStatus={playStatus}
onFinishedPlaying={() => setPlayStatus(Sound.status.STOPPED)} />}
{showResult && <Redirect exact to="reise" />}
</div>
);
Expand Down
29 changes: 29 additions & 0 deletions libs/ui/src/lib/text/text.scss
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,35 @@ p {
animation: move-text 0.1s forwards;
}

.link a {
margin: auto;
border-bottom: 3px solid var(--color-link);
transition: all 0.25s linear;
position: relative;
cursor: pointer;
color: var(--color-title);

&:before {
content: "";
display: block;
width: 100%;
height: 3px;
background-color: var(--color-link-highlighted);
position: absolute;
left: 0;
bottom: -3px;
transform-origin: left;
transform: scale(0);
transition: 0.5s linear;
}
&:hover {
color: var(--color-link);
}
&:hover:before {
transform: scale(1);
}
}

@keyframes move-text {
0% {
opacity: 1;
Expand Down
2 changes: 1 addition & 1 deletion libs/ui/src/lib/text/text.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const Text = (props: TextProps) => {
return (
<div className={`box ${props.option}`}>
<Fade bottom duration={5000}>
<p>{props.value}</p>
{props.option === 'link' ? <p className="link" dangerouslySetInnerHTML={{__html: props.value}} /> : <p>{props.value}</p>}
</Fade>
</div>
);
Expand Down
Loading

0 comments on commit 3466583

Please sign in to comment.