|
#ifndef _GAME_H_ #define _GAME_H_ #define DIRECTINPUT_VERSION 0x0700 // 우리는 DirectInput7버전을 사용할 것이다. #include "Common.h" #include "ddraw.h" #include "dinput.h" #define RLimit ClientRect.right-lstrlen(str)*8 #define BLimit ClientRect.bottom-15 #define Movement 5 // 이동량. #define DIKEYDOWN(data, n) (data[n] & 0x80) #define DILBUTTON(State) (State.rgbButtons[0] & 0x80) // 마우스 왼쪽 버튼 클릭. #define DIRBUTTON(State) (State.rgbButtons[1] & 0x80) // 마우스 오른쪽 버튼 클릭. #define DIMBUTTON(State) (State.rgbButtons[2] & 0x80) // 마우스 가운데 버튼 클릭. class CGame { private: HDC hDC; HWND hWnd; HINSTANCE hInst; bool bPause; // 현재 게임이 정지 상태인지의 여부. LPDIRECTDRAW7 lpdd; BYTE KeyState[256]; DIMOUSESTATE MouseState; LPDIRECTINPUT lpdi; LPDIRECTINPUTDEVICE lpdiKbd; LPDIRECTINPUTDEVICE lpdiMouse; char str[50]; POINT pt; // 클라이언트의 화면 좌표. RECT ClientRect; // 클라이언트 렉트. COORD Text; // 문자열의 좌표. COORD PreText; // 문자열의 이전 좌표. DDSURFACEDESC2 ddsd; LPDIRECTDRAWSURFACE7 lpddSPrimary; // Primary Surface. public: int Init(HWND m_hWnd, HINSTANCE m_hInst); // 게임 초기화. int Main(); // 게임 메인. int Shutdown(); // 게임 종료. int GetClientPos(); // 클라이언트 영역의 화면 위치를 얻어온다. int SetAcquire(); int GetInput(); // 키 입력을 받는다. }; #endif // end of ifndef _GAME_H. |
* Game.cpp
#include "Game.h" int CGame::GetClientPos() { pt.x = 0; pt.y = 0; ClientToScreen(hWnd, &pt); // 클라이언트 영역의 화면 좌표를 구해온다. GetClientRect(hWnd, &ClientRect); // 클라이언트 렉트를 구한다. return 0; } int CGame::Init(HWND m_hWnd, HINSTANCE m_hInst) { hWnd = m_hWnd; hInst = m_hInst; // DirectDraw 객체 생성. if( FAILED(DirectDrawCreateEx(NULL, (LPVOID*)&lpdd, IID_IDirectDraw7, NULL)) ) return ERR; if( FAILED(lpdd->SetCooperativeLevel(hWnd, DDSCL_NORMAL)) ) return ERR; // 프라이머리 서페이스 생성. memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; if( FAILED(lpdd->CreateSurface(&ddsd, &lpddSPrimary, NULL)) ) return ERR; // DirectInput 객체 생성. if( FAILED(DirectInputCreate(hInst, DIRECTINPUT_VERSION, &lpdi, NULL)) ) return ERR; // 키보드 인풋 세팅. if( FAILED(lpdi->CreateDevice(GUID_SysKeyboard, &lpdiKbd, NULL)) ) return ERR; if( FAILED(lpdiKbd->SetDataFormat(&c_dfDIKeyboard)) ) return ERR; if( FAILED(lpdiKbd->SetCooperativeLevel(hWnd, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND)) ) return ERR; // 마우스 인풋 세팅. if( FAILED(lpdi->CreateDevice(GUID_SysMouse, &lpdiMouse, NULL)) ) return ERR; if( FAILED(lpdiMouse->SetDataFormat(&c_dfDIMouse)) ) return ERR; if( FAILED(lpdiMouse->SetCooperativeLevel(hWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND)) ) return ERR; bPause = false; if( SetAcquire() == ERR) return ERR; lstrcpy(str, "메롱"); Text.X = 0; Text.Y = 0; PreText.X = 1; PreText.Y = 1; GetClientPos(); // 클라이언트의 화면상 위치를 구한다. return 0; } int CGame::SetAcquire() { if( bPause ) { if( FAILED(lpdiKbd->Unacquire()) ) return ERR; if( FAILED(lpdiMouse->Unacquire()) ) return ERR; } else { if( FAILED(lpdiKbd->Acquire()) ) return ERR; if( FAILED(lpdiMouse->Acquire()) ) return ERR; } return 0; } int CGame::GetInput() { // 키보드에서 데이터 읽어오기. if( FAILED(lpdiKbd->GetDeviceState(sizeof(KeyState), (LPVOID)KeyState)) ) return ERR; // 마우스에서 데이터 읽어오기. if( FAILED(lpdiMouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)MouseState)) ) return ERR; if( DIKEYDOWN(KeyState, DIK_ESCAPE) ) { bPause = true; return ERR; } // 방향키 입력 처리 멀티키 입력도 가능. if( DIKEYDOWN(KeyState, DIK_LEFT) ) Text.X -= (Text.X < Movement)? 0 : Movement; if( DIKEYDOWN(KeyState, DIK_RIGHT) ) Text.X += (Text.X >= RLimit-Movement)? 0 : Movement; if( DIKEYDOWN(KeyState, DIK_UP) ) Text.Y -= (Text.Y < Movement)? 0 : Movement; if( DIKEYDOWN(KeyState, DIK_DOWN) ) Text.Y += (Text.Y > BLimit-Movement)? 0 : Movement; // 마우스 좌표. Text.X += MouseState.lX; Text.Y += MouseState.lY; if(Text.X < 0) Text.X = 0; if(Text.X > RLimit-Movement) Text.X = RLimit-Movement; if(Text.Y < 0) Text.Y = 0; if(Text.Y > BLimit-Movement) Text.Y = BLimit-Movement; char str2[256]; if( DILBUTTON(MouseState) ) // 마우스 왼쪽 버튼 클릭시, { wsprinf(str2, "왼쪽 버튼이 눌려짐, (%d, %d)", Text.X, Text.Y); lstrcpy(str, str2); } else if( DIRBUTTON(MouseState) ) // 마우스 오른쪽 버튼 클릭시, { wsprintf(str2, "오른쪽 버튼이 눌려짐, (%d, %d)", Text.X, Text.Y); lstrcpy(str, str2); } else // 아무런 버튼도 눌려지지 않았다면, { wsprintf(str2, "아무 버튼도 눌려지지 않았음, (%d, %d)", Text.X, Text.Y); lstrcpy(str, str2); } return 0; } int CGame::Main() { if( GetInput() == ERR ) return ERR; lpddSPrimary->GetDC(&hDC); // 이전 위치의 문자열을 지워주고, SelectObject(hDC, GetStockObject(BLACK_PEN)); SelectObject(hDC, GetStockObject(BLACK_BRUSH)); Rectangle(hDC, pt.x + PreText.X, pt.y + PreText.Y, pt.x + PreText.X+lstrlen(str)*8+50, pt.y + PreText.Y+20); // 문자열을 그려준다. SetBkColor(hDC, RGB(0, 0, 0)); SetTextColor(hDC, RGB(255, 255, 0)); TextOut(hDC, pt.x+Text.X, pt.y+Text.Y, str, lstrlen(str)); lpddSPrimary->ReleaseDC(hDC); Sleep(50); // 문자열의 이전위치 기억. PreText.X = Text.X; PreText.Y = Text.Y; return 0; } int CGame::Shutdown() { SetAcquire(); SAFERELEASE( lpdiMouse ); SAFERELEASE( lpdiKbd ); SAFERELEASE( lpdi ); SAFERELEASE( lpddSPrimary ); SAFERELEASE( lpdd ); return 0; } |