diff --git a/src/components/Apple.js b/src/components/Apple.js new file mode 100644 index 0000000..104b15a --- /dev/null +++ b/src/components/Apple.js @@ -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; diff --git a/src/components/SnakePart.js b/src/components/SnakePart.js new file mode 100644 index 0000000..a8763db --- /dev/null +++ b/src/components/SnakePart.js @@ -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; diff --git a/src/components/Stage.js b/src/components/Stage.js index e69de29..4330ab9 100644 --- a/src/components/Stage.js +++ b/src/components/Stage.js @@ -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 }) => ( +
+ {data.map((r, y) => ( + + {r.map((c, x) => ( + {children(c)} + ))} + + ))} +
+); + +export default Stage; diff --git a/src/containers/Snake.js b/src/containers/Snake.js index 246d1da..3c3c1f6 100644 --- a/src/containers/Snake.js +++ b/src/containers/Snake.js @@ -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 }) => ( -
- {data.map((r, y) => ( - - {r.map((c, x) => ( - - {c.type === "apple" && } - {!died && c.type === "snake" && } - {died && c.type === "snake" && } - - ))} - - ))} -
-); - class Snake extends React.Component { constructor(props) { super(props); @@ -132,7 +67,12 @@ class Snake extends React.Component { return ( - + + {cell => + (cell.type === "apple" && ) || + (cell.type === "snake" && ) + } +