화면 구성
우선, 게임을 구현하기 앞서, 2048 게임 화면엘 들어갈 요소들 레이아웃들을 정해줍시다. 저는 Ant Design 의 그리드 시스템과 Styled Component를 이용하여 스타일링을 했습니다! 이 부분에 대해서는 따로 설명하지 않을테니 잘 모르시는 분들은 스타일 컴퍼넌트 공식문서 나 제 Antd 포스팅 을 보시고 오는걸 권장합니다!
최종 화면은 다음과 같을 것이고, 저는 스타일링에는 재주가 없다보니, 스타일은 본인 취향에 맞게 꾸미시는거를 추천드립니다 ㅎㅎㅎ😜
시작합니다!
레이아웃 나누기
Ant Design 에서는 기본적으로 Row 와 Col 을 지원해서 Grid 시스템을 쉽게 쓸수 있게 해줍니다. 저는 다음과 같이 레이아웃을 나눠보았습니다. 게임에 관한 요소들이 들어있는 Game2048Board 라는 자식 컴퍼넌트로 따로 빼주고, 나머지는 Col 과 Div 를 이용해서 나눴습니다.
Styled-Component로 스타일링 하기
스타일링이 된 요소들을 만들어 주었습니다. 알아보기 쉽게 이름을 용도에 맞게 지어주세요!
다음과 같은 요소들이 사용됩니다! 이 것 외에 것들은 간단하게 내부 style 태그를 이용했습니다.
const VersionButton = styled(Button)`
display: block;
width: 50%;
margin: 10px auto;
`
const ModeContainer = styled.div`
width: 60%;
background-color: #383b3a;
-webkit-box-shadow: 9px 11px 12px 2px rgba(0, 0, 0, 0.75);
-moz-box-shadow: 9px 11px 12px 2px rgba(0, 0, 0, 0.75);
box-shadow: 9px 11px 12px 2px rgba(0, 0, 0, 0.75);
padding: 20px;
margin: 20px auto;
`
const MainContainer = styled(Row)`
color: #f5f6fa;
min-height: 100vh;
background-color: ${GAME_BG_COLOR};
`
const H2 = styled.h2`
font-size: 2vw;
max-width: 75vw;
color: ${(props) => props.color || "inherit"};
font-family: "Red Hat Display", "Noto Sans KR", sans-serif;
`
미리 styled-component 모듈을 import 하셔야 하고, Button , Row , Col 과 같은 요소들 또한 antd 를 통해 import 하셨어야 합니다!
컴퍼넌트 부분
const game2048: NextPage<{ serverData: Data2048 }> = ({ serverData }) => {
const [version, setVersion] = useState(4)
const onClickButton = (ver: number) => {
setVersion(ver)
}
}
저희는 버전에 따라 2048 게임을 변화시켜줘야합니다! useState 를 이용해서 자식 컴퍼넌트인 Board를 담당하는 Game2048Board 에 version 변수를 전달해줘야합니다. 그리고 Button 을 클릭하면 trigger 될 onClickButton 함수를 작성해줍니다. 큰 내용은 없고 version을 변화시켜주는 함수입니다!
( serverData 에 관련된 것은 일단 넘어가세요! 최고점수 를 서버에다 저장해서 가져올 때 이용할 것입니다.)
return (
<MainContainer>
<Col xs={24} md={6} style={{ textAlign: "center" }}></Col>
/* 게임 네비게이션 바가 들어갈 공간 (저는 게임 여러개를 구현해둬서 만들었습니다) */
// 그냥 아무것도 안넣으셔도 됨
<Col xs={24} md={12}>
/* 가운데 부분 , 게임 보드와 설명, footer 등 들어갈 공간 */
<br></br>
// Game2048Board 컴퍼넌트는 추후 작성할 예정이니 일단 비워주셔도 됩니다!
<Game2048Board serverData={serverData} version={version}></Game2048Board>
<Row align='middle' justify='center' style={{ textAlign: "center" }}>
<p>조작법 : ➡ / ⬅ / ⬆ / ⬇</p>
<p>우측 상단메뉴를 통해 여러 모드와 테마로 즐길 수 있습니다! (웹 전용)</p>
</Row>
<footer>게임 내용 출처 : "https://play2048.co/"</footer>
</Col>
<Col xs={24} md={6} style={{ textAlign: "center" }}>
/* 게임 모드 선택 바를 넣을 공간 */
</Col>
</MainContainer>
)
가운데에 메인 파트부터 작성해보았습니다.
필요에 맞게 설명이나 내용을 작성해주시고, Game2048Board 컴퍼넌트는 아직 안만들었으니 그냥 놔두세요!
모드 선택 부분
<Col xs={24} md={6} style={{ textAlign: "center" }}>
/* 게임 모드 선택 바를 넣을 공간 */
<ModeContainer>
<H2>SELECT MODE</H2>
{new Array(4).fill(null).map((v, i) => (
<Popconfirm
placement='leftTop'
title={EXIT_TEXT}
onConfirm={() => {
message.info("Mode changed.")
onClickButton(i + 2)
}}
okText='Yes'
cancelText='No'
key={`Popconfirm__${i}`}
>
<VersionButton>{`${i + 2} ❌ ${i + 2}`}</VersionButton>
</Popconfirm>
))}
</ModeContainer>
</Col>
굳이 2*2 버튼 3*3 버튼 4*4 버튼 5*5 버튼 다 만드는 거는 비효율적입니다.
4개짜리 배열을 선언해서 한번에 구현해줍니다!
최종 코드
import React, { useState } from "react"
import { Row, Col, Button, Popconfirm, message } from "antd"
import Game2048Board from "../../components/games/Game2048Board"
import styled from "styled-components"
import { GAME_BG_COLOR, H2, H3_KR } from "../../styles/styled"
import GameNavigation from "../../components/GameNavigation"
import { NextPage, NextPageContext } from "next"
import db from "../../db/game2048"
const EXIT_TEXT = "진행중인 게임이 종료 됩니다."
const VersionButton = styled(Button)`
display: block;
width: 50%;
margin: 10px auto;
`
const ModeContainer = styled.div`
width: 60%;
background-color: #383b3a;
-webkit-box-shadow: 9px 11px 12px 2px rgba(0, 0, 0, 0.75);
-moz-box-shadow: 9px 11px 12px 2px rgba(0, 0, 0, 0.75);
box-shadow: 9px 11px 12px 2px rgba(0, 0, 0, 0.75);
padding: 20px;
margin: 20px auto;
`
const MainContainer = styled(Row)`
color: #f5f6fa;
min-height: 100vh;
background-color: ${GAME_BG_COLOR};
`
export interface Data2048 {
best: {
ver2: number
ver3: number
ver4: number
ver5: number
}
}
const game2048: NextPage<{ serverData: Data2048 }> = ({ serverData }) => {
const [version, setVersion] = useState(4)
const onClickButton = (ver: number) => {
setVersion(ver)
}
return (
<MainContainer>
<Col xs={24} md={6} style={{ textAlign: "center" }}></Col>
<GameNavigation></GameNavigation>
<Col xs={24} md={12}>
<br></br>
<Game2048Board serverData={serverData} version={version}></Game2048Board>
<Row align='middle' justify='center' style={{ textAlign: "center" }}>
<p>조작법 : ➡ / ⬅ / ⬆ / ⬇</p>
<p>우측 상단메뉴를 통해 여러 모드와 테마로 즐길 수 있습니다! (웹 전용)</p>
</Row>
<footer>게임 내용 출처 : "https://play2048.co/"</footer>
</Col>
<Col xs={24} md={6} style={{ textAlign: "center" }}>
<ModeContainer>
<H2>SELECT MODE</H2>
{new Array(4).fill(null).map((v, i) => (
<Popconfirm
placement='leftTop'
title={EXIT_TEXT}
onConfirm={() => {
message.info("Mode changed.")
onClickButton(i + 2)
}}
okText='Yes'
cancelText='No'
key={`Popconfirm__${i}`}
>
<VersionButton>{`${i + 2} ❌ ${i + 2}`}</VersionButton>
</Popconfirm>
))}
</ModeContainer>
</Col>
</MainContainer>
)
}
game2048.tsx 파일명으로 했습니다. 다음 포스팅은 게임의 핵심인 Game2048Board 부분으로 이어집니다!
| 리액트로 2048 게임 만들기🎮 |
2020/08/17 - [웹 개발/React] - [React🌀] React로 2048 게임 만들기 ! / 1️⃣ - 기본 세팅 및 소개 / Clone Coding
'Web > React' 카테고리의 다른 글
[React🌀] React로 2048 게임 만들기 ! 🎮 / 4️⃣ - 테마 설정하기 (0) | 2020.09.02 |
---|---|
[React🌀] React로 2048 게임 만들기 ! 🎮 / 3️⃣ - 알고리즘 구현 (0) | 2020.08.31 |
[React🌌] 리액트 공식문서 함께 읽기 📘 / 2️⃣ - 리액트를 사용하는 여러 방식 / (0) | 2020.08.28 |
[React🌌] 리액트 공식문서 함께 읽기 📘 / 1️⃣ - JSX 없이 사용하는 리액트 / (0) | 2020.08.24 |
[React🌀] React로 2048 게임 만들기 ! 🎮 / 1️⃣ - 기본 세팅 및 소개 / Clone Coding (1) | 2020.08.17 |
댓글