-
Notifications
You must be signed in to change notification settings - Fork 322
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
Ninas Project Labyrinth #212
base: master
Are you sure you want to change the base?
Changes from all commits
a691807
3001f72
8525855
cf24983
09fbd3b
a7311fc
420612b
e6c9316
e2929b3
0a7c715
19657e3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,28 @@ | ||
# Project Labyrinth | ||
|
||
Replace this readme with your own information about your project. | ||
This week's project is all about tying together the skills you've learnt to build an app that retrieves a list of actions from the backend and presents them to the user as interactable items. | ||
|
||
Start by briefly describing the assignment in a sentence or two. Keep it short and to the point. | ||
**What you need to do** | ||
|
||
✓ Your page should be responsive. | ||
|
||
✓ Use redux to store the current state of the game. | ||
|
||
✓ Focus on making the UX of your app good. Handle the response delay. | ||
|
||
✓ Use thunks to wrap your API calls. | ||
|
||
## The problem | ||
|
||
Describe how you approached to problem, and what tools and techniques you used to solve it. How did you plan? What technologies did you use? If you had more time, what would be next? | ||
|
||
In this week's project, you'll be building a project which allows a user to navigate a maze, in the form of a text-based adventure, provided by a backend. | ||
|
||
The goal for this week is to use the API specified to build a frontend that gives the user control over what to do next. You'll focus on using thunks and redux to build the communication with the backend. Beyond that, you'll have a lot of freedom. | ||
|
||
This week's project comes in the form of a text-based adventure. Classic games like this usually present the user with a description of where they are and provide several alternatives about what they can do. | ||
|
||
## View it live | ||
|
||
Every project should be deployed somewhere. Be sure to include the link to the deployed project so that the viewer can click around and see what it's all about. | ||
https://labyrinth-game-redux.netlify.app/ | ||
|
||
Sound Effect by "https://pixabay.com/users/maxou-yt-30144327/?utm_source=link-attribution&utm_medium=referral&utm_campaign=music&utm_content=141426">MAXOU-YT</a> from "https://pixabay.com/sound-effects//?utm_source=link-attribution&utm_medium=referral&utm_campaign=music&utm_content=141426">Pixabay |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,28 @@ | ||
# Project Labyrinth | ||
|
||
Replace this readme with your own information about your project. | ||
This week's project is all about tying together the skills you've learnt to build an app that retrieves a list of actions from the backend and presents them to the user as interactable items. | ||
|
||
Start by briefly describing the assignment in a sentence or two. Keep it short and to the point. | ||
**What you need to do** | ||
|
||
✓ Your page should be responsive. | ||
|
||
✓ Use redux to store the current state of the game. | ||
|
||
✓ Focus on making the UX of your app good. Handle the response delay. | ||
|
||
✓ Use thunks to wrap your API calls. | ||
|
||
## The problem | ||
|
||
Describe how you approached to problem, and what tools and techniques you used to solve it. How did you plan? What technologies did you use? If you had more time, what would be next? | ||
|
||
In this week's project, you'll be building a project which allows a user to navigate a maze, in the form of a text-based adventure, provided by a backend. | ||
|
||
The goal for this week is to use the API specified to build a frontend that gives the user control over what to do next. You'll focus on using thunks and redux to build the communication with the backend. Beyond that, you'll have a lot of freedom. | ||
|
||
This week's project comes in the form of a text-based adventure. Classic games like this usually present the user with a description of where they are and provide several alternatives about what they can do. | ||
|
||
## View it live | ||
|
||
Every project should be deployed somewhere. Be sure to include the link to the deployed project so that the viewer can click around and see what it's all about. | ||
https://labyrinth-game-redux.netlify.app/ | ||
|
||
Sound Effect by "https://pixabay.com/users/maxou-yt-30144327/?utm_source=link-attribution&utm_medium=referral&utm_campaign=music&utm_content=141426">MAXOU-YT</a> from "https://pixabay.com/sound-effects//?utm_source=link-attribution&utm_medium=referral&utm_campaign=music&utm_content=141426">Pixabay |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,26 @@ | ||
import React from 'react' | ||
import { Provider } from 'react-redux'; | ||
import { combineReducers, configureStore } from '@reduxjs/toolkit'; | ||
import { labyrinth, game } from 'reducers/labyrinth'; | ||
import { Background } from 'components/BackGround'; | ||
import { StartPage } from 'components/StartPage'; | ||
|
||
const reducer = combineReducers({ | ||
labyrinth: labyrinth.reducer, | ||
game: game.reducer | ||
}); | ||
|
||
const store = configureStore({ reducer }); | ||
|
||
export const App = () => { | ||
return ( | ||
<div> | ||
Find me in src/app.js! | ||
</div> | ||
<section className="main-container"> | ||
<Provider store={store}> | ||
<Background /> | ||
<div> | ||
<StartPage /> | ||
</div> | ||
</Provider> | ||
</section> | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import React from 'react'; | ||
import styled from 'styled-components'; | ||
import backgroundImage from 'images/background.jpg' | ||
|
||
const StyledBackground = styled.div` | ||
background-image: url(${backgroundImage}); // replace with your image path | ||
background-size: cover; | ||
background-position: center; | ||
background-repeat: no-repeat; | ||
width: 100%; | ||
height: 100%; | ||
position: fixed; | ||
top: 0; | ||
left: 0; | ||
z-index: -1; | ||
`; | ||
export const Background = () => { | ||
return <StyledBackground />; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import React, { useEffect } from 'react'; | ||
import { useDispatch } from 'react-redux'; | ||
import { nextMove } from 'reducers/labyrinth'; | ||
import styled from 'styled-components'; | ||
|
||
export const Direction = ({ actions = [] }) => { | ||
const dispatch = useDispatch(); | ||
|
||
useEffect(() => { | ||
const handleKeyDown = (event) => { | ||
switch (event.keyCode) { | ||
case 37: // left arrow | ||
dispatch(nextMove('west')); | ||
break; | ||
case 38: // up arrow | ||
dispatch(nextMove('north')); | ||
break; | ||
case 39: // right arrow | ||
dispatch(nextMove('east')); | ||
break; | ||
case 40: // down arrow | ||
dispatch(nextMove('south')); | ||
break; | ||
default: | ||
break; | ||
} | ||
}; | ||
|
||
document.addEventListener('keydown', handleKeyDown); | ||
|
||
return () => { | ||
document.removeEventListener('keydown', handleKeyDown); | ||
}; | ||
}, [dispatch]); | ||
|
||
const DirectionSection = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
` | ||
|
||
const MoveBtn = styled.button` | ||
font-family: 'Castoro Titling', cursive; | ||
background-color: #000; | ||
border-radius: 5px; | ||
padding: 5px 10px; | ||
font-size: 1rem; | ||
cursor: pointer; | ||
margin-bottom: 20px; | ||
color: lightgoldenrodyellow; | ||
&:hover { | ||
background-color: #999966; | ||
color: #000; | ||
} | ||
@media (min-width: 668px) { | ||
font-size: 1.2rem; | ||
} | ||
` | ||
const moveOnClick = (direction) => { | ||
dispatch(nextMove(direction)) | ||
} | ||
return ( | ||
actions.map((action) => ( | ||
<DirectionSection> | ||
<div key={action.direction} className="direction-div"> | ||
<p>{action.description}</p> | ||
<div> | ||
<MoveBtn type="button" onClick={() => moveOnClick(action.direction)}>Go {action.direction}</MoveBtn> | ||
</div> | ||
</div> | ||
</DirectionSection> | ||
)) | ||
); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
/* eslint-disable react/no-unescaped-entities */ | ||
import React, { useState, useEffect } from 'react'; | ||
import { useSelector } from 'react-redux'; | ||
import styled from 'styled-components'; | ||
import endPageImage from 'images/end-game-image.jpg' | ||
import soundFile from 'images/angels-singing.mp3' | ||
import { Direction } from './Direction'; | ||
|
||
export const Game = () => { | ||
const description = useSelector((store) => store.game.description); | ||
const [showEndPage, setShowEndPage] = useState(false); | ||
const onRestartButtonClick = () => { | ||
window.location.reload() | ||
} | ||
|
||
useEffect(() => { | ||
const audio = new Audio(soundFile); // Create an Audio object with the sound file | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great input with the sound-effect! |
||
if (showEndPage) { | ||
audio.play(); // Play the sound when showEndPage becomes true | ||
} | ||
}, [showEndPage]); | ||
|
||
const ResetBtn = styled.button` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe create a separate file for your design and styled components to keep function-files a bit cleaner/easy to follow :) But just an input, nothing major! |
||
font-family: 'Castoro Titling', cursive; | ||
background-color: #293d3d; | ||
border-radius: 5px; | ||
padding: 5px 10px; | ||
font-size: 1rem; | ||
cursor: pointer; | ||
margin-bottom: 20px; | ||
color: #FEF5BD; | ||
&:hover { | ||
background-color: #FEF5BD; | ||
color: #000; | ||
} | ||
@media (min-width: 668px) and (max-width: 1023px) { | ||
font-size: 1.2rem; | ||
} | ||
@media (min-width: 1024px) { | ||
font-size: 1.2rem; | ||
margin-top: 30px; | ||
} | ||
` | ||
const EndBtn = styled(ResetBtn)` | ||
background-color: #b3cccc; | ||
font-size: 1.5rem; | ||
padding: 10px 20px; | ||
`; | ||
|
||
const StyledParagraph = styled.p` | ||
background-color: #c2d6d6; | ||
border-radius: 30px; | ||
padding: 10px; | ||
text-align: center; | ||
margin-top: 100px; | ||
` | ||
const StyledImage = styled.img` | ||
max-width: 100%; | ||
max-height: 500px; | ||
border-radius: 30px; | ||
`; | ||
|
||
return ( | ||
<div className="game-div"> | ||
<p className="game-p">{description.description} <br /> <span style={{ textDecoration: 'underline' }}>which path will you choose?</span></p> | ||
<Direction actions={description.actions} /> | ||
{description.coordinates === '1,3' && ( | ||
<> | ||
<ResetBtn type="button" onClick={onRestartButtonClick}>Play again</ResetBtn> | ||
{!showEndPage && ( | ||
<EndBtn type="button" onClick={() => setShowEndPage(true)}>Show the light!</EndBtn> | ||
)} | ||
{showEndPage && ( | ||
<StyledImage src={endPageImage} alt="End Page" /> | ||
)} | ||
<div> | ||
<StyledParagraph>~By Nina W~ <br /> Student at Technigo</StyledParagraph> | ||
</div> | ||
</> | ||
)} | ||
</div> | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import React from 'react'; | ||
import Lottie from 'lottie-react'; | ||
import myAnimation from '../images/lottie2.json' | ||
|
||
const Loading = () => { | ||
return ( | ||
<Lottie | ||
animationData={myAnimation} // Replace animationData with your own Lottie animation data | ||
loop | ||
autoplay | ||
style={{ height: '300px', width: '300px' }} /> | ||
); | ||
}; | ||
|
||
export default Loading; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/* eslint-disable jsx-a11y/label-has-associated-control */ | ||
import React, { useState } from 'react'; | ||
import { useDispatch } from 'react-redux'; | ||
import { game, labyrinth } from 'reducers/labyrinth'; | ||
import styled from 'styled-components/macro'; | ||
|
||
const StyledForm = styled.form` | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
` | ||
const StyledInput = styled.input` | ||
font-family: 'Castoro Titling', cursive; | ||
background-color: #FEF5BD; | ||
border: none; | ||
padding: 7px 5px 7px 10px; | ||
outline: none; | ||
font-size: 1rem; | ||
color: #000; | ||
margin: 5vh 0 7vh 0; | ||
width: 145px; | ||
border-radius: 5px; | ||
@media (min-width: 668px) { | ||
font-size: 1.5rem; | ||
width: 210px; | ||
} | ||
` | ||
const StyledBtn = styled.button` | ||
font-family: 'Castoro Titling', cursive; | ||
background-color: #408000; | ||
color: white; | ||
border: none; | ||
border-radius: 20px; | ||
padding: 5px 10px; | ||
font-size: 1rem; | ||
cursor: pointer; | ||
&:hover { | ||
box-shadow: 2px 2px 5px rgba(254, 245, 189, 0.5), -2px -2px 5px rgba(254, 245, 189, 0.5); | ||
} | ||
@media (min-width: 668px) { | ||
font-size: 1.5rem; | ||
} | ||
` | ||
export const StartGame = () => { | ||
const [userName, setUserName] = useState(''); | ||
const dispatch = useDispatch(); | ||
|
||
const InputUserName = (event) => { | ||
event.preventDefault(); | ||
dispatch(game.actions.setUserName(userName)); | ||
dispatch(labyrinth()); | ||
} | ||
|
||
return ( | ||
<StyledForm onSubmit={InputUserName}> | ||
<label htmlFor="user-input"> | ||
<StyledInput id="user-input" type="text" placeholder="Name..." onChange={(event) => setUserName(event.target.value)} value={userName} required /> | ||
</label> | ||
<StyledBtn type="submit">Enter Labyrinth</StyledBtn> | ||
</StyledForm> | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import React from 'react'; | ||
import { useSelector } from 'react-redux'; | ||
import Loading from 'components/Loading'; | ||
import { Game } from './Game'; | ||
import { StartGame } from './StartGame'; | ||
|
||
export const StartPage = () => { | ||
const gameStarted = useSelector((store) => store.game.isStarted); | ||
const loading = useSelector((store) => store.game.loading); | ||
|
||
return ( | ||
<div className={gameStarted ? 'game-page' : 'start-page'}> | ||
{!gameStarted && <h1>Welcome to the Labyrinth</h1>} | ||
{loading && <Loading />} | ||
{!loading && ( | ||
<div> | ||
{!gameStarted && <StartGame />} | ||
{gameStarted && <Game />} | ||
</div> | ||
)} | ||
</div> | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"v":"5.4.2","fr":50,"ip":0,"op":100,"w":500,"h":500,"nm":"navigation","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"navigation Outlines - Group 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.477],"y":[1]},"o":{"x":[0.768],"y":[0]},"n":["0p477_1_0p768_0"],"t":0,"s":[0],"e":[-27]},{"i":{"x":[0.435],"y":[1]},"o":{"x":[0.63],"y":[0]},"n":["0p435_1_0p63_0"],"t":25,"s":[-27],"e":[0]},{"i":{"x":[0.33],"y":[1]},"o":{"x":[0.619],"y":[0]},"n":["0p33_1_0p619_0"],"t":50,"s":[0],"e":[27]},{"i":{"x":[0.503],"y":[1]},"o":{"x":[0.622],"y":[0]},"n":["0p503_1_0p622_0"],"t":77,"s":[27],"e":[0]},{"t":99}],"ix":10},"p":{"a":0,"k":[250.281,229.995,0],"ix":2},"a":{"a":0,"k":[150.281,144.495,0],"ix":1},"s":{"a":0,"k":[110,110,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[45.583,44.635],[-0.206,-44.635],[-45.583,43.823],[-0.206,20.489]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.223528977936,0.192156967462,0.674509983437,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"ix":5},"lc":1,"lj":1,"ml":10,"ml2":{"a":0,"k":10,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[150.281,144.495],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":100,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Merged Shape Layer","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250.25,262.648,0],"ix":2},"a":{"a":0,"k":[250.25,262.648,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,33.474],[53.496,0],[0,-33.474],[-53.496,0]],"o":[[0,-33.474],[-53.496,0],[0,33.474],[53.496,0]],"v":[[96.863,0],[0,-60.609],[-96.863,0],[0,60.609]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.223528981209,0.192156970501,0.674510002136,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"ix":5},"lc":1,"lj":1,"ml":10,"ml2":{"a":0,"k":10,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[150.25,150],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[250.25,250],"ix":2},"a":{"a":0,"k":[150.25,150],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"navigation Outlines - Group 2","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-53.496,0],[0,33.474],[0,0]],"o":[[0,0],[0,33.474],[53.496,0],[0,0],[0,0]],"v":[[-96.863,-27.952],[-96.863,-17.656],[0,42.952],[96.863,-17.656],[96.863,-27.952]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.223528981209,0.192156970501,0.674510002136,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"ix":5},"lc":1,"lj":1,"ml":10,"ml2":{"a":0,"k":10,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[150.25,182.452],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[250.25,292.953],"ix":2},"a":{"a":0,"k":[150.25,192.952],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"navigation Outlines - Group 3","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":100,"st":0,"bm":0}],"markers":[]} |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,138 @@ | ||
@import url('https://fonts.googleapis.com/css2?family=Castoro+Titling&display=swap'); | ||
body { | ||
margin: 0; | ||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", | ||
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", | ||
sans-serif; | ||
font-family: 'Castoro Titling', cursive; | ||
-webkit-font-smoothing: antialiased; | ||
-moz-osx-font-smoothing: grayscale; | ||
} | ||
|
||
code { | ||
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", | ||
monospace; | ||
font-family: 'Castoro Titling', cursive; | ||
} | ||
|
||
|
||
.main-container { | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
margin-bottom: 30px; | ||
} | ||
|
||
h1 { | ||
color: white; | ||
display: flex; | ||
justify-content: center; | ||
text-align: center; | ||
font-size: 2.5rem; | ||
width: 260px; | ||
} | ||
.top-lottie-container { | ||
margin-top: 60px; | ||
} | ||
.top-lottie { | ||
width: 100px; | ||
} | ||
|
||
.maze-span { | ||
color: #F8E152; | ||
} | ||
.large-span { | ||
white-space: nowrap; | ||
} | ||
.game-div { | ||
width: 90vw; | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
margin-top: 100px; | ||
} | ||
.game-p { | ||
font-weight: 700; | ||
font-size: 1.4rem; | ||
text-align: center; | ||
width: 80vw; | ||
color: white; | ||
background-color: rgba(128, 128, 128, 0.5); | ||
border-radius: 10px; | ||
margin-bottom: 30px; | ||
} | ||
.direction-div { | ||
width: 90vw; | ||
height: auto; | ||
background-color: rgba(128, 128, 128, 0.5); | ||
color: #e7e3c8; | ||
border-radius: 5px; | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
margin-bottom: 10px; | ||
} | ||
.direction-div p { | ||
text-align: justify; | ||
width: 80vw; | ||
padding: 5px 15px; | ||
font-size: 1rem; | ||
word-spacing: -3px; | ||
} | ||
|
||
@media (min-width: 668px) and (max-width: 1023px) { | ||
.top-lottie { | ||
width: 150px; | ||
} | ||
h1 { | ||
font-size: 3rem; | ||
} | ||
.spinner { | ||
height: 300px; | ||
width: 300px; | ||
} | ||
|
||
.game-p { | ||
font-size: 2rem; | ||
} | ||
.direction-div { | ||
margin-bottom: 20px; | ||
} | ||
.direction-div p { | ||
font-size: 1.3rem; | ||
width: auto; | ||
} | ||
|
||
|
||
@media (min-width: 1024px) { | ||
.top-lottie-container { | ||
position: absolute; | ||
top: 2vh; | ||
left: 2vh; | ||
margin: 0; | ||
} | ||
.top-lottie { | ||
width: 100px; | ||
} | ||
} | ||
.main-container { | ||
margin-top: 10px; | ||
width: 1024px; | ||
} | ||
.game-div { | ||
margin-top: 40px; | ||
} | ||
h1 { | ||
font-size: 2rem; | ||
} | ||
.game-p { | ||
width: 70vw; | ||
font-size: 1.6rem; | ||
max-width: 1024px; | ||
} | ||
.direction-div { | ||
width: 70vw; | ||
max-width: 1024px; | ||
} | ||
.direction-div p { | ||
width: 60vw; | ||
font-size: 1.3rem; | ||
max-width: 924px; | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { createSlice } from '@reduxjs/toolkit'; | ||
|
||
const initialState = { | ||
user: '', | ||
isStarted: false, | ||
description: '', | ||
isLoading: false, | ||
move: [] | ||
} | ||
|
||
export const game = createSlice({ | ||
name: 'game', | ||
initialState, | ||
reducers: { | ||
setUserName: (store, action) => { | ||
store.user = action.payload | ||
}, | ||
gameIsStarted: (store, action) => { | ||
store.isStarted = action.payload | ||
}, | ||
setDescription: (store, action) => { | ||
store.description = action.payload | ||
}, | ||
setMove: (store, action) => { | ||
store.move = [...store.move, action.payload] | ||
}, | ||
isLoading: (store, action) => { | ||
store.loading = action.payload | ||
} | ||
} | ||
|
||
}) | ||
// the two thunks: | ||
export const labyrinth = () => { | ||
return (dispatch, getState) => { | ||
dispatch(game.actions.isLoading(true)) | ||
|
||
const start = { | ||
method: 'POST', | ||
headers: { 'Content-type': 'application/json' }, | ||
body: JSON.stringify({ username: getState().game.user }) | ||
} | ||
fetch('https://labyrinth.technigo.io/start', start) | ||
.then((res) => res.json()) | ||
.then((data) => { | ||
dispatch(game.actions.setDescription(data)) | ||
dispatch(game.actions.gameIsStarted(true)) | ||
}) | ||
.finally(() => { | ||
dispatch(game.actions.isLoading(false)) | ||
}) | ||
} | ||
} | ||
|
||
export const nextMove = (direction) => { | ||
return (dispatch, getState) => { | ||
dispatch(game.actions.isLoading(true)) | ||
|
||
const move = { | ||
method: 'POST', | ||
headers: { 'Content-Type': 'application/json' }, | ||
body: JSON.stringify({ username: getState().game.user, | ||
type: 'move', | ||
direction }) | ||
} | ||
fetch('https://labyrinth.technigo.io/action', move) | ||
.then((res) => res.json()) | ||
.then((data) => { | ||
dispatch(game.actions.setDescription(data)) | ||
}) | ||
.finally(() => { | ||
dispatch(game.actions.isLoading(false)) | ||
}) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well done with this code!