[TetrisView 클래스의 Class Diagram]


이제는, 테트리스의 UI 를 담당하는 클래스인 TetrisView 에 대해서 말씀드릴 차례입니다. TetrisView.h 와 TetrisView.c 를 분석해 보겠습니다.


[TetrisView.h]

#ifndef _TETRIS_VIEW_H
#define _TETRIS_VIEW_H

#include "TetrisManager.h"

typedef struct _tetrisView{
	TetrisManager tetrisManager;
}TetrisView;

void TetrisView_StartGame(TetrisView* tetrisView);
void TetrisView_ProcessGame(TetrisView* tetrisView, int processType, int direction);
void TetrisView_EndGame(TetrisView* tetrisView);

#endif


1 ~ 2, 14 라인

이 헤더파일을 include 하는 곳들에서 중복 포함 하지 않게 하기 위한 guard 입니다.


6 ~ 8 라인

TetrisView 구조체의 정의부입니다. 멤버로는 tetrisManager 를 가지고 있습니다.


10 ~ 12 라인

TetrisView.c 에서 정의될 함수들의 선언부입니다.


[TetrisView.c]

#include <stdio.h>
#include <windows.h>
#include <mmsystem.h>
#include "TetrisView.h"
#include "TetrisManager.h"
#include "Constant.h"

#pragma comment(lib, "winmm.lib")

#define TETRIS_BACKGROUND_MUSIC_FILE_NAME "..\\res\\tetris_background_music.wav"

void TetrisView_StartGame(TetrisView* tetrisView){
	int speedLevel;
	PlaySound(TEXT(TETRIS_BACKGROUND_MUSIC_FILE_NAME), NULL, SND_ASYNC | SND_LOOP);
	printf("***** Tetris *****\nSpeed level (1 ~ 10) : ");
	scanf_s("%d", &speedLevel);
	if (speedLevel > MAX_SPEED_LEVEL || speedLevel < MIN_SPEED_LEVEL){
		speedLevel = MIN_SPEED_LEVEL;
	}
	TetrisManager_Init(&tetrisView->tetrisManager, speedLevel);
	TetrisManager_Print(&tetrisView->tetrisManager);
}

void TetrisView_ProcessGame(TetrisView* tetrisView, int processType, int direction){
	if (processType == DIRECTION){
		TetrisManager_ChangeBoardByDirection(&tetrisView->tetrisManager, direction);
	}
	else if (processType == DIRECT_DOWN){
		TetrisManager_ProcessDirectDown(&tetrisView->tetrisManager);
	}
	else if (processType == AUTO){
		TetrisManager_ChangeBoardByAuto(&tetrisView->tetrisManager);
	}
	if (TetrisManager_IsReachedToBottom(&tetrisView->tetrisManager)){
		//if you are going to move the block which has bottom wall or bottom fixed block, permit the block to move the direction
		if (processType == DIRECTION && direction == LEFT && (TetrisManager_CheckValidPosition(&tetrisView->tetrisManager, LEFT) == EMPTY) || 
			processType == DIRECTION && direction == RIGHT && (TetrisManager_CheckValidPosition(&tetrisView->tetrisManager, RIGHT) == EMPTY)){
			TetrisManager_ChangeBoardByDirection(&tetrisView->tetrisManager, direction);
		}
		if (TetrisManager_ProcessReachedCase(&tetrisView->tetrisManager) == END){
			TetrisView_EndGame(tetrisView);
		}
	}
	TetrisManager_ProcessDeletingLines(&tetrisView->tetrisManager);
	TetrisManager_Print(&tetrisView->tetrisManager);
	if (processType == AUTO){
		TetrisManager_Sleep(&tetrisView->tetrisManager);
	}
}

void TetrisView_EndGame(TetrisView* tetrisView){
	PlaySound(NULL, 0, 0);
	system("cls");
	printf("***** End *****\n%d level / %d lines deleted\n",
		tetrisView->tetrisManager.speedLevel,
		tetrisView->tetrisManager.deletedLineCount);
	system("pause");
	exit(-1);
}


1 ~ 6 라인

현재 소스 파일에서 필요한 헤더파일들을 include 합니다.


8 라인

소리 및 음악 재생을 위해서 winmm.lib 라이브러리를 로드합니다.


10 라인

테트리스 배경 음악 파일명을 상수화 합니다. (상대 경로 포함)


12 라인

TetrisView_StartGame 함수의 정의부입니다. 매개변수로 tetrisView 를 받아서, 테트리스 게임을 시작하기 위한 설정을 하고, 시작을 하는 역할을 합니다.


14 라인

PlaySound 함수를 호출하여 테트리스 배경음악을 재생합니다.

(소리 및 음악 재생하기 - WinApi 참고)

http://kkikkodev.tistory.com/54


16 ~ 19 라인

사용자로부터 원하는 시작 speedLevel 을 입력받은 뒤, 그 speedLevel 이 유효하지 않으면 (MAX_SPEED_LEVEL (= 10) 보다 크거나, MIIN_SPEED_LEVEL (= 1) 보다 작은 경우) speedLevel 에 임의로 MIN_SPEED_LEVEL 로 설정합니다.


20 라인

TetrisManager_Init 함수를 호출하여, tetrisView->tetrisManager 변수를 초기화합니다. 


21 라인

TetrisManager_Print 함수를 호출하여 테트리스 판, 블럭, 게임 상태 등을 화면에 출력합니다.


24 라인

TetrisView_ProcessGame 함수의 정의부입니다. 매개변수로, tetrisView 와 processType (사용자가 방향키를 눌렀는지, 스페이스바를 눌렀는지, 자동으로 내려오는지를 구분하는 변수), direction (방향) 을 전달받아서, 실제 테트리스 게임을 진행합니다.


25 ~ 33 라인

크게, processType 을 확인하여, DIRECTION (방향키를 누른 경우), DIRECT_DOWN (스페이스바를 누른 경우), AUTO (자동으로 내려오는 경우) 의 3 가지 경우로 구분하여 게임을 진행합니다. 먼저, processType 이 DIRECTION 인 경우는, TetrisManager_ChangeBoardByDirection 함수를 호출하여, 블럭의 방향을 업데이트 해 준뒤, 화면을 갱신합니다. 두 번째로, processType 이 DIRECT_DOWN 인 경우에는, TetrisManager_ProcessDirectDown 함수를 호출하여 현재 블럭이 내려갈 수 있을 때까지 내리고, 화면을 갱신합니다. 마지막으로, processType 이 AUTO 인 경우는, TetrisManager_ChangeBoardByAuto 함수를 호출하여 한 칸 밑으로 블럭을 내린 뒤 화면을 갱신합니다. 


34 ~ 43 라인

TetrisManager_IsReachedToBottom 함수를 호출하여 현재 블럭이 바닥에 닿았는지를 체크합니다. (바닥은, 아래 벽 말고도, 굳어진 블럭도 포함합니다.) 만약 바닥에 닿았으면, 먼저, 사용자가 좌우키를 눌렀는지 확인하여, 그 방향이 비었는지 확인합니다. (즉. 블럭이 바닥에 닿기는 했찌만, 좌우로 한번더 이동 가능한 경우를 말합니다.) 이것은, 사용자가 LEFT 방향을 원했을 때, 블럭의 왼쪽이 빈 경우와 사용자가 RIGHT 방향을 원했을 때, 블럭의 오른쪽이 빈 경우를 말합니다. 왼쪽이나 오른쪽이 비었는지는 TetrisManager_CheckValidPosition 함수를 호출하여 체크합니다. 만약 이 두 가지 경우중 하나에 해당된다면, TetrisManager_ChanageBoardByDirection 함수를 호출하여 사용자가 원하는 방향으로 블럭을 이동하게 합니다. 


그리고 나서, TetrisManager_ProcessReachedCase 함수를 호출하여 현재 블럭이 바닥에 닿은 경우의 처리를 합니다. 추가적으로, 이 함수의 반환값을 확인하여 END 인 경우에 TetrisView_EndGame 을 호출하여 테트리스 게임을 종료합니다.


44 라인

TetrisManageR_ProcessDeletingLines 함수를 호출하여 굳어진 블럭들이 한 줄을 이뤘을 경우를 처리합니다.


45 라인

TetrisManager_Print 함수를 호출하여 게임 화면을 갱신합니다.


46 ~ 48 라인

processType 이 AUTO 인 경우에는, TetrisManager_Sleep 함수를 호출하여 speedLevel 에 기반한 일정 시간동안 게임을 지연시킵니다.


51 라인

TetrisView_EndGame 함수의 정의부입니다. 매개변수로 tetrisView 를 받아서, 테트리스 게임을 종료합니다.


52 라인

PlaySound 함수를 호출하여 테트리스 배경 음악 재생을 정지합니다.


53 라인

system("cls") 함수를 호출하여 화면을 지웁니다.

(콘솔 화면 지우기 참고)

http://kkikkodev.tistory.com/64


54 ~ 56 라인

게임의 현재 속도 레벨과 총 지운 라인의 개수를 출력합니다.


57 라인

system("pause") 함수를 호출하여 콘솔이 바로 닫히지 않도록 프로그램을 일시정지합니다. (사용자가 키 입력을 해야 다음을 실행합니다.)


58 라인

exit(-1) 함수를 호출하여 프로그램을 종료합니다.

(프로그램 강제로 종료시키기 참고)

http://kkikkodev.tistory.com/65


by kkikkodev 2015. 6. 12. 11:24