'IT/프로젝트'에 해당되는 글 5건

IT/프로젝트

[테트리스5] 테트리스 소스

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


델파이를 사용하여 만든 테트리스 소스를 깃허브에 올리고 깃허브 주소를 공유하려 합니다.


사실 소스를 공유한다는것 자체가 뭔가 평가 받는 느낌이 들고 ,

점수매겨지는 느낌이 들고, 

쪽팔려서 공개를 안하고 싶지만..


공개를 함으로써 저나 보는 사람 둘다 도움이 됬으면 하는 바람으로 올립니다.


https://github.com/ljh3326/tetris.git


사실 원하는 기능을 다 구현하지 못하여서 조금더 수정을 할겁니다.



감사합니다.

,
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 함수를 호출하여 지워진 상태로 출력을 합니다.


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


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


감사합니다.




  

,
IT/프로젝트

[테트리스3] 블럭 변경하기

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


이번에는 블럭 변경하는 법을 보도록 하겠습니다.


사실 블럭 변경하는 법은 간단합니다. 

1. 블럭을 변경할 수 있는 공간이 있는지 체크를 하고 

2. 블럭을 지운 뒤

3. 블럭모양의 인덱스 값을 바꾼 뒤 다시 블럭을 그려주면 됩니다.


BrickChange 함수를 선언해서 사용하겠습니다.



1
2
3
4
5
6
7
8
9
10
11
12
procedure TFrmMain.BrickChange;
begin
  if CheckBrick(iXY, iDown) then
  begin
    PrintBrick(false);
    if iBrickRotation = 3 then
      iBrickRotation := 0
    else
      inc(iBrickRotation);
    PrintBrick(True);
  end;
end;
cs



함수안에는 CheckBrick 함수를 사용합니다.

CheckBrick(iXY, iDown) 와 같이 호출 하여서 변경이 가능한지 유무를 확인합니다.

iXY는 현재 가로위치이고, iDown은 현재 세로위치입니다.


주위에 블록이나 벽인지 체크를 한 뒤 가능하면 블럭을 없애고, 블럭모양의 index인 iBrickRotation를 증가하고,

iBrickRotation에 맞는 블럭을 그립니다.


printBrick함수는 다음과 같습니다.


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
27
28
29
30
31
32
33
34
35
36
37
procedure TFrmMain.PrintBrick(bShow : Boolean);
var
  i : integer;
begin
   if (bShow) then
   begin
     for i := 0 to 3 do
     begin
       MCanvas.brush.Color := BlockColor[iBrickIndex];
       MCanvas.Pen.Style := psClear;
       MCanvas.Rectangle( (shape[iBrickIndex][iBrickRotation][i]._iX * 15) + iXY + ( 15* 5 ),
                         (shape[iBrickIndex][iBrickRotation][i]._iY * 15) + iDown + 15,
                         (shape[iBrickIndex][iBrickRotation][i]._iX * 15) + 15+ iXY + ( 15* 5),
                         (shape[iBrickIndex][iBrickRotation][i]._iY * 15) + iDown + 15+ 5
                       );
     end;
   end
   else
   begin
     for i := 0 to 3 do
     begin
       MCanvas.brush.Color := clSilver;
       MCanvas.Pen.Style := psClear;
       MCanvas.Rectangle( (shape[iBrickIndex][iBrickRotation][i]._iX * 15) + iXY + ( 15* 5),
                         (shape[iBrickIndex][iBrickRotation][i]._iY * 15) + iDown + 15,
                         (shape[iBrickIndex][iBrickRotation][i]._iX * 15) + 15 + iXY + ( 15* 5),
                         (shape[iBrickIndex][iBrickRotation][i]._iY * 15) + iDown + 15+ cBrickSize
                       );
     end;
   end;
end;
cs



저번시간에 사용했던 함수를 하나로 묶은 것입니다.


다음 시간에는 블럭쌓기와 블럭 한줄 없애기에 대해서 살펴보겠습니다.


감사합니다.

,
IT/프로젝트

[테트리스2] 블럭 그리기, 블럭 내리기

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

이번 시간에는 배경에 블록을 그리고 블록이 내려오는 기능에 대해 살펴보려 합니다.


블록은 총 7가지 종류가 있습니다.


위의 그림처럼 블럭 모양 및 색을 사용하겠습니다.


위의 블록을 배열에 미리 저장하여 사용합니다. 저는 TPoint 3차원 배열을 선언해서 사용하였습니다.

TPoint는 다음과 같이

1
2
3
4
5
6
type
  TPoint = record
    _iX : integer;
    _iY : integer;
  end;
cs

정의 하였습니다.


_iX _iY는 각각 x,y좌표를 나타냅니다.

 

각각의 블록은 미리 배열에 저장해 두겠습니다.


1
2
3
4
5
6
7
8
9
10
11
shape : array[0..6, 0..3, 0..3] of TPoint =
  (
     (
         ( (_iX : 0; _iY : 0), (_iX : 0; _iY : 1), (_iX : 0; _iY : 2), (_iX : 1; _iY : 2) ), // L
         ( (_iX : 2; _iY : 0), (_iX : 2; _iY : 1), (_iX : 1; _iY : 1), (_iX : 0; _iY : 1) ),
         ( (_iX : 0; _iY : 0), (_iX : 1; _iY : 0), (_iX : 1; _iY : 1), (_iX : 1; _iY : 2) ),
         ( (_iX : 0; _iY : 0), (_iX : 0; _iY : 1), (_iX : 1; _iY : 0), (_iX : 2; _iY : 0) )
     ),
     //생략
  );
cs



위는 L자 모양의 블록을 정의한 내용입니다.

변경했을 때의 블록 모양도 정의하여 총 4개로 정의하였습니다.


블록을 그리기 위해 블록 색깔을 정해둡니다.


1
2
  BlockColor : array [0..8of TColor = ($00A5FF, $E96AE9, $09D9D9, $D9D909, 
                                       $FF5900, $09D909, $4949EE, clBlack, clSilver );
cs


델파이는 RGB가 아닌 BGR로 하기 때문에 $00A5FF는 L자 블록 모양의 색인 주황색 입니다.


블록을 그릴때는 다음과 같이 함수를 사용합니다.


1
2
3
4
5
6
7
8
9
10
11
     for i := 0 to 3 do
     begin
      MCanvas.brush.Color := BlockColor[iBrickIndex];
      MCanvas.Pen.Style := psClear;
      MCanvas.Rectangle( (shape[iBrickIndex][iBrickRotation][i]._iX * 15+ iXY + ( 15 * 5 ),
                         (shape[iBrickIndex][iBrickRotation][i]._iY * 15+ iDown + 15,
                         (shape[iBrickIndex][iBrickRotation][i]._iX * 15+ 15 + iXY + ( 15 * 5 ),
                         (shape[iBrickIndex][iBrickRotation][i]._iY * 15+ iDown + 15 + 15
                       );
     end;
cs


iBrickIndex 값은 이 함수 실행전 어떤 블록을 선택할건지의 인덱스 값입니다.

iBrickRotation 변수는 초기에 어떤모양의 블록을 내릴건지의 인덱스 값입니다

15는 블록한칸의 가로, 세로 길이입니다.

 

iXY 변수는 현재 블록의 가로 좌표 위치를 나타냅니다. 초기값은 0입니다.

(15*5)15는 블록의 한변의 길이이고, 5는 총 가로길이의 중간을 나타냅니다.

초기 시작시에 블록이 중간에서 내려오기 위해서입니다.

 

iDown 변수는 세로 좌표 위치를 나타냅니다. 초기값은 0입니다.

 

정리하자면 중간에 블록 4개 그리는 함수입니다.

 

글이 많아서 설명이 어려울 수 있는데 댓글로 남겨주세요.

 

블록을 한칸 내리기 위해서는 블록 바로 아래에 벽이 있는지, 다른 블록이 쌓여있는지 확인을 해봐야 합니다.

확인하는 함수는 다음과 같이 사용합니다.

CheckBrick(iXY, iDown+15)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function TFrmMain.CheckBrick(x,y : integer) : Boolean;
var
  i, j : integer;
begin
  j := 0;
  for i := 0 to 3 do
  begin
    j := max( j,
            board[ 5 + (x div 15+ shape[iBrickIndex][iBrickRotation][i]._iX ]
                 [ 1 + (y div 15+ shape[iBrickIndex][iBrickRotation][i]._iY ]
                 [ 1 ]
            );
  end;
  // 벽돌이나 가장자리이면
  if (j = 1) or (j = 2then
    result := False
  else
    result := True;
end;
cs

여기서 x의 값은 가로에서 어느 위치인지를 나타냅니다.

y는 세로에서 어느 위치인지를 나타냅니다.

 

board배열 첫 번째에 5를 더하는 이유는 블록의 시작이 왼쪽 위가 아닌 중간에서 시작하기 때문입니다.

중간의 위치는 총 10의 길이에서 반인 5입니다.

board배열 첫 번째에 1을 더하는 이유는 제일 위에 블록이 벽이기 때문에 한칸 밑부터 시작하려고 1을 더합니다.

나누기 15를 하는 이유는 x의 값은 블록의 가로/세로 길이이기 때문에 15로 나누어서 상대적인 위치를 가져옵니다.


CheckBrick(iXY, iDown+15) 다음과 같이 함수를 실행합니다. iXY, iDown는 현재 가로세로의 위치를 나타냅니다.


이제 블럭을 한칸씩 내려보겠습니다.

블럭을 내리기 위해서는 기존의 블럭을 지우고, 바로 한칸 아래에 블럭을 그려야 합니다.

1
2
3
4
5
6
7
8
9
10
     for i := 0 to 3 do
     begin
       MCanvas.brush.Color := clSilver;
       MCanvas.Pen.Style := psClear;
       MCanvas.Rectangle( (shape[iBrickIndex][iBrickRotation][i]._iX * 15) + iXY + ( 15* 5 ),
                         (shape[iBrickIndex][iBrickRotation][i]._iY * 15) + iDown + 15,
                         (shape[iBrickIndex][iBrickRotation][i]._iX * 15) + 15+ iXY + ( 5* 5),
                         (shape[iBrickIndex][iBrickRotation][i]._iY * 15) + iDown + 5+ 15
                       );
     end;
cs



지우는 방식은 현재 블럭의 위치를 벽색깔인 회색으로 덮어 씌웁니다. Color만 다르고 위의 함수와 동일하기 때문에 설명은 생략하겠습니다.


그리고 iDown의 변수를 +15(블록 크기) 한 뒤 다시 위의 함수를 호출하면 한칸 아래로 내려온것 처럼 보입니다.


간단하게 정리하자면 초기에는 블록을 그리기 전에 바로 밑에 블록인지 체크 한 뒤 블록을 그립니다.

그릴수 있다면 블록을 그리고 그릴수 없다면 블록이 초기상태까지 쌓였기 때문에 게임 종료입니다.


초기가 아니라면 블록을 그리고 블록을 한칸 내리기 위해 다시한번더 밑에 블록이 있는지 체크를 합니다.

없다면 블록을 내리고 있다면 블록을 쌓습니다.


정리하거나 표현하는게 서툴러 이해가 되지 않을 수도 있지만, 일단 저는 알고 보니 이해가 되서..


다음에는 블록 변경하는거에 대해서 살펴보겠습니다.


감사합니다.

,
IT/프로젝트

[테트리스1] 개요, 설계, 화면구성

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

델파이를 사용하여 테트리스 게임을 만들어보려 합니다.

 

첫 번째로 화면 구성 및 설계를 하려 합니다.

아래 플로우차트와 같이 테트리스의 전체적인 흐름이 흘러갑니다.

미리 설계를 해놓고 코드를 짜게되면 수월하게 코드를 짤 수 있습니다.




두 번째로 화면을 구성해보려 합니다

아래 그림과 같이 게임 진행화면, 다음블럭표시 화면, 점수 표시화면으로 크게 3가지로 나누려 합니다.



세 번째로 테트리스 진행 화면에서 배경을 그려보려 합니다

배경의 크기는 벽을 포함해서 가로 12, 세로 22인 직사각형으로 합니다

그리고 벽의 색은 하늘색으로 설정합니다




이 벽돌을 board라는 3차원 배열로 선언하겠습니다.


1
board : array[0..110..210..1of integer;      // 0..2 0은 색 index, 1은 쌓여있는지 여부
cs


여기서 0..11은 총 12길이의 가로길이,

0..21은 총 22길이의 세로길이,

0..1은 첫 번째 [0]은 색깔 index, [1]은 블록 쌓여있는지 아닌지 여부를 나타냅니다.



board 3차원 배열을 다음과 같이 초기화 합니다

끝 벽쪽은 2라는 임의값을 넣고 나머지는 0이라는 임의의 값을 넣습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
begin
  // 벽부분 board배열에 2넣기.
  for i := 0 to 11 do
  begin
    for j := 0 to 21 do            
    begin
      if (j = 0) or (j = 21) or (i = 0) or (i = 11then
        board[i][j][1] := 2
      else
      begin
        board[i][j][0] := 0;
        board[i][j][1] := 0;
      end;
    end;
  end;
end;
cs



그리고 canvas를 이용하여 네모를 그립니다



1
2
3
4
5
6
7
8
9
10
11
12
13
14
  for i := 0 to 11 do
  begin         
    for j := 0 to 21 do
    begin
      if board[i][j][1= 2 then
        BackColor := $E7D2A5 // 하늘색(BGR)
      else
        BackColor := clSilver; // 회색
      MCanvas.brush.Color :=  BackColor;
      MCanvas.Pen.Style := psClear;
      MCanvas.Rectangle(i * cBrickSize, j * cBrickSize,
                      (i+1* cBrickSize, (j+1* cBrickSize);
    end;
  end;
cs



여기서 cBrickSize15입니다. 한변이 15인 정사각형을 그립니다.

왼쪽 위부터 오른쪽으로 가면서 정사각형을 그리고 다음줄로 내려와 다시 왼쪽부터 차례대로 정사각형을 그립니다.

다 그리면 다음 그림과 같이 테트리스 배경이 완성됩니다.





오늘은 여기까지 하겠습니다.

다음엔 블럭을 그리고 내려오는 기능에 대해 구현해보도록 하겠습니다.


감사합니다.





,

최근 댓글

최근 트랙백

알림

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

링크

카운터

Today :
Yesterday :
Total :