테트리스 게임 – JavaScript

tetris game screenshot

얼마 전 세미나에서 테트리스 게임을 만드는 것을 보고 다른 방식으로 만들어 보고 싶었다. 자바스크립트는 프로그래밍 방법을 강제하지 않아서 Functional Programming (FP) 방법을 같이 사용하기에 적당한 언어다. if 문을 사용하지 않는 방법을 시도했다. 음.. 동작은 한다. 시작 코드로 Create React App를 사용했는데 App.js, App.css 이 두 파일을 수정했고 fp-tetris 모듈을 사용했다. FP 라이브러리로 유명한 Lodash를 사용했다.

if, for, let, function 키워드를 사용하지 않는다.

if 키워드를 사용하지 않았다. 조건에 따라서 값을 변경할 경우에만 ?: 연산자를 사용하여 그 기능을 대신했다. 처음부터 일부러 if 문을 사용하지 않을 계획이 있었던 것은 아니다. 입력 값을 변경하여 출력하는 용도의 여러 함수를 만들다 보니 if 문을 덜 사용하게 되었고 나중에는 끝까지 사용하지 않으려 노력했다. Lodash를 사용하면 for 키워드는 자연스럽게 사용하지 않게 된다. let 키워드는 사용하지 않았다. 대신 const를 사용한다. 하나의 이름이 하나의 값을 가지면 코드를 이해하기 쉽다. class 키워드도 사용하지 않는다. class를 사용할 만큼 복잡한 데이터 구조도 없으며 Lodash의 flow를 사용하여 함수를 모아서 사용하기 때문에 class 키워드는 사용하지 않는다. React Component Class만 예외다. if, for, let 키워드를 C 언어의 goto 처럼 생각하는 것은 아니지만 사용하지 않으면 코드가 조금 더 읽기 쉬워진다고 생각한다. Function 키워드 사용하지 않는 것은 단지 취향이다.

좌표 정보를 따로 업데이트하지 않는다.

i++과 같은 코드는 제외하려고 노력했다. 좌표 정보가 필요할 것으로 예상되는 위에서 내려오는 블록은 2차원 배열에 저장했다. 매번 블록의 위치를 찾는 방식을 선택했다. 비 효율적이긴 하다. 데이터 구조는 간단하게 유지했다. 작은 함수들을 여럿 사용할 때는 단순한 데이터 구조가 편리할 것이라고 생각했다. 두 개의 2차원 배열을 사용하는데 코드에서 panel이라고 이름 지었다. 하나의 패널은 블록들을 쌓는 백그라운드를 나타내고 다른 하나는 위에서 떨어지고 있는 블록을 나타낸다. 이 두 패널을 합쳐서 브라우저 화면에 표시했다.

+-----------+   +-----------+   +-----------+
|           |   | +-------+ |   | +-------+ |
|           |   | | +-----+ |   | | +-----+ |
|     +-+   | + | +-+       | = | +-+ + +   |
+--+  | +-+ |   |           |   |--+  | +-+ |
|  +--+   +-+   |           |   |  +--+   +-|
+-----------+   +-----------+   +-----------+
  bgPanel         toolPanel        screen

블록이 서로 겹쳐지는 것은 두 패널을 교차하여 값을 확인하는 방법으로 해결했다. 이렇게 패널 두 개로 구성하면 블록이 어디에 있는지 알기 위해 위치 관련 코드를 작성할 필요가 없다. 단지 두 개의 배열만 처리하면 된다. 대부분의 함수는 이 패널을 인자로 받아서 두 개 패널을 변경하는 용도다. fp-tetris.js에서 패널을 변경하는 가장 상위의 함수는 아래와 같다.

  • tick
  • key

이벤트는 2개다.

이 두 함수를 호출하는 이벤트는 두개다.

  • 타이머
  • 사용자 키 입력

주기적으로 블록을 아래로 내려주는 타이머와 사용자의 키 입력이다. 블록을 저장하는 툴 패널은 타이머에 의하여 자동으로 아래로 내려오거나 방향키를 사용할 때 업데이트된다. 툴 패널이 더 내려갈 곳이 없다면 백그라운드 패널로 복사하고 툴 패널은 다시 만든다.

  • 좌, 우 방향키: 툴 패널의 블록 이동
  • 위 방향키: 툴 패널의 블록 회전
  • 아래 방향키: 툴 패널의 블록을 아래로 한 칸 이동
  • 스페이스키: 화면을 멈춘다.

블록을 찾아서 회전한다.

각 블록을 따로 데이터로 다루지 않는다. 그래서 블록을 회전하려면 먼저 툴 패널에 포함된 블록을 찾아야 한다. 블록이 위치하는 일정 영역을 임시 배열에 복사한다. 임시 배열을 회전한 다음 툴 패널에 복사하는 방법을 사용한다. 블록을 회전하는데 아래 자바스크립트 코드를 사용했다.

View at Medium.com

Canvas는 사용하지 않는다.

React를 사용하여 DOM을 업데이트 한다.

마무리

Lodash 같은 라이브러리를 사용한다고 바로 FP 스타일 코드가 되는 것은 아니지만 그래도 처음 시작할 때는 이런 라이브러리를 사용하는 괜찮은 방법이라 생각한다. 아직 코드는 미숙하지만 FP 방식을 사용하려고 노력한 것만으로도 이해하기 쉽고 수정하기 쉬운 코드가 되었다고 생각한다.

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google photo

Google의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중

This site uses Akismet to reduce spam. Learn how your comment data is processed.