์์ :)
https://github.com/eazuooz/WindowAPI/commit/ba073f8950369851aa3b812bf7ed862141d52784
Animation Event · eazuooz/WindowAPI@ba073f8
Show file tree Showing 6 changed files with 48 additions and 4 deletions.
github.com
2D ๊ฒ์์์ ์ ๋๋ฉ์ด์ ์ ์ฌ์์ํค๋ ๋ฐฉ๋ฒ์ ์ํ์์ ์ฐ์ด๋ ๋ฐฉ์๊ณผ ํฌ๊ฒ ๋ค๋ฅด์ง ์๋ค.
์ด๋ฌํ ์ ๋๋ฉ์ด์ ๊ธฐ๋ฒ์ Sprite ์ ๋๋ฉ์ด์ ์ด๋ผ๊ณ ํ๋ค.
์ด๋ฌํ ๊ทธ๋ฆผ์ ํ์ฅ์ฅํ์ ์์ง์ด๋ ์์๋๋ก ๋น ๋ฅธ์๊ฐ๋์ ์ฌ์์์ผ์ฃผ๋ฉด ๋์ ์ฐฉ์๋ก ์์ง์ด๋ ๊ฒ ์ฒ๋ผ ๋ณด์ด๊ฒ ๋๋ค.
์ฐ์ ์ Animation์ด ์ฌ์๋๊ฒ ํ๋ Animator ์ปดํฌ๋ํธ์
Animator ์ปดํฌ๋ํธ๋ Animation ์ ๊ฐ์ง๊ณ ์๋ค.
class Animator : public Component
{
public:
struct Event
{
void operator=(std::function<void()> func)
{
mEvent = std::move(func);
}
void operator()()
{
if (mEvent)
mEvent();
}
std::function<void()> mEvent;
};
public:
Animator();
~Animator();
virtual void Tick() override;
virtual void Render(HDC hdc) override;
void CreateAnimaiton(const std::wstring& name, Image* image
, Vector2 leftTop, Vector2 size, Vector2 offset
, float columnLegth, UINT spriteLength, float duration, bool bAffectedCamera = false);
Animation* FindAnimation(const std::wstring& name);
void Play(const std::wstring& name, bool bLoop = false);
public:
Event mStartEvent;
Event mCompleteEvent;
Event mEndEvent;
private:
std::map<std::wstring, Animation*> mAnimations;
Animation* mPlayAnimation;
bool mbLoop;
};
typedef std::map<std::wstring, Animation*>::iterator AnimationsIter;
Animator ์ปดํฌ๋ํธ๋ ์ฌ๋ฌ๊ฐ์ Animation ๋ค (์ : ๋ฌ๋ฆฌ๊ธฐ, ๊ฑท๊ธฐ, ๋๊ธฐ, ์ฃฝ๋ ๋ชจ์ ๋ฑ) ์ ๊ฐ์ง๊ณ ์๊ฒ ๋๋ค.
๊ทธ๋ฆฌ๊ณ ํ์ฌ ์คํ๋๋ ์ ๋๋ฉ์ด์ ์ PlayAnimation์ด๋ค.
Loop๊ฐ ํ์ฑํ ๋์ด์๋ค๋ฉด ํด๋น ์ ๋๋ฉ์ด์ ์ ์ข ๋ฃ๋์ง ์๊ณ
๋ค์ Reset() ์์ผ์ ์ฒ์๋ถํฐ ๋ค์ ์ฌ์๋๊ฒ ๋๋ค.
void Animator::Tick()
{
if (mPlayAnimation != nullptr)
{
mPlayAnimation->Tick();
if (mbLoop && mPlayAnimation->isComplete())
{
mCompleteEvent();
mPlayAnimation->Reset();
}
}
}
Event๋ ๊ฐ๊ฐ์ ์ ๋๋ฉ์ด์ ์ด ์ฒ์ ์ฌ์๋ ๋ StartEvent
ํ๋์ ์ ๋๋ฉ์ด์ ๋์์ด ์๋ฃ๋ ๋ CompleteEvent
์ ๋๋ฉ์ด์ ์ด ์ ํ๋๋ฉด์ ๋๋ ๋ EndEventํจ์๋ฅผ ํธ์ถ๋๊ฒ ๋์ด์๋ค.
๊ทธ๋์ ๋ค์๊ณผ ๊ฐ์ด Event์ ์๋ง๋ ๋ฉค๋ฒํจ์๋ฅผ bind์์ผ์ฃผ์ด์ผ ์ ๋๋ก ๋์ํ๊ฒ ๋๋ค.
Image* pImage
= Resources::Load<Image>(L"PlayerImage", L"..\\Resources\\Images\\link.bmp");
Animator* animator = GetComponent<Animator>();
animator->CreateAnimaiton(L"Walk_Up", pImage, Vector2(0.f, 780.f), Vector2(120.f, 130.f), Vector2(0.f, -30.f), 120.f, 10, 0.1f);
animator->CreateAnimaiton(L"Walk_Down", pImage, Vector2(0.f, 520.f), Vector2(120.f, 130.f), Vector2(0.f, -30.f), 120.f, 10, 0.1f);
animator->CreateAnimaiton(L"Walk_Left", pImage, Vector2(0.f, 650.f), Vector2(120.f, 130.f), Vector2(0.f, -30.f), 120.f, 10, 0.1f);
animator->CreateAnimaiton(L"Walk_Right", pImage, Vector2(0.f, 910.f), Vector2(120.f, 130.f), Vector2(0.f, -30.f), 120.f, 10, 0.1f);
animator->mStartEvent = std::bind(&Player::AnimationStart, this);
animator->mCompleteEvent = std::bind(&Player::AnimationComplete, this);
animator->mEndEvent = std::bind(&Player::AnimationEnd, this);
animator->Play(L"Walk_Down", true);
ํด๋น Event๋ค์ ์ฌ๋ฌ๋ถ๋ค์ ํธ๋ฆฌ์ฑ์ ์ํด ์ ๊ณตํ๊ฒ์ด๋ค.
๊ฐ๊ฐ์ Event๊ฐ ํธ์ถ๋๋ ์์๋ ๋ค์๊ณผ ๊ฐ์ด ํธ์ถ๋๋ค๊ณ ๋ณด๋ฉด ๋๋ค.
์ ๋๋ฉ์ด์ ํด๋์ค๋ ๋ค์๊ณผ ๊ฐ์ด ๊ตฌ์ฑ๋์ด ์๋ค.
class Image;
class Animator;
class Animation : public Entity
{
public:
struct Sprite
{
Vector2 leftTop; // ์ข์ธก ์๋จ ํฝ์
์ขํ
Vector2 size; // ์ข์ธก ์๋จ์ผ๋ก ๋ถํฐ ์๋ผ๋ผ ๊ฐ๋ก ์ธ๋ก ํฝ์
๊ธธ์ด
Vector2 offset;
float duration; // ํด๋น ํ๋ ์ ์ ์ง์๊ฐ
Sprite()
: leftTop(0.0f, 0.0f)
, size(0.0f, 0.0f)
, offset(0.0f, 0.0f)
, duration(0.0f)
{
}
};
public:
Animation();
~Animation();
void Tick();
void Render(HDC hdc);
void Create(Image* image, Vector2 leftTop, Vector2 size, Vector2 offset
, float columnLegth, UINT spriteLength, float duration, bool affectedCamera = false);
void Reset();
bool isComplete() { return mbComplete; }
void SetAnimator(Animator* animator) { mAnimator = animator; }
private:
Animator* mAnimator;
Image* mImage;
std::vector<Sprite> mSpriteSheet;
int mSpriteIndex;
float mTime;
bool mbComplete;
bool mbAffectedCamera;
};
Animation ํด๋์ค๋ Sprite Image๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
์ฌ๋ฌ๊ฐ์ Sprite ๊ฐ ๋ชจ์ฌ์ ํ๋์ Sprite sheet๊ฐ ๋๊ณ ๊ทธ๊ฒ์ด ํ๋์ ์ ๋๋ฉ์ด์ ์ ๋ณด๋ผ๊ณ ๋ณด๋ฉด ๋๋ค.
์ ๋๋ฉ์ด์ ์ ์์ฑํ ๋ ํด๋น ์ด๋ฏธ์ง์์ ์์์ ์ ๊ธฐ์ค์ผ๋ก ํ์นธ์ฉ ์ด๋ํ๋ฉด์ ๊ทธ๋ฆผ๋ณ๋ก Sprite์ ๋ณด๋ฅผ Spritesheet์๋ค๊ฐ ์ ์ฅํ๋ค.
void Animation::Create(Image* image, Vector2 leftTop, Vector2 size, Vector2 offset
, float columnLegth, UINT spriteLength, float duration, bool affectedCamera)
{
mImage = image;
mbAffectedCamera = affectedCamera;
for (size_t i = 0; i < spriteLength; i++)
{
Sprite sprite;
sprite.leftTop.x = leftTop.x + (columnLegth * float(i));
sprite.leftTop.y = leftTop.y;
sprite.size = size;
sprite.offset = offset;
sprite.duration= duration;
mSpriteSheet.push_back(sprite);
}
}
void Animation::Tick()
{
if (mbComplete)
return;
mTime += Time::DeltaTime();
if (mSpriteSheet[mSpriteIndex].duration < mTime)
{
mTime = 0.0f;
if (mSpriteSheet.size() <= mSpriteIndex + 1)
{
mbComplete = true;
}
else
{
mSpriteIndex += 1;
}
}
}
void Animation::Render(HDC hdc)
{
Object* object = mAnimator->GetOwner();
Vector2 pos = object->GetPos();
if (mbAffectedCamera)
pos = Camera::CalulatePos(pos);
BLENDFUNCTION func = {};
func.BlendOp = AC_SRC_OVER;
func.BlendFlags = 0;
func.AlphaFormat = AC_SRC_ALPHA;
func.SourceConstantAlpha = 255;
pos += mSpriteSheet[mSpriteIndex].offset;
AlphaBlend(hdc
, int(pos.x - mSpriteSheet[mSpriteIndex].size.x / 2.0f)
, int(pos.y - mSpriteSheet[mSpriteIndex].size.y / 2.0f)
, int(mSpriteSheet[mSpriteIndex].size.x)
, int(mSpriteSheet[mSpriteIndex].size.y)
, mImage->GetHdc()
, int(mSpriteSheet[mSpriteIndex].leftTop.x)
, int(mSpriteSheet[mSpriteIndex].leftTop.y)
, int(mSpriteSheet[mSpriteIndex].size.x)
, int(mSpriteSheet[mSpriteIndex].size.y)
, func);
}
์ฌ์ํ ๋๋ ๊ฐ๊ฐ์ ํ๋ ์๋ง๋ค ์ฌ์์๊ฐ์ ๊ณ์ฐํํ sprite๋ฅผ ํ๋์ฉ ์ฌ์ํ๋ฉด๋๋ค.
'๐ Development Study > ๐ป Win32API' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Rigidbody (0) | 2022.10.20 |
---|---|
API Math (0) | 2022.10.20 |
Object Delete (0) | 2022.10.12 |
Alphablend, Camera Effect (0) | 2022.10.05 |
Camera (1) | 2022.10.04 |
๋๊ธ