프로젝트/강강술래잡기
[프로젝트][강강술래잡기] 버튼
wnstjd
2023. 12. 18. 08:52
개요
게임UI의 버튼 기능 구현을 정리한 글이다.
버튼 기능을 구현하며 함수 포인터와 funtional, C++의 람다, 캡처를 공부하여 C++ 사용 능력이 많이 상승한 것 같다.
결과물
헤더
#pragma once
#include "Object.h"
#include "Texture.h"
class Button :
public Object
{
public:
Button(void(*_action)(), wstring _text);
~Button();
public:
void Update() override;
void Render(HDC _dc) override;
void SetText(wstring str) { m_sText = str; }
private:
void(*m_pAction)();
wstring m_sText;
Texture* m_pTex;
};
cpp
#include "pch.h"
#include "Button.h"
#include "KeyMgr.h"
#include "ResMgr.h"
#include <string>
Button::Button(void(*_action)(), wstring _text)
: m_pTex(nullptr)
{
m_pAction = _action;
m_sText = _text;
m_pTex = ResMgr::GetInst()->TexLoad(L"Button", L"Texture\\Button.bmp");
}
Button::~Button()
{
}
void Button::Update()
{
if (KEY_UP(KEY_TYPE::LBUTTON))
{
Vec2 vPos = GetPos();
Vec2 vScale = GetScale();
POINT _pMousePoint;
GetCursorPos(&_pMousePoint);
if (IS_CLICK(vPos.x, vPos.y, vScale.x, vScale.y, _pMousePoint.x, _pMousePoint.y))
{
ResMgr::GetInst()->Play(L"Button_Click");
m_pAction();
}
}
}
void Button::Render(HDC _dc)
{
Vec2 vPos = GetPos();
Vec2 vScale = GetScale();
RECT rt = { vPos.x - vScale.x / 2, vPos.y - vScale.y / 2
, vPos.x + vScale.x / 2, vPos.y + vScale.y / 2 };
TransparentBlt(_dc
, (int)(vPos.x - m_pTex->GetWidth() / 2)
, (int)(vPos.y - m_pTex->GetHeight() / 2)
, m_pTex->GetWidth(), m_pTex->GetHeight(), m_pTex->GetDC()
, 0, 0, m_pTex->GetWidth(), m_pTex->GetHeight(), RGB(255, 0, 255));
DrawText(_dc, m_sText.c_str(), -1, &rt
, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
기타
#define IS_CLICK(posx, posy, scalex, scaley, mousex, mousey) \
(int)(posx-scalex/2) <= mousex && (int)(posy-scaley/2) <= mousey \
&& (int)(posx+scalex/2) >= mousex && (int)(posy+scaley/2) >= mousey \
구현 사항
생성자에서 함수 포인터로 버튼이 클릭되었을 때 실행되는 함수를 전달받고
클릭되었을 때 함수 포인터를 실행하는 방식으로 구현하였다.
IS_CLICK이라는 매크로를 만들어 클릭 되었음을 알 수 있도록 하였다.