Extracted all components in their own files.

This commit is contained in:
2019-08-27 15:17:52 +02:00
parent 75a6247586
commit aa1bf44f7c
5 changed files with 85 additions and 88 deletions

17
src/components/Apple.js Normal file
View 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;

View 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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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;
}
}