Web/React

[React🌀] React로 2048 게임 만들기 ! 🎮 / 4️⃣ - 테마 설정하기

서상혁 2020. 9. 2. 16:45

테마를 만들어보자!

 제가 만드는 2048 게임의 2번째 차별점입니다, 기존의 2048 게임은 항상 똑같은 색깔이라 그런지 계속하다보면 밋밋한 기분이 들죠. 그래서 뭔가 버튼 클릭에 따라서 맵도 바뀌고 테마도 이쁘게 바뀌었으면 하는 생각을 해봤습니다. 그런데 정작 제 자신이 디자인알못이라 테마에 들어갈 색을 이쁘게 고르지는 못한다는 허점이 있네요 ㅎㅎㅎㅎ 😂

 


타일별로 색 설정하기

완성 모습을 보시면 타일별로 색깔이 다 다릅니다.

그렇다고 해서 숫자 셀 하나하나를 컴퍼넌트로 설정하면 불편하겠죠? 저희는 Styled-component 를 이용해서 구현합시다!

 

레벨 별 색 설정

 

Game2048Fun.ts

먼저 단계별 무슨 색상을 할 것인지 설정해줍시다. 직접 고르는거보다 요즘은 색 고르는데에 도움을 주는 파레트 사이트가 좋은게 많으니 참고하시면 좋을 것 같습니다!

 

테마 색을 하나하나 직접 커스텀 하실 분들은, 이 부분의 구조를 바꾸시면 됩니다! 저는 LEVEL 13 까지는 거의 가기 불가능에 가깝다는 점을 이용해서 LEVEL0 색깔은 숫자 0 인 Cell 로 고정. 테마 1번은 LEVEL1 색깔부터 오름차순, 테마 2번은 LEVEL13 부터 내림차순 으로 진행되도록 만들었습니다!

 

테마 커스텀 예시

 

const Theme1 = {
  LEVEL0 : "#d2dae2",
  LEVEL1 : "#fffa65",
  // ...... 이런식으로
}

 

막상 예시를 쓰고보니, 이런 방식이 더 나았을 것 같다는 생각이... 조만간 제 코드도 수정해야겠습니다.

 


파레트 참고 사이트

 

flatuicolors.com/ 

 

Flat UI Colors 2 - 14 Color Palettes, 280 colors 🎨

280 handpicked colors ready for COPY & PASTE

flatuicolors.com

colorhunt.co/

 

Color Hunt - Color Palettes for Designers and Artists

Color Hunt is a free and open platform for color inspiration with thousands of trendy hand-picked color palettes

colorhunt.co


 

 

버전별로 색을 고를 수 있게 해주는 함수도 만들어줍니다.

export const chooseColor: any = {
  0: LEVEL0,
  // Ver 2 , 4
  2: LEVEL1,
  4: LEVEL2,
  8: LEVEL3,
  16: LEVEL4,
  32: LEVEL5,
  64: LEVEL6,
  128: LEVEL7,
  256: LEVEL8,
  512: LEVEL9,
  1024: LEVEL10,
  2048: LEVEL11,
  4096: LEVEL12,
  8192: LEVEL13,
  // Ver 3
  3: LEVEL1,
  6: LEVEL2,
  12: LEVEL3,
  24: LEVEL4,
  48: LEVEL5,
  96: LEVEL6,
  192: LEVEL7,
  384: LEVEL8,
  768: LEVEL9,
  1536: LEVEL10,
  3072: LEVEL11,
  6144: LEVEL12,
  12288: LEVEL13,
  // Ver 4
  5: LEVEL1,
  10: LEVEL2,
  20: LEVEL3,
  40: LEVEL4,
  80: LEVEL5,
  160: LEVEL6,
  320: LEVEL7,
  640: LEVEL8,
  1280: LEVEL9,
  2560: LEVEL10,
  5120: LEVEL11,
  10240: LEVEL12,
  20480: LEVEL13,
}

(Game2048Fun.ts)

 

약간 하드코딩 느낌이 없지않아 있네요 흠.. 개선 방안을 생각해보는게 좋을 것 같기도 합니다.

 

 


 

화면에 적용시키기

 

타입 인터페이스 선언

interface CellProps {
  version: number
  customTheme?: number
  value: number
}

 

하나의 칸을 의미하는 Cell

import styled from "styled-components"

const Cell = styled.div`
  ${(props: CellProps) => getStyle(props.version)}
  position: relative;
  background-color: ${(props: CellProps) => {
    let version = props.version !== 4 ? props.version : 2 // 4버전은 2버전이랑 색을 공유
    let index = props.value / version // 테마2 거꾸로 알고리즘에 이용할 index
    if (index === 0) return chooseColor[0]
    let color = chooseColor[props.value]
    switch (props.customTheme) {
      case 1:
        color = chooseColor[props.value]
        break
      case 2:
        color = chooseColor[Math.floor(Math.pow(2, 13) / index)] // 테마2는 거꾸로 진행
        break
      default:
        break
    }
    return color
  }};
  border: 2px solid;
`

props 로 version 과 value 를 받아서 색깔을 조정해줍니다!

 

커스텀 FlexDiv

export const FlexDiv = styled.div`
  display: ${(props: FlexDivProps) => props.flex || "flex"};
  flex-direction: ${(props: FlexDivProps) => props.direction || "row"};
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  background-color: ${(props: FlexDivProps) => props.backgroundColor || "auto"};
  height: ${(props: FlexDivProps) => props.height || "auto"};
  width: ${(props: FlexDivProps) => props.width || "auto"};
`

 

버전 정보는 부모에서 받아와요

 

const Game2048Board: NextPage<{ version: number }> = ({version}) => {
  const [gameBoard, setGameBoard] = useState<number[][]>(init_gameBoard(version))
  const [theme, setTheme] = useState<number>(1)
}

 

테마 바꾸는 버튼

<Button onClick={onClickChange}>테마바꾸기</Button>

const onClickChange = useCallback(
    (e: React.MouseEvent) => {
      const { current }: any = gameDoing
      current?.focus()
      setText("THEME CHANGED!")
      setTheme(theme === 1 ? 2 : 1)
    },
    [version, theme, playing],
 )

 

 

 

return 하는 jsx 에 넣어주자!  

<div onClick={gameFocus} style={{ margin: "10px auto" }}>
          {gameBoard.map((row, r) => (
            <FlexDiv width='55%' key={`FlexDiv__${r}`} style={{ margin: "0 auto" }}>
              {row.map((num, c) => (
                <Cell version={version} value={num} customTheme={theme} key={`Cell__${r}_${c}`}>
                  <InnerH2 color={GAME_BG_COLOR} key={`H2__${r}_${c}`}>
                    {num !== 0 ? num : " "}
                  </InnerH2>
                </Cell>
              ))}
            </FlexDiv>
          ))}
        </div>

 


완료된 모습

 

 

 

 

 


| 리액트로 2048 게임 만들기🎮 |

 

2020/08/17 - [웹 개발/React] - [React🌀] React로 2048 게임 만들기 ! / 1️⃣ - 기본 세팅 및 소개 / Clone Coding

2020/08/29 - [웹 개발/React] - [React🌀] React로 2048 게임 만들기 ! 🎮 / 2️⃣ - 화면 레이아웃 잡기

2020/08/31 - [웹 개발/React] - [React🌀] React로 2048 게임 만들기 ! 🎮 / 3️⃣ - 알고리즘 구현

2020/09/02 - [분류 전체보기] - [React🌀] React로 2048 게임 만들기 ! 🎮 / 4️⃣ - 테마 설정하기

 

 

 

 

 

* 전체 코드는 제 깃허브에서 확인 가능합니다.

* 제가 직접 읽고 느낀 생각을 글로 쓰는 것이기에, 잘못된 내용이 있을 수 있습니다. 피드백과 지적은 언제나 환영합니다!

 

 

728x90