IT/프로젝트

[테트리스4] 블럭 쌓기. 한줄 지우기

안녕하세요. 컴퓨터 못하는 컴퓨터공학생입니다.


이번에는 블럭 쌓기와 한줄 지우기에 대해서 알아보겠습니다.


초기에 board라는 배열을 다음과 같이 지정했습니다.


1
board : array[0..cWIDTH + 10..cHEIGTH + 10..1of integer;
cs


마지막 0..1은 0은 색깔 인덱스, 1은 쌓여있는지의 여부입니다.


블럭을 내리기전 CheckBrick 함수로 체크를 한다고 하였습니다. 블럭이 내려 갈수 없는 상황, 곧 다른 블럭이 쌓여있다면 


1
2
3
4
5
6
7
8
9
10
11
12
13
procedure TFrmMain.CheckLines;
var
  i,j,k : integer;
begin
  for i := 0 to 3 do
  begin
    board[ c_Start_Default_Center  + (iXY div 15) + shape[iBrickIndex][iBrickRotation][i]._iX ]
         [ c_Start_Default_Heigth  + (iDown div 15) + shape[iBrickIndex][iBrickRotation][i]._iY][0] := iBrickIndex;
    board[ c_Start_Default_Center  + (iXY div 15) + shape[iBrickIndex][iBrickRotation][i]._iX ]
         [ c_Start_Default_Heigth  + (iDown div 5) + shape[iBrickIndex][iBrickRotation][i]._iY][1] := 1;
  end;
  ShowStackBrick;
end;
cs



CheckLines 함수로 board배열의 세번째 인덱스의 0값에는 현재 블럭의 모양인덱스 값을, 1 값에는 1이라는 값을 넣습니다.

현재 블럭 모양의 인덱스 순서대로 색깔이 정해져 있기 때문에 블럭 모양 인덱스 값을 넣으면 됩니다.

그리고 1의 값은 블럭이 쌓여 있다는 의미의 값이고, 0은 배경, 2는 가장자리의 벽돌 이라는 뜻입니다.



그리고 ShowStackBrick 함수를 이용하여 쌓여있는 블럭을 그립니다.


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
procedure TFrmMain.ShowStackBrick;
var
  i, j : Integer;
begin
  for i := 0 to cWIDTH + 1 do
  begin
    for j := 0 to cHEIGTH + 1 do
    begin
      if board[i][j][1= 1 then
      begin
        MCanvas.brush.Color := BlockColor[    board[i][j][0]   ] ;
        MCanvas.Pen.Style := psClear;
        MCanvas.Rectangle(i * 15, j * 15,
                        (i+1* 15, (j+1* 15);
      end
      else if board[i][j][1= 0 then
      begin
        MCanvas.brush.Color := clSilver;
        MCanvas.Pen.Style := psClear;
        MCanvas.Rectangle(i * 15, j * 15,
                        (i+1* 15, (j+1* 5);
      end;
    end;
  end;
end;
cs



board배열의 세번째 값이 1이면 블럭이 쌓여있다는 의미이기 때문에 그 블럭을 그립니다. 

board[i][j][0]값에는 블럭 모양의 인덱스 값이 있고, 그 인덱스 값이 색깔의 인덱스 이기 때문에 색을 지정합니다.


board배열의 세번째 값이 0이면 배경이기 때문에 회색으로 그립니다.


간단하게 정리하면 블럭을 쌓아야 한다면 블럭을 쌓는 의미의 값인 board[][][0]에 색깔, board[][][1]에 쌓여있다 라는 값을 넣고

다시 전체 화면을 리플레쉬 합니다.


알고 있는 내용인데도 설명을 하려니 잘 되지 않네요.. 점점 좋아질거라 믿고, 계속 진행하겠습니다.



이제는 한줄 지우기에 대해서 알아보겠습니다.


블럭이 한칸 내려왔을때 벽이거나 블럭이 있다면 DeleteLine 함수를 호출합니다.


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
procedure TFrmMain.DeleteLine;
var
  i, j, k, p : Integer;
begin
  for j := 1 to cHEIGTH + 1 do
  begin
    for k := 1 to cWIDTH + 1 do
    begin
      if board[k][j][1<> 1 then
      Break;
    end;
    if (k = cWIDTH + 1then
    begin
      p := j;
      repeat
        for k := 1 to cWIDTH do
        begin
          board[k][p] := board[k][p-1];
        end;
        p := p - 1;
      until p = 1;
      Sleep(50);
      ShowStackBrick;
    end;
  end;
end;
cs


위에서 한줄씩 체크하면서 아래로 내려옵니다.

만약 한줄씩 체크하는데 벽돌이 아닌 부분if board[k][j][1] <> 1 then이 있다면 한줄을 건너뜁니다.

만약 한줄이 전부다 블럭이 채워져 있다면, 그러니까 for k := 1 to cWIDTH + 1 do 루프를 끝까지 돌았는데 

Break가 안걸려 있다면 (if (k = cWIDTH + 1) then) 이 성립하게 되고

왼쪽부터 오른쪽으로 차례대로 위의 블럭을 아래로 내립니다.




Sleep(50)의 이유는 블럭이 지워지는것이 눈에 보이도록 추가하였습니다.

그리고 ShowStackBrick 함수를 호출하여 지워진 상태로 출력을 합니다.


하나하나 보다보면 이해가 될거라 생각됩니다.


궁금한점 있으시면 댓글로..


감사합니다.




  

,

최근 댓글

최근 트랙백

알림

이 블로그는 구글에서 제공한 크롬에 최적화 되어있고, 네이버에서 제공한 나눔글꼴이 적용되어 있습니다.

링크

카운터

Today :
Yesterday :
Total :