이번에는 콘솔창을 흔들어보는 기능을 만들어 보겠습니다.
참고로 방법은 여러 가지이기에 꼭 이것만이 정답은 아닙니다.
콘솔창 흔들기
가장 먼저 cpp파일과 h(헤더)파일을 만들어줍니다.
이름은 원하는대로 지어주시고(여기서는 CameraManager라고 사용했습니다.) h를 먼저 채워봅시다.
#pragma once
class CameraManager
{
public:
CameraManager();
~CameraManager();
public:
void ShakeConsoleWindow(int duration, int power);
private:
HWND m_consoleWindow;
int m_originalX;
int m_originalY;
private:
void SaveOriginalPosition();
};
우선
public으로 생성자와 소멸자를 만들어줍니다.
그리고 호출하여 사용할 함수를 하나 더 public으로 만들어줍니다. 저는 ShakeConsoleWindow로 만들었습니다.
그리고 인자로 duration(횟수)과, power(흔들리는 정도)를 받아줍시다.
그리고 이제 private으로 HWND(윈도우핸들)과 기존위치를 콘솔창의 기존 위치를 저장할 x, y값을 만듭니다.
마지막으로 콘솔창의 현재 위치를 받아와서 저장시켜줄 함수도 하나 만듭시다.
이제 본격적으로 cpp를 구현하러갑시다.
가장 먼저 생성자에서 콘솔 창 핸들을 얻어옵니다.
GetColsoleWindow() 함수를 사용하여서 얻어오면 됩니다. 이때 핸들이 유효하지 않다면 함수는 바로 종료되죠.
그리고 콘솔창의 기존 위치를 저장하는 SaveOriginalPosition() 함수를(곧 만들 겁니다) 호출해서 콘솔창의 기존 위치를 저장합니다.
그리고 난수를 생성하기 위해 srand() 함수를 이용했습니다. 이때 난수 생성을 위한 시드를 현재 시간으로 설정하여 완전히 랜덤한 값이 나오게 합시다.
소멸자에서는 딱히 해줄 일이 없습니다.
그렇다면 왜 만들었냐? 하실 수도 있겠지만 이 글을 보는 여러분이 하기 따라서 사용할 수도 있기에 우선 만들었습니다.
그리고 이제 ShakeConsoleWindow() 짜보겠습니다.
우선 생성자에서 했던 것처럼 m_consoleWindow가 없다면 return을 시켜주고 콘솔창이 흔들리는 코드를 짜야합니다.
저는 for문을 통해서 duration 값만큼 움직이게 하는 형식을 선택했습니다.
for문을 dutation횟수만큼 반복하게 해주고 for문의 내부에는 흔들릴 포지션을 정해주면 되는데 rand() 함수를 사용해서 랜덤한 값을 받고 그 값에 power만큼을 나누어주는 형식으로 했습니다.
이때 랜덤한 값에 power를 나눈 만큼의 값에 power/2 한 값을 빼주는데 그 이유는 오프셋 값을 콘솔 창의 중심에서 양방향으로 움직이게 하기 위함입니다.
그렇게 받아온 값을 SetWindowPos함수를 이용하여 콘솔창을 흔드는 위치로 옮겨줍니다.
그리고 SWP_NOSIZE | SWP_NOZORDER를 사용할 것인데 SWP_NOSIZE는 창의 크기를 변경하지 않게 해주는 플래그이고 SWP_NOZORDER는 창의 Z-순서를 변경하지 않도록 합니다.
그리고 Sleep() 함수로 해당 위치에 조금 머물도록 설정해 줄 것입니다. Sleep함수를 사용 안 하면 갔다가 바로 돌아오기에 눈에 흔들리는 것이 보이지 않습니다.
그리고 for문을 나오고 콘솔창을 다시 원래 위치로 돌아오게 설정합시다.
마지막으로 SaveOriginalPosition()를 코딩해 봅시다.
간단히 GetWindowRect()를 사용해 콘솔 창의 현재 위치를 얻고, m_originalX와 m_originalY에 저장할 것입니다.
지금까지 말로 풀었던 것을 코드로 봅시다.
#include "pch.h"
#include "CameraManager.h"
#include <iostream>
#include <cstdlib>
#include <ctime>
CameraManager::CameraManager()
{
m_consoleWindow = GetConsoleWindow();
if (!m_consoleWindow)
return;
SaveOriginalPosition();
srand(static_cast<unsigned int>(time(nullptr)));
}
CameraManager::~CameraManager()
{
}
void CameraManager::ShakeConsoleWindow(int duration, int power)
{
if (!m_consoleWindow)
return;
for (int i = 0; i < duration; ++i)
{
int offsetX = rand() % power - (power / 2);
int offsetY = rand() % power - (power / 2);
SetWindowPos(m_consoleWindow, nullptr, m_originalX + offsetX, m_originalY + offsetY,
0, 0, SWP_NOSIZE | SWP_NOZORDER);
Sleep(10);
}
SetWindowPos(m_consoleWindow, nullptr, m_originalX, m_originalY,
0, 0, SWP_NOSIZE | SWP_NOZORDER);
}
void CameraManager::SaveOriginalPosition()
{
if (!m_consoleWindow)
return;
RECT rect;
GetWindowRect(m_consoleWindow, &rect);
m_originalX = rect.left;
m_originalY = rect.top;
}
위와 같이 코드가 짜입니다.
이제 이 기능을 실행시킬 곳에 CameraManager를 변수로 만들고
CameraManager.ShakeConsoleWindow(dutation, power)를 설정해 주고 실행을 해보면
마무리
오늘 글은 여기까지입니다.
'개발' 카테고리의 다른 글
[C++] 게임프로그래밍 수행평가 회고록 (0) | 2024.12.15 |
---|---|
[유니티] 그냥 적당히 쓸만한 꿀팁 (2) | 2024.11.11 |
[유니티] UI컴포넌트 (2) | 2024.10.29 |
유니티 타임라인 (1) | 2024.10.11 |