react.js

리액트로 테트리스 만들어보자[2]

윤만석 2022. 10. 31. 13:16

https://orgin00.tistory.com/48

 

리액트로 테트리스 만들어보자[1]

App.js 전체 코드입니다. 난잡하지만 끊어서 보겠습니다. 첫번째 글에서는 커스텀훅으로 게임화면,크기를 지정하고 canvas를 이용해 게임보드와 현재 블록, 그리고 다음 블록이 보여질 박스까지 그

orgin00.tistory.com

블록을 그리는 함수까지 만들었습니다.

 

이번에는 app.js에서 HTML부분을 살펴보고, 여러가지 상태관리를 보겠습니다.

 

  return (
    <div>
      <div className="main">
        <div
          style={{
            marginLeft: "50px",
          }}
        >
          <Tetris fowardRef={repeatRef} />
        </div>

        <div
          style={{
            marginLeft: "50px",
            marginBottom: "200px",
          }}
        >
          <div style={{ marginTop: "50px" }}>
            <NextBlockBox />
            <UserInterface data={data} />
            <button onClick={() => setOnGame(true)}>시작</button>
          </div>
        </div>
      </div>
    </div>
  );

우선 return 의 HTML부분입니다.

Tetris 컴포넌트에서 게임을 실행합니다. useRef를 사용하는데 children component로 한단계 내려가야 하므로 fowardRef를 사용합니다.

 

NextBlockBox 컴포넌트는 다음 블록을 보여줄 박스입니다.

UserInterface 컴포넌트는 score,level,stage 등 유저 데이터를 보여주는 박스입니다.

그 아래 버튼은 게임 시작 버튼입니다.

 

  const [map, setMap] = useState(initMatrix());
  const [CurrentBlock, setCurrentBlock] = useState(createRandomBlock());
  const [NextBlock, setNextBlock] = useState(createRandomBlock());
  const [FilledLines, setFilledlines] = useState([]);
  const [timeForRemoved, setTimeForRemoved] = useState(0);
  const [cur, setCur] = useState(0);
  const [onGame, setOnGame] = useState(false);
  
  const [data, setData] = useState({
    score: 0,
    level: 1,
    stage: 1,
  });

기본적으로 useState를 이용해서 상태관리를 해주었습니다.

map은 10*21 좌표를 생성하는 initMatrix함수를 만들었습니다.

 

InitMatrix.js

//10*21 0으로 이루어진 배열을 생성합니다.
//빈배열 matrix를 선언하고, for문의 21번 반복동안 matrix에 10칸의 new Array(10) 0 을 채운채로 push합니다.
export const initMatrix = () => {
  let matrix = [];
  for (let y = 0; y < 21; y++) {
    matrix.push(new Array(10).fill(0));
  }
  return matrix;
};

 

CurrentBlock과 NextBlock은 각각 createRandomBlock함수로 초기화 했습니다. 

 

SelectBlock.js

import { BLOCK } from "../source/block";
//위에서 import 한 source/block 파일은 아래와 같습니다.
/*
block.js

export const BLOCK = [
  [
    [1, 1],
    [1, 1],
  ],
  [
    [0, 2, 0, 0],
    [0, 2, 0, 0],
    [0, 2, 0, 0],
    [0, 2, 0, 0],
  ],
  [
    [3, 0, 0],
    [3, 3, 3],
    [0, 0, 0],
  ],
  [
    [0, 0, 4],
    [4, 4, 4],
    [0, 0, 0],
  ],
  [
    [0, 5, 0],
    [5, 5, 5],
    [0, 0, 0],
  ],
  [
    [0, 6, 6],
    [6, 6, 0],
    [0, 0, 0],
  ],
  [
    [7, 7, 0],
    [0, 7, 7],
    [0, 0, 0],
  ],
];
//블록의 종류에 따라 색을 다르게 주어야하므로, 1부터7까지 숫자를 넣었습니다. 빈칸은 0입니다.

*/

//1~7까지 랜덤 Index를 반환합니다. Math.rendom()
export const selectRandomIndex = (length) => {
  return Math.floor(Math.random() * length);
};
//selectRandomIndex(7)을 사용해서 Block의 random 요소를 반환합니다.
export const selectRandomBlock = () => {
  return BLOCK[selectRandomIndex(BLOCK.length)];
};

//randomBlock의 요소로 x,y좌표 그리고 type이 있습니다.
export const createRandomBlock = () => {
  const randomBlock = {
    x: 0,
    y: 0,
    type: selectRandomBlock(),
  };
  return randomBlock;
};

FilledBlock 은 매번 블록으로 가득찬 line이 있다면 그 line들을 저장합니다.

이후 게임로직에 사용됩니다.

 

timeForRemoved 와 cur은 시간으로, 게임 로직에 사용됩니다.

 

onGame은 게임시작시 true, 아닌경우 false가 됩니다.

 

data같은경우 level,stage,score을 요소로 가지고 있습니다.

 

 

https://github.com/Mansook/TetrisBot