19개의 테트리스 모양 * * *이 있습니다. 이를 배열로 표현하는 것은 공간 낭비일 수 있습니다(웹에는 많은 구현 코드가 있습니다).
각 사각형 모양이 4 * 4 범위의 작은 사각형이라는 점을 고려하여 글꼴 점 행렬, 즉 4 행과 4 열의 배열로 저장되며 요소는 이 위치가 작다는 것을 나타내는 1로 설정됩니다.
상자, 요소는 0으로 설정되어 이 위치에 작은 상자가 없음을 나타냅니다. 이 전체 4*4 배열이 테트리스 모양을 형성하죠?
1000?
1000?
1100?
0000?
위의 4*4는 L자형 정사각형을 나타냅니다.
4*4 = 16비트는 짧은 타입이므로 각 블록은 짧은 타입의 데이터로 표현할 수 있습니다.
우리는 테트리스 점의 수를 락어레이에 저장하고, 이 19개의 정사각형의 글꼴 점을 16진수로 미리 변환한 다음 락어레이를 초기화할 때 할당할 수 있습니다.
그러나 이 방법은 확장할 수 없으며 새 사각형이 나타날 때마다 변경해야 합니다.
그렇다면 19가지 유형의 사각형을 나타내는 구성 파일을 작성할 수 있습니다. (RockShape.ini)
@###@###@@@######1234
설정 파일에서 블록 유형을 읽어오는 코드는 아래 3에 설명되어 있습니다(Init.h의 ReadRock 함수에서).
2정사각형은 어떻게 그리나요?
EasyX 라이브러리를 사용하여 간단한 도형을 그릴 수 있습니다.
EasyX 라이브러리는 VC에서 TC 간단한 그리기 기능을 구현하는 라이브러리로, 배우기 쉽습니다(직접 바이두 EasyX 라이브러리, 자세한 튜토리얼이 있습니다).
단순한 형태로 저장된 상자를 그리는 방법은 무엇일까요?
숏에서 읽으면 마스크 마스크 = 1을 사용하여 숏의 각 비트로 위상을 지정하고 결과가 1이면 작은 사각형; 을 그릴 수 있습니다.
함수 선언:
void DisplayRock(int rockIdx, ?RockLocation_t* ?LocatePtr, bool displayed)1
파라미터 1: 배열의 첨자를 나타내고, 데이터를 나타내기 위해 짧은 유형의 상자를 꺼낼까요?
파라미터 2: 현재 좌표, 즉 상자의 왼쪽 상단 모서리의 좌표 x, y를 나타냅니다.
파라미터 3: 참이면 상자를 그리고, 거짓이면 상자를 지웁니다.
// 그래픽 창에서 상자의 위치(즉, 4*4 블록의 왼쪽 상단 모서리 좌표 찾기)
{ int leftint top
} rock location _ t; 123456
3같은 유형의 상자를 뒤집는 방법
↑를 누르면 다음을 수행해야 합니다. 같은 유형의 상자를 뒤집습니다.
예를 들어 아래쪽 가로 막대와 세로 막대입니다.
@###@##################@@@@############****1234567891011
이렇게 구현된 정적 순환 링크 테이블을 상상할 수 있을까요?
동일한 타입의 블록을 반복하고,
사각형은 구조체로 표현됩니다.
Typedef 구조체 록
{// 상자 모양을 나타내는 데 사용됩니다(바이트당 8비트, 4비트마다 상자 안의 행을 나타냄).
부호 없는 짧은 rockShapeBitsint?nextRockIndex?//다음 상자, 배열 내 첨자?} RockType123456
19가지 유형의 상자를 저장하기 위해 RockType 유형의 배열을 정의하시겠습니까?
rock type rock array[19]= {(0, 0)};
"↑"를 누르면 들어오는 드로잉 박스 함수의 rockIndex를 현재 박스 구조의 nextRockIndex로 변경할 수 있습니다.
ReadRock 함수의 구현을 간단히 설명하면, 빈 줄을 읽으면 상자를 읽었음을 의미하고, * * *? 줄을 읽을 때는 코드 구현 및 코드의 특정 주석에 따라 동일한 유형의 상자를 읽었음을 의미합니다.
4. 메인 게임 구현 로직
왜 티저를 게시하지 않나요?
주: 위에서 미리 본 게임 컨트롤 영역과 게임 표시 영역은 Draw.h의 DrawGameWindow() 함수로 구현됩니다
(1) 초기 위치에 사각형을 그리고 미리보기 영역에 다음 사각형을 그리는가?
(2) 상자에는 두 가지 동작이 있습니다: 키보드 명령 UserHitKeyBoard()에 반응하는 것과 자유 낙하?
키보드(w, a, s, d,)를 누르면 공백은 일시 중지를 나타냅니다. 할당된 시간 내에 키보드를 누르지 않으면 상자가 한 단위 자유 낙하합니다.
If (kbhit()) // 키보드를 누르면 키 입력을 처리합니다.
{
user hit = getch();
사용자가 키보드를 쳤다면 (user hit & ampcurRockIndex & amp; curRockLocation);
}/// 그렇지 않으면 자동으로 한 단위 아래로 떨어집니다:else는 키가 위, 아래, 왼쪽, 오른쪽이 아닐 수 있기 때문에 작동하지 않습니다.
DWORD new time = GetTickCount(); if(new time-old time & gt; = (부호 없는 정수)(300)amp; & ampmoveAbled == TRUE)
{
oldtime = newtime
display rock(curRockIndex & amp; curRockLocation, false);
currocklocation . top+= ROCK _ SQUARE _ WIDTH;//delete a grid
}1234567891011121314
(3) 사각형이 바닥에 떨어지면(즉, 아래로 이동할 수 없으면) 가득 차 있는지 판단하고 가득 차면 제거한 다음 게임 종료 여부를 판단합니다. 게임이 끝났다면 바로 게임을 종료합니다.
풀라인 판정: fullline() 함수를 사용하면 빈 줄이 나올 때까지 맨 아래 줄부터 판정을 시작합니다.
그리고 (숫자! = xROCK_SQUARE_NUM) // 빈 줄 14를 만납니다.
{
linefull = truecount = 0; for(int I = 1; I& lt= xROCK _ SQUARE _ NUM++i)
{ if (game_board[idx][i] ==? 0)
{
linefull = falsecount++;
}
} if (linefull) // 전체 라인, 현재 라인 제거, 점수 업데이트.
{
DelCurLine(idx); //전체 라인 제거
game _ socres+= 3;
update socres(game _ socres);
idx++; //다음은 1씩 감소하기 때문입니다.
}
idx-;
}123456789101112131415161718192021
(4) 전체 줄을 제거하시겠습니까?
삭제할 줄 전체를 지우시겠습니까(예: 배경과 같은 색, 코드 검정색으로 블록?)?
그런 다음 맨 위 줄을 아래로 이동하여 빈 줄이 생길 때까지 한 줄을 이동하고 다른 줄을 삭제할까요?
구현은 game.h 코드를 참조하세요?
void DelCurLine(int rowIdx)
(4) 상자를 이동할 수 있는지 확인하려면?
게임.h에 구현
bool MoveAble(int rockIndex, rock location _ t * currentlocatoptr, int f_direction)1
* * 현재 위치(왼쪽 상단 모서리)의 좌표를 비교하여 rockIndex 상자에 넣을까요?
주: f_direction이 ↑인 경우, 전달된 rockIndex는 다음 상자가 됩니다 * *.
이동할 수 없는 경우 게임보드에 플래그를 설정하여 해당 위치가 점유되었음을 나타냅니다.
// 전역 변수 - 게임보드의 상태에 대한 설명(즉, 현재 인터페이스에서 사각형이 있는 위치를 나타냄)? // 0은 아니오, 1은 예(상자를 옮길 수 있는지 쉽게 판단할 수 있도록 두 개의 행과 열이 추가되어 울타리를 형성함)? int game _ board[yROCK _ SQUARE _ NUM+2][xROCK _ SQUARE _ NUM+2] = { 0 }; 123
(1) 구현 중 발생한 몇 가지 문제
(2) 간단히 살펴봅시다. 낙하 시 상자가 펜스 범위 밖으로 떨어질 수 있습니다.
빠른 낙하란 상자가 한 번에 2단위 거리를 떨어뜨리는 것을 말합니다.
(2) 떨어질 수 없다고 판단할 때는 현재 좌표의 상단에서 거리의 한 단위인 Y를 뺍니다.
(3) 폴리라인이 꽉 차면 제거할 수 없습니다.
가득 찬 선을 판단할 때는 가득 찬 선을 찾기 위해 루프하고, 하나를 찾은 후 한 줄을 더 제거한 다음 빈 선을 만날 때까지 계속 가득 찼는지 여부를 판단합니다.