일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- Algorithm
- 알고리즘
- redux-toolkit
- Python
- 항해99
- 테코테코
- sw expert academy
- JavaScript
- redux-saga
- useDispatch
- react-router
- react
- Get
- 프로그래머스
- 코딩테스트합격자되기
- programmers
- 리액트
- axios
- java
- 이코테
- json-server
- maeil-mail
- 항해플러스
- react-redux
- C++
- SW
- 매일메일
- 자바
- redux
- createSlice
- Today
- Total
Binary Journey
[React][Clone] Chess 게임 만들기 - 2. (2) 체스판 모양 갖추기, require 로 image 파일 가져오기, default 의 필요성 본문
[React][Clone] Chess 게임 만들기 - 2. (2) 체스판 모양 갖추기, require 로 image 파일 가져오기, default 의 필요성
binaryJournalist 2021. 2. 10. 08:57
이전 글
2021/02/09 - [React] - [React][Clone] Chess 게임 만들기 (single-player) - 2. (1) board settings
참고한 영상
www.youtube.com/watch?v=kBR7pDLcC3A&t=2462s
전체 배경색을 꺼멓게 만들었으니 이제는 격자무늬와 체스말을 그려줄 차례다.
Board.js에서 map으로 뿌려준 board 부분에 class 'square'를 추가한다.
// /src/Board.js
return (
<div className="board">
{board.map((piece, index) => (
<div key={index} className="square">
<p>{JSON.stringify(piece)}</p>
</div>
))}
</div>
);
App.css 에 square class를 만들어준다.
.square {
width: 12.5%;
height: 12.5%;
}
격자무늬를 위해 Square.js 파일을 먼저 생성한다.
// /src/Square.js
import React from 'react';
function Square() {
return (
<div>
</div>
);
}
export default Square;
체스말을 위해 Piece.js 파일을 생성한다.
// /src/Piece.js
import React from 'react';
function Piece() {
return (
<div>
</div>
);
}
export default Piece;
격자무늬판을 위해 BoardSquare.js 파일을 생성한다. BoardSquare 컴포넌트는 piece를 property로 받아 사용할 것이다.
그리고 Square 컴포넌트를 import한다.
Piece 컴포넌트도 import하여 Square 컴포넌트 안에 배치한다.
받은 piece property는 다시 Piece 컴포넌트에 넘겨준다.
// /src/BoardSquare.js
import React from 'react';
import Square from './Square';
import Piece from './Piece';
function BoardSquare({piece}) {
return (
<div>
<Square>
<Piece piece={piece} />
</Square>
</div>
);
}
export default BoardSquare;
화면을 보면 아직 모양이 위와 같을 것이다.
위 항목들을 1차원 배열로 바꿔줘야 한단다. (영상에서 그렇게 설명함)
그래서 사용하던 함수 map 앞에 flat 을 추가해줘야 한다.
나도 믿기지 않았는데 소스를 수정하고 화면을 다시 봐보자.
소스들이 체스판처럼 배치되어있다. (잘 보일지는 모르겠지만)
영상에서 이유는 정확히 안 말해주지만 아무래도 Square에 null이 안보이게 하기 위해 조건항을 넣어주는 거 같다.
BoardSquare에 조건부 렌더링을 작성해주자.
// /src/BoardSquare.js
function BoardSquare({piece}) {
return (
<div>
<Square>
{/* 수정 */}
{ piece && <Piece piece={piece} /> }
</Square>
</div>
);
}
그리고 Board.js에 BoardSquare를 import 하고 JSON.stringify 로 소스를 보여줬던 부분을 BoardSquare로 바꿔준다.
// /src/Board.js
...
import BoardSquare from './BoardSquare';
function Board({board}) {
return (
<div className="board">
{board.flat().map((piece, index) => (
<div key={index} className="square">
<BoardSquare piece={piece} />
{/* <p>{JSON.stringify(piece)}</p> */}
</div>
))}
</div>
);
}
...
Square.js 는 따로 property 를 만들어 보내지 않았으므로 children으로 property 를 받아 작성한다.
// /src/Square.js
import React from 'react';
function Square({children}) {
return (
<div>
{children}
</div>
);
}
export default Square;
그리고 Piece 컴포넌트에서 piece 는 체스말을 가려주는 type만 보이게 한다.
// /src/Piece.js
import React from 'react';
function Piece({piece}) {
return (
<div>
{piece.type}
</div>
);
}
export default Piece;
그러고나서 화면을 보면
아직 그림은 없지만 알파벳으로 말들이 진열된 게 보인다.
하지만 그전에 격자무늬를 흑과 백으로 나눠 만들어줘야 할 것 같다.
Board 컴포넌트 안에 자리값에 따라 흑백을 가릴 함수를 만들고 그 함수를 BoardSquare->Square에 black property로 넘겨준다.
// /src/Board.js
...
function getXYPosition (i) {
const x = i % 8;
const y = Math.abs(Math.floor(i / 8) - 7);
return { x, y }
}
function isBlack (i) {
const { x, y } = getXYPosition(i);
return (x + y) % 2 === 1;
}
return (
...
<BoardSquare piece={piece} black={isBlack(index)} />
// /src/BoardSquare.js
function BoardSquare({piece, black}) {
return (
<div className="board-square">
<Square black={black} >
{ piece && <Piece piece={piece} /> }
그리고 격자무늬 색이 갈라지는 건 Square 이므로 Square 에서 결과에 따라 흑백이 나뉘는 분기를 만들어준다.
(아직 해당 이름의 class를 만들지는 않았지만 먼저 써준 후 만들기로 한다.)
// /src/Square.js
function Square({children, black}) {
const bgClass = (black) ? 'square-black' : 'square-white';
return (
<div className={`${bgClass} board-square`}>
/* /src/App.css */
.square-black {
background: #B59963;
}
.square-white {
background: #F0D9B5;
}
.board-square {
width: 100%;
height: 100%;
}
색은 완전 흑백이 아닌 약간의 갈색 계열로 만들었다. (변경 가능)
이제 말에 맞는 이미지를 씌워줄 차례인데 진행하기 전에 이미지를 먼저 가져와야 한다.
위의 사이트에서 zip파일을 다운받아서(git clone 도 가능) ./src/assets 폴더를 복사하여 지금 작업하고 있는 /src 폴더에 붙여넣기한다.
그리고 Piece 컴포넌트를 수정해보자.
// /src/Piece.js
import React from 'react';
function Piece({ piece: { type, color } }) {
const pieceImg = require(`./assets/${type}_${color}.png`);
return (
<div>
<img src={pieceImg} alt="" />
</div>
);
}
export default Piece;
require는 다른 의미의 import라고 생각하면 된다.
영상에서는 위와 같이 하면 체스말 그림이 바로 뜨는데 내 화면에서는 안 뜨길래 어디서 문제인지 계속 찾아보았다.
퇴근 시간 가까이 돼서 끝내 포스팅을 못했는데 출근해서야 찾았다.
stackoverflow.com/questions/59070216/webpack-file-loader-outputs-object-module
It seems that webpack resolves ES module require() calls to an object that looks like this: {default: module}, instead of to the flattened module itself. This behavior is somewhat controversial and is discussed in this issue.
Therefore, to get your src attribute to resolve correctly, you need to be able to access the default property of the exported module. If you're using a framework, you should be able to do something like this:
<img src="require('assets/logo.png').default"/>
그래서 Piece.js 에 require 뒤에 .default 를 붙여보았다.
// /src/Piece.js
import React from 'react';
function Piece({ piece: { type, color } }) {
const pieceImg = require(`./assets/${type}_${color}.png`).default;
return (
<div className="piece-container">
<img src={pieceImg} alt="" className="piece" />
</div>
);
}
export default Piece;
이젠 매우 잘 보인다!
영상에서는 체스말들이 ugly 하다며 정리를 위해 class를 추가하였다.
/* /src/App.css */
.piece-container {
cursor: grab;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.piece {
max-width: 70%;
max-height: 70%;
}
cursor: grab 은 마우스가 말 위로 다가가면 손바닥을 펼치는 모양으로 바뀌어있다가 클릭하고 있을 동안은 정말 쥐고 있는 것처럼 쥐고 있는 손모양으로 바꿔준다.
영상 제작자 말대로 pretty 해졌다.
다음 포스팅은 아마 drag and drop 을 이용하여 체스말들의 자리를 바꿔주는 걸 하지 않을까 싶다.
'React' 카테고리의 다른 글
[React][Clone] Chess 게임 만들기 - 4. useDrag 궁금증 풀기 (0) | 2021.04.02 |
---|---|
[React][Clone] Chess 게임 만들기 - 3. 체스말 움직이기 (0) | 2021.02.10 |
[React][Clone] Chess 게임 만들기 - 2. (1) board settings (0) | 2021.02.09 |
[React][Clone] Chess 게임 만들기 - 1. setting (0) | 2021.02.09 |
[React][react-quickly review #1] 속성(props), 상태(state), 바벨(babel) 상태비저장 컴포넌트 관련 필기 (0) | 2020.09.28 |