테트리스 게임은 그 자체로 클래식한 재미를 제공하는 재미있는 프로젝트입니다. 이번 가이드에서는 배열 기반 회전 방식을 중심으로 테트리스를 개발하는 방법에 대해 단계적으로 설명하겠습니다. 이 과정을 통해 기본적인 게임 로직과 구조를 이해하고, 실제로 작동하는 테트리스 게임을 만들어보겠습니다.
테트리스 게임의 개요 및 기본 개념
테트리스는 도형이 위에서 아래로 떨어지는 구조를 가지고 있으며, 사용자는 이 도형을 좌우로 이동시키거나 회전시키는 등의 조작을 통해 바닥에 쌓이도록 합니다. 게임의 목표는 도형이 일정한 행을 가득 채워서 그 행을 제거하는 것입니다. 이러한 기본적인 흐름을 이해하고, 테트리스의 핵심인 ‘도형의 회전’ 개념을 바탕으로 게임을 구현할 필요가 있습니다.
배열 방식의 도형 회전과 게임 구현
배열 기반 도형 회전
테트리스에서 도형의 회전은 매우 중요한 요소입니다. 배열을 이용해 도형의 회전을 구현할 수 있으며, 이를 통해 다양한 형태의 도형을 손쉽게 다룰 수 있습니다. 배열로 표현된 도형은 2차원 배열로 각 요소가 도형의 블록을 나타냅니다. 회전 시에는 배열의 인덱스를 변경하여 도형의 모양을 변형합니다.
도형의 움직임 구현하기
도형이 아래로 떨어지는 기능을 구현하기 위해서는 주기적으로 도형의 위치를 업데이트해야 합니다. 이는 타이머를 활용하여 일정 시간 간격으로 도형의 Y 좌표를 증가시키는 방식으로 이루어집니다. 자바스크립트의 setInterval() 함수를 사용하여 400ms마다 도형을 그리는 함수를 호출하도록 설정합니다.
“`javascript
var sPos = {x:0, y:0};
var intervalHandler = setInterval(function () {
draw();
}, 400);
function draw() {
ctx.fillStyle = ‘white’;
ctx.fillRect(0, 0, 200, 400);
ctx.strokeStyle=”blue”;
ctx.strokeRect(0, 0, 200, 400);
ctx.fillStyle = ‘black’;
for (var y = 0; y < 4; y++) {
for (var x = 0; x < 4; x++) {
if (curShape[y][x]) {
ctx.fillRect((sPos.x+x) * 20, (sPos.y+y) * 20, 19, 19);
}
}
}
if (sPos.y++ === 18){
clearInterval(intervalHandler);
}
}
“`
위 코드는 도형을 그리는 기본 구조를 설정합니다. 도형의 위치는 sPos 객체로 관리되며, Y 좌표가 증가하면서 도형이 아래로 이동합니다.
도형 충돌 감지 및 게임판 관리
도형이 이동할 때마다 그 위치에 다른 도형이 있는지를 확인하는 기능이 필요합니다. 이를 위해 10×20 크기의 2차원 배열을 사용하여 게임판의 상태를 저장합니다. 도형이 이동할 때 충돌 감지 함수를 통해 다른 도형이 있는지 확인하고, 그에 따라 도형의 이동을 처리합니다.
“`javascript
var gamePanel = Array.from({length: 20}, () => Array(10).fill(0));
function intersects(y, x) {
if (y >= 20 || x < 0 || x >= 10) {
return true;
}
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
if (curShape[i][j] && gamePanel[y + i][x + j]) {
return true;
}
}
}
return false;
}
“`
이 함수는 도형이 이동할 수 있는지를 판단하며, 게임판 배열에서 이미 도형이 쌓여 있는 위치를 확인합니다.
도형 조작 구현하기
키보드 입력으로 도형 조작하기
도형을 조작하는 기능을 구현하기 위해, 버튼 대신 키보드 이벤트를 활용합니다. 사용자가 키보드를 눌렀을 때 해당 도형이 왼쪽, 오른쪽으로 이동하거나 회전하도록 설정합니다.
javascript
document.addEventListener('keydown', function(event) {
if (event.key === 'ArrowLeft') {
moveShape(-1);
} else if (event.key === 'ArrowRight') {
moveShape(1);
} else if (event.key === 'ArrowDown') {
dropShape();
} else if (event.key === 'ArrowUp') {
rotateShape();
}
});
위 코드는 키보드의 화살표 키를 눌렀을 때 각각의 조작을 수행하도록 설정합니다.
도형의 색상 지정하기
각 도형별로 고유한 색상을 지정하여 시각적으로 구분할 수 있도록 합니다. 도형의 유형에 따라 색상을 배열로 정의하고, 도형을 그릴 때 해당 색상을 사용하도록 구현합니다.
“`javascript
var colors = [‘cyan’, ‘blue’, ‘orange’, ‘yellow’, ‘green’, ‘purple’, ‘red’];
function drawShape() {
ctx.fillStyle = colors[curShapeType];
// 도형 그리기 로직
}
“`
이렇게 각 도형이 그려질 때마다 해당 색상을 적용하여 보다 명확히 도형의 종류를 알 수 있도록 합니다.
행 제거 기능 구현하기
게임판에서 한 행이 모두 채워졌을 때 해당 행을 제거하는 기능을 추가합니다. 이 기능은 게임판 배열을 검사하여 한 행이 모두 1로 채워져 있는지 확인한 후, 해당 행을 제거하고 위의 행을 아래로 내리는 방식으로 구현됩니다.
javascript
function removeRow() {
var newRows = [];
for (var y = 19; y >= 0; y--) {
if (gamePanel[y].every(cell => cell === 1)) {
newRows.unshift(Array(10).fill(0));
} else {
newRows.unshift(gamePanel[y]);
}
}
gamePanel = newRows;
}
이 코드는 각 행을 검사하여 완전히 채워진 행을 찾아내고, 완전한 행을 제거한 후 새롭게 게임판을 구성합니다.
결론
테트리스를 구현하는 과정은 다양한 프로그래밍 개념을 접목시킬 수 있는 훌륭한 프로젝트입니다. 도형의 회전, 이동, 충돌 감지, 키보드 입력, 행 제거 등 여러 개념을 종합적으로 활용하여 게임을 완성할 수 있습니다. 이 과정에서 각 개념을 잘 이해하고 구현하는 것이 중요하며, 이를 통해 프로그래밍 실력을 한층 더 향상시킬 수 있습니다.
