본문 바로가기
자바스크립트와 캔버스

자바스크립트와 캔버스 6, 테트리스를 만들어봐-2

1. HTML 표준 CANVAS 기술 소개 / https://itadventure.tistory.com/130

2. 자바스크립트와 CANVAS 두번째시간. 캔바스에 눈을 내리자 / https://itadventure.tistory.com/131

3. 자바스크립트와 캔버스 3번째 시간, 공튀기기 놀이 / https://itadventure.tistory.com/132

4. 자바스크립트와 캔버스 4번째 시간, 마우스의 파동을 느껴봐! | https://itadventure.tistory.com/133

 

5. 자바스크립트와 캔버스, 테트리스를 만들어봐-1 | https://itadventure.tistory.com/136

◐ 6. 자바스크립트와 캔버스, 테트리스를 만들어봐-2 ◑


지난 시간에는 20행 10열의 블럭박스를 구성하고
블럭 1개를 채운 결과를 캔버스에 표시하는 부분을 다뤄보았었습니다.

오늘은 블럭박스 위에서 떨어지는 테트리스 조각을 다뤄볼텐데요.
여기서 잠깐 퀴~즈입니다.
테트리스 게임에서 퍼즐조각은 몇가지나 있을까요?
변형판이 아닌 초기 테트리스 게임 기준입니다.

:
:

총 7가지입니다. 아래와 같지요.

이 중에서 우선 5가지 정도만 다루어 볼텐데요.

사실 특별한 이유가 있는게 아니라 급하게 미리 준비하다 보니 처음에 5개만 생각이 나서 미리 만들어놓은게 5개라서 그렇습니다 :)

2개는 나중에 생각이 나더라구요 ㅎ..

우선 논리적인 틀을 먼저 구성해보지요.

5개의 블럭조각중 1개가 블럭박스 안에 표시될텐데요.

표시될 때만 블럭박스 안에서 표시가 되고,

변수로는 별도로 정의되어야 관리하기가 편리합니다.

5가지 타입의 블럭박스를 다음과 같이 정의할 겁니다.

4개 상대 좌표 ( +y, +x ) 지점을 위치값으로 갖는 배열을 블럭 하나로 5개의 배열을 정의

이를테면 첫번째 블럭 의 경우,

[ □□□□ ]

(0,0), (0,1), (0,2), (0,3) 이 블럭의 구성좌표가 됩니다.

두번째 블럭의 경우

[ □□□ ]

[ □ ]

(0,0), (0,1), (0,2), (1,1) 이 블럭의 구성좌표가 되는 것이지요.

이와 같이 5개의 블럭조각의 좌표를 초기화하는 코드를 구성합니다.

먼저 전역변수로 블럭조각을 담을 변수를 정의하고,

// 5가지 타입 블록
var tetrix_block;

블럭조각을 초기화 할 함수를 정의한 다음에

// 5가지 블럭 초기화
function tetrix_block_init()
{
	:
}

함수 안에 블럭 조각을 우선 배열로 정의합니다.

tetrix_block=new Array();

그리고 첫번째 조각을 배열로 만들어서 집어넣는 것이지요.

좌표 구성 형식으로 말이죠.

	// 첫번째 블럭
	// □□□□
	tmp=new Array();
	tmp.push(0,0); tmp.push(0,1); tmp.push(0,2); tmp.push(0,3);
	tetrix_block.push(tmp);

하지만 좌표라고 해서 거창한건 아니고 사실 tmp.push(0, 1); 과

tmp.push(0); tmp.push(1); 과는 똑같은 의미입니다.

그냥 배열 요소가 8개가 추가된다고 보시면 됩니다.

이어서 두번째부터 다섯번째 조각까지 초기화하는 함수 전체입니다.

// 5가지 블럭 초기화
function tetrix_block_init()
{
	tetrix_block=new Array();

	// 첫번째 블럭
	// □□□□
	tmp=new Array();
	tmp.push(0,0); tmp.push(0,1); tmp.push(0,2); tmp.push(0,3);
	tetrix_block.push(tmp);

	// 두번째 블럭
	// □□□
	//  □
	tmp=new Array();
	tmp.push(0,0); tmp.push(0,1); tmp.push(0,2); tmp.push(1,1);
	tetrix_block.push(tmp);

	// 세번째 블럭
	// □□
	//  □□
	tmp=new Array();
	tmp.push(0,0); tmp.push(0,1); tmp.push(1,1); tmp.push(1,2);
	tetrix_block.push(tmp);

	// 네번째 블럭
	//  □□
	// □□
	tmp=new Array();
	tmp.push(0,1); tmp.push(0,2); tmp.push(1,0); tmp.push(1,1);
	tetrix_block.push(tmp);

	// 다섯번째 블럭
	// □□
	// □□
	tmp=new Array();
	tmp.push(0,0); tmp.push(0,1); tmp.push(1,0); tmp.push(1,1);
	tetrix_block.push(tmp);
}

이 함수도 지난 블럭박스처럼 Init() 함수에서 한번 호출해주면 됩니다.

// 초기화
function Init()
{
	if(init==false)
	{
             :
		tetrix_blockbox_init();	// 블럭상자 초기화
             :
	}
}

블럭조각 모양도 준비가 되었으니 이제 블럭조각을 블럭박스 안에 표시할 차례입니다.

블럭조각이 위에서 아래로 떨어지려면 블럭조각은 가로, 세로 좌표가 있어야 합니다.

그리고 현재 표시할 블럭조각이 몇번째 블럭인지의 정보도 있어야 겠지요?

블럭조각은 1번으로 하고, (x, y) 좌표는 3, 2 로 정하기로 합시다.

아래와 같이 전역변수를 선언하고 값을 초기화합니다.

// 현재 떨어지는 블록번호와 좌표
var tetrix_block_number=1;
var tetrix_block_x=3;
var tetrix_block_y=0;

그리고 블럭 박스 내에 블럭조각을 표시할텐데요.

Draw 함수 내에서 블럭 박스를 그려주는 for 반복문 내에 이 부분을 추가해주겠습니다.

원래 Draw 함수에서 블럭을 표시해주는 부분은 아래와 같이 블럭박스의 현재 위치에 따라 그려줄 색상을 정의해주는 부분이 전부였습니다만,

	// 블럭 표시
	for(i=0;i<20;++i)
		for(j=0;j<10;++j)
		{
			if(tetrix_blockbox[i][j]==0)
				Context.fillStyle="#ccc";
			else
				Context.fillStyle="green";
             :

그 아래에 이런 코드가 추가됩니다. 현재 위치를 블럭 조각이 지나고 있으면 표시할 색상을 파란색으로 바꿔주는 건데요.

			// 떨어지는 블럭검사 
			var size=tetrix_block[tetrix_block_number].length;
			for(k=0;k<size;k+=2)
			{
				if(tetrix_block_y+tetrix_block[tetrix_block_number][k]==i
				   && tetrix_block_x+tetrix_block[tetrix_block_number][k+1]==j)
					Context.fillStyle="blue"; 
			}
            :

현재 블록에 해당하는 4쌍(8개)의 좌표와 현재 블럭 박스의 좌표 중 겹치는 부분이 있는지를 검사해서 겹치는 경우 표시할 블럭 색상을 파란색으로 바꿔주게 됩니다.

여기까지 반영된 전체 코드입니다.

<!DOCTYPE html>
<html lang="ko">
<head>
	<meta charset="UTF-8">
	<title>캔바스. 테트리스</title>
</head>
<body>
https://blog.naver.com/ephraimdrlee 
/ 크레이의 세컨드라이프 탐구생활 네이버 블로그<br/>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script>
// 기본 초기화
var init=false;
var myCanvas;
var Context;

var tetrix_blockbox_boxsize=25;
var tetrix_blockbox_top=50;
var tetrix_blockbox_left=280;

// tetrix_blockbox[row][col]; 20행 10열
var tetrix_blockbox;

// 테트리스 블럭박스 초기화
function tetrix_blockbox_init()
{
	// 20행 10열의 박스 생성
	tetrix_blockbox=new Array();
	for(i=0;i<20;++i)
	{
		tetrix_blockbox.push(new Array(10));
		// 모두 0으로 채운다
		for(j=0;j<10;++j)tetrix_blockbox[i][j]=0;
	}
}

// 5가지 타입 블록
var tetrix_block;

// 5가지 블럭 초기화
function tetrix_block_init()
{
	tetrix_block=new Array();

	// 첫번째 블럭
	// □□□□
	tmp=new Array();
	tmp.push(0,0); tmp.push(0,1); tmp.push(0,2); tmp.push(0,3);
	tetrix_block.push(tmp);

	// 두번째 블럭
	// □□□
	//  □
	tmp=new Array();
	tmp.push(0,0); tmp.push(0,1); tmp.push(0,2); tmp.push(1,1);
	tetrix_block.push(tmp);

	// 세번째 블럭
	// □□
	//  □□
	tmp=new Array();
	tmp.push(0,0); tmp.push(0,1); tmp.push(1,1); tmp.push(1,2);
	tetrix_block.push(tmp);

	// 네번째 블럭
	//  □□
	// □□
	tmp=new Array();
	tmp.push(0,1); tmp.push(0,2); tmp.push(1,0); tmp.push(1,1);
	tetrix_block.push(tmp);

	// 다섯번째 블럭
	// □□
	// □□
	tmp=new Array();
	tmp.push(0,0); tmp.push(0,1); tmp.push(1,0); tmp.push(1,1);
	tetrix_block.push(tmp);
}

// 현재 떨어지는 블록번호와 좌표
var tetrix_block_number=1;
var tetrix_block_x=3;
var tetrix_block_y=0;

// 초기화
function Init()
{
	if(init==false)
	{
		myCanvas=document.getElementById("MyCanvas");
		Context=myCanvas.getContext("2d");		
		init=true;
		tetrix_block_init();	// 5가지 블럭 모양 초기화
		tetrix_blockbox_init();	// 블럭상자 초기화
	}
}

function Run()
{
	onDraw();
}

// draw 이벤트
function onDraw()
{
	if(init==false)return;
	// 전체 테두리
	Context.strokeStyle="#000";
	Context.lineWidth=1;
	Context.strokeRect(0, 0, myCanvas.width-1, myCanvas.height-1);
	// 블럭 표시
	for(i=0;i<20;++i)
		for(j=0;j<10;++j)
		{
			if(tetrix_blockbox[i][j]==0)
				Context.fillStyle="#ccc";
			else
				Context.fillStyle="green";
			
			// 떨어지는 블럭검사 
			var size=tetrix_block[tetrix_block_number].length;
			for(k=0;k<size;k+=2)
			{
				if(tetrix_block_y+tetrix_block[tetrix_block_number][k]==i
				   && tetrix_block_x+tetrix_block[tetrix_block_number][k+1]==j)
					Context.fillStyle="blue"; 
			}


			x=tetrix_blockbox_left + j*tetrix_blockbox_boxsize;
			y=tetrix_blockbox_top + i*tetrix_blockbox_boxsize;
			Context.fillRect(x, y, tetrix_blockbox_boxsize-2, tetrix_blockbox_boxsize-2);
		}
}

$(document).ready(function(){
	Init();
	setInterval(Run, 500);

});

</script>

<canvas id="MyCanvas" width=800 height=600>
Canvas is not supported.
</canvas>
허공에 존재하는 블럭 1개 표시
<span id=debug></span>
</body>
</html>

이 코드를 실행하면, 블럭박스 안에 블럭조각이 이렇게 떠 있을 겁니다.

소스에서 블럭 조각 번호를 한번 바꿔 볼까요?

tetrix_block_number 라고 된 곳을 찾아서 뒤의 숫자를 바꿔 보세요.

var tetrix_block_number=3;

아래와 같은 모양으로 바뀌는 것을 확인하실 수 있습니다.

블럭번호를 0~4까지 총 5가지니까 실습해보시면 다양한 모양을 확인해보실 수 있습니다.

여기서 끝내면 아쉬우니까 1가지만 더 해보죠.

바로 블럭 조각이 화면 아래로 떨어지는 부분인데요.

Run() 함수 안에

한줄만 추가해주면 됩니다.

function Run()
{
	tetrix_block_y++;
	onDraw();
}

그리고 페이지를 새로 고침하면,

블럭 조각이 위에서 아래로 떨어집니다

이윽고 바닥에 닿았다가

영영 사라져 버리는 것을 보실 수 있습니다.

불행히도 블럭조각은 저 아래로 한 없이 한 없이 하강 행진을 계속하는 것이지요 :)

블럭조각이 바닥에 쌓이도록 하면 어떻게 해야 할까요?

그건 다음 시간에 살펴보도록 합시다

여기까지 읽어주신 분들께 감사드립니다 :)

오늘 진행된 부분에 대한 예제 페이지는 아래 URL에서 확인하실 수 있습니다.

http://dreamplan7.cafe24.com/canvas/cray06.php

 

캔바스. 테트리스

 

dreamplan7.cafe24.com

시도하시는 모든 분들 성공하시길 바랍니다.
읽어주셔서 감사합니다 :)

 

다음 강좌 보러가기 / https://itadventure.tistory.com/142

 

자바스크립트와 캔버스 7, 테트리스를 만들어봐-3

1. HTML 표준 CANVAS 기술 소개 / https://itadventure.tistory.com/130 2. 자바스크립트와 CANVAS 두번째시간. 캔바스에 눈을 내리자 / https://itadventure.tistory.com/131 3. 자바스크립트와 캔버스 3번째 시..

itadventure.tistory.com