프로젝트/강강술래잡기

[프로젝트][강강술래잡기] 버튼

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이라는 매크로를 만들어 클릭 되었음을 알 수 있도록 하였다.