Extracted all components in their own files.
This commit is contained in:
17
src/components/Apple.js
Normal file
17
src/components/Apple.js
Normal file
@@ -0,0 +1,17 @@
|
||||
import styled from "styled-components";
|
||||
|
||||
export const Apple = styled.div.attrs({ role: "img", "aria-label": "apple" })`
|
||||
width: ${({ theme }) => theme.snake.cell.size};
|
||||
height: ${({ theme }) => theme.snake.cell.size};
|
||||
display: inline-block;
|
||||
font-size: 1.3rem;
|
||||
vertical-align: top;
|
||||
line-height: 1.8rem;
|
||||
padding-left: 0.0625rem;
|
||||
&:after {
|
||||
content: "${props => (!props.died ? "🍎" : "🐛")}";
|
||||
display: inline-block;
|
||||
}
|
||||
`;
|
||||
|
||||
export default Apple;
|
||||
29
src/components/SnakePart.js
Normal file
29
src/components/SnakePart.js
Normal file
@@ -0,0 +1,29 @@
|
||||
import styled, { css } from "styled-components";
|
||||
|
||||
export const SnakePart = styled.div`
|
||||
width: ${({ theme }) => theme.snake.cell.size};
|
||||
height: ${({ theme }) => theme.snake.cell.size};
|
||||
display: inline-block;
|
||||
font-size: 1.3rem;
|
||||
vertical-align: top;
|
||||
line-height: 1.8rem;
|
||||
padding-left: 0.0625rem;
|
||||
|
||||
${props =>
|
||||
!props.died
|
||||
? css`
|
||||
background-color: ${props => props.value && `hsl(340, ${props.value.brightness}%, 65%)`};
|
||||
box-shadow: 1px 1px 2px #ddd inset, -1px -1px 2px gray inset;
|
||||
`
|
||||
: css`
|
||||
background-color: ${props => props.value && `hsl(0, 0%, ${100 - props.value.brightness}% )`};
|
||||
box-shadow: 1px 1px 2px #ddd inset, -1px -1px 2px gray inset;
|
||||
|
||||
&:after {
|
||||
content: "${props => props.value && props.value.index === 0 && "💀"}";
|
||||
display: inline-block;
|
||||
}
|
||||
`}
|
||||
`;
|
||||
|
||||
export default SnakePart;
|
||||
@@ -0,0 +1,30 @@
|
||||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
|
||||
const Row = styled.div`
|
||||
white-space: nowrap;
|
||||
`;
|
||||
|
||||
const Cell = styled.div`
|
||||
width: ${({ theme }) => theme.snake.cell.size};
|
||||
height: ${({ theme }) => theme.snake.cell.size};
|
||||
border: ${({ theme }) => theme.snake.cell.border};
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
text-align: center;
|
||||
box-shadow: 1px 1px 4px gray inset, -1px -1px 4px #fff inset;
|
||||
`;
|
||||
|
||||
export const Stage = ({ data, children }) => (
|
||||
<div>
|
||||
{data.map((r, y) => (
|
||||
<Row key={`y${y}`}>
|
||||
{r.map((c, x) => (
|
||||
<Cell key={`x${x}y${y}`}>{children(c)}</Cell>
|
||||
))}
|
||||
</Row>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
||||
export default Stage;
|
||||
|
||||
@@ -17,6 +17,9 @@ import {
|
||||
/* Components */
|
||||
import ControlPanel from "../components/ControlPanel.js";
|
||||
import Scoreboard from "../components/Scoreboard.js";
|
||||
import Stage from "../components/Stage.js";
|
||||
import SnakePart from "../components/SnakePart.js";
|
||||
import Apple from "../components/Apple.js";
|
||||
|
||||
const Layout = styled.div`
|
||||
display: flex;
|
||||
@@ -29,74 +32,6 @@ const SidePanel = styled.div`
|
||||
flex-direction: column;
|
||||
`;
|
||||
|
||||
const Row = styled.div`
|
||||
white-space: nowrap;
|
||||
`;
|
||||
|
||||
const Cell = styled.div`
|
||||
width: ${({ theme }) => theme.snake.cell.size};
|
||||
height: ${({ theme }) => theme.snake.cell.size};
|
||||
border: ${({ theme }) => theme.snake.cell.border};
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
text-align: center;
|
||||
background-color: ${props => props.theme.snake.cellColors[" "]};
|
||||
box-shadow: 1px 1px 4px gray inset, -1px -1px 4px #fff inset;
|
||||
`;
|
||||
|
||||
const SnakePart = styled.div`
|
||||
width: ${({ theme }) => theme.snake.cell.size};
|
||||
height: ${({ theme }) => theme.snake.cell.size};
|
||||
background-color: ${props => props.value && `hsl(340, ${props.value.brightness}%, 65%)`};
|
||||
box-shadow: 1px 1px 2px #ddd inset, -1px -1px 2px gray inset;
|
||||
`;
|
||||
|
||||
const Apple = styled.div.attrs({ role: "img", "aria-label": "apple" })`
|
||||
width: ${({ theme }) => theme.snake.cell.size};
|
||||
height: ${({ theme }) => theme.snake.cell.size};
|
||||
display: inline-block;
|
||||
font-size: 1.3rem;
|
||||
vertical-align: top;
|
||||
line-height: 1.8rem;
|
||||
padding-left: 0.0625rem;
|
||||
&:after {
|
||||
content: "${props => (!props.died ? "🍎" : "🐛")}";
|
||||
display: inline-block;
|
||||
}
|
||||
`;
|
||||
|
||||
const Skull = styled.div.attrs({ role: "img", "aria-label": "skull" })`
|
||||
width: ${({ theme }) => theme.snake.cell.size};
|
||||
height: ${({ theme }) => theme.snake.cell.size};
|
||||
display: inline-block;
|
||||
font-size: 1.3rem;
|
||||
vertical-align: top;
|
||||
line-height: 1.8rem;
|
||||
background-color: ${props => props.value && `hsl(0, 0%, ${100 - props.value.brightness}% )`};
|
||||
padding-left: 0.0625rem;
|
||||
box-shadow: 1px 1px 2px #ddd inset, -1px -1px 2px gray inset;
|
||||
&:after {
|
||||
content: "${props => props.value && props.value.index === 0 && "💀"}";
|
||||
display: inline-block;
|
||||
}
|
||||
`;
|
||||
|
||||
const Grid = ({ data, died }) => (
|
||||
<div>
|
||||
{data.map((r, y) => (
|
||||
<Row key={`y${y}`}>
|
||||
{r.map((c, x) => (
|
||||
<Cell key={`x${x}y${y}`} died={died}>
|
||||
{c.type === "apple" && <Apple died={died} />}
|
||||
{!died && c.type === "snake" && <SnakePart value={c} />}
|
||||
{died && c.type === "snake" && <Skull value={c} />}
|
||||
</Cell>
|
||||
))}
|
||||
</Row>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
||||
class Snake extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@@ -132,7 +67,12 @@ class Snake extends React.Component {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Layout>
|
||||
<Grid data={grid} died={died} />
|
||||
<Stage data={grid}>
|
||||
{cell =>
|
||||
(cell.type === "apple" && <Apple died={died} />) ||
|
||||
(cell.type === "snake" && <SnakePart value={cell} died={died} />)
|
||||
}
|
||||
</Stage>
|
||||
<SidePanel>
|
||||
<Scoreboard score={score} zoom={2} />
|
||||
<ControlPanel
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
export default class GameLoop {
|
||||
-_isRunning = false;
|
||||
-_handler = null;
|
||||
|
||||
constructor(handler) {
|
||||
this._handler = handler;
|
||||
}
|
||||
|
||||
get isRunning() {
|
||||
return this._isRunning;
|
||||
}
|
||||
|
||||
start() {
|
||||
this._isRunning = true;
|
||||
}
|
||||
stop() {
|
||||
this._isRunning = false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user