수업내용
1.xml로 처리하면 애니메이션을쉽게 구현할수있다.
+ Quad객체 수정
더보기
Quad::Quad(wstring textureFile, bool isAdd, Vector2 startUV, Vector2 endUV, Vector2 pos)
{
tag = "Quad";
material->SetTexture(textureFile);
size = material->GetTexture()->GetSize();
mesh = new Mesh<VertexUV>();
MakeMesh(startUV, endUV, pos);
mesh->CreateMesh();
}
Quad::Quad(wstring textureFile, float x, float y, float width, float height)
{
tag = "Quad";
material->SetTexture(textureFile);
size = material->GetTexture()->GetSize();
Vector2 startUV = Vector2(x, y) / size;
Vector2 cutSize = Vector2(width, height) / size;
Vector2 endUV = startUV + cutSize;
mesh = new Mesh<VertexUV>();
MakeMesh(startUV, endUV);
mesh->CreateMesh();
}
void Quad::MakeMesh(Vector2 startUV, Vector2 endUV, Vector2 pos)
{
float left = pos.x - size.x * 0.5f;
float right = pos.x + size.x * 0.5f;
float top = pos.y + size.y * 0.5f;
float bottom = pos.y - size.y * 0.5f;
vector<VertexUV>& vertices = mesh->GetVertices();
vertices.clear();
vertices.emplace_back(left, top, startUV.x, startUV.y);
vertices.emplace_back(right, top, endUV.x, startUV.y);
vertices.emplace_back(left, bottom, startUV.x, endUV.y);
vertices.emplace_back(right, bottom, endUV.x, endUV.y);
vector<UINT>& indices = mesh->GetIndices();
indices = { 0, 1, 2, 2, 1, 3 };
}
2.Frame 객체
헤더
더보기
class Frame
{
public:
Frame(wstring textureFile, Vector2 startUV = Vector2(),
Vector2 endUV = Vector2(1, 1), Vector2 pos = Vector2());
Frame(wstring textureFile, float x, float y, float width, float height);
~Frame();
void Render();
Vector2 GetSize() { return size; }
private:
void MakeMesh(Vector2 startUV = Vector2(), Vector2 endUV = Vector2(1, 1), Vector2 pos = Vector2());
protected:
Material* material;
Mesh<VertexUV>* mesh;
Vector2 size;
};
cpp
더보기
#include "Framework.h"
Frame::Frame(wstring textureFile, Vector2 startUV, Vector2 endUV, Vector2 pos)
{
material = new Material(textureFile);
size = (endUV - startUV) * material->GetTexture()->GetSize();
mesh = new Mesh<VertexUV>();
MakeMesh(startUV, endUV, pos);
mesh->CreateMesh();
}
Frame::Frame(wstring textureFile, float x, float y, float width, float height)
{
material = new Material(textureFile);
Vector2 textureSize = material->GetTexture()->GetSize();
size = Vector2(width, height);
Vector2 startUV = Vector2(x, y) / textureSize;
Vector2 cutSize = size / textureSize;
Vector2 endUV = startUV + cutSize;
mesh = new Mesh<VertexUV>();
MakeMesh(startUV, endUV);
mesh->CreateMesh();
}
Frame::~Frame()
{
delete material;
delete mesh;
}
void Frame::Render()
{
material->Set();
mesh->Draw();
}
void Frame::MakeMesh(Vector2 startUV, Vector2 endUV, Vector2 pos)
{
float left = pos.x - size.x * 0.5f;
float right = pos.x + size.x * 0.5f;
float top = pos.y + size.y * 0.5f;
float bottom = pos.y - size.y * 0.5f;
vector<VertexUV>& vertices = mesh->GetVertices();
vertices.emplace_back(left, top, startUV.x, startUV.y);
vertices.emplace_back(right, top, endUV.x, startUV.y);
vertices.emplace_back(left, bottom, startUV.x, endUV.y);
vertices.emplace_back(right, bottom, endUV.x, endUV.y);
vector<UINT>& indices = mesh->GetIndices();
indices = { 0, 1, 2, 2, 1, 3 };
}
3.Clip 객체 Frame&Clip은 출력에만 관여한다(world 가 없기때문에)
헤더
더보기
#pragma once
class Clip
{
private:
const float FPS = 10.0f;
public:
Clip(vector<Frame*> frames, bool isLoop = true, float speed = 1.0f);
~Clip();
void Update();
void Render();
void Play();
void Stop();
void SetEndEvent(function<void()> event) { endEvent = event; }
Frame* GetCurFrame() { return frames[curFrameNum]; }
private:
vector<Frame*> frames;
UINT curFrameNum = 0;
float frameTime = 0.0f;
float delayTime = 0.0f;
float speed;
bool isLoop;
bool isPlay = false;
function<void()> endEvent = nullptr;
};
cpp
더보기
#include "Framework.h"
Clip::Clip(vector<Frame*> frames, bool isLoop, float speed)
: frames(frames), isLoop(isLoop), speed(speed)
{
delayTime = 1.0f / FPS;
}
Clip::~Clip()
{
for (Frame* frame : frames)
delete frame;
}
void Clip::Update()
{
if (!isPlay) return;
frameTime += speed * DELTA;
if (frameTime < delayTime) return;
frameTime -= delayTime;
curFrameNum++;
if (isLoop)
{
curFrameNum %= frames.size();
}
else
{
if (curFrameNum >= frames.size())
{
curFrameNum--;
Stop();
}
}
}
void Clip::Render()
{
frames[curFrameNum]->Render();
}
void Clip::Play()
{
isPlay = true;
frameTime = 0.0f;
curFrameNum = 0;
}
void Clip::Stop()
{
isPlay = false;
if (endEvent) endEvent();
}
4.tinyxml을 사용(깃허브)
줍줍해오자~
5.애니메이션 출력
쿠키.h
더보기
#pragma once
class Cookie : public GameObject
{
private:
enum State
{
IDLE, RUN, JUMP
};
public:
Cookie();
~Cookie();
void Update() override;
void Render() override;
private:
void SetIdle();
void LoadClip(string path, string file, bool isLoop, float speed = 1.0f);
private:
vector<Clip*> clips;
State curState = IDLE;
};
쿠키cppㅇ
더보기
#include "Framework.h"
Cookie::Cookie()
{
LoadClip("Resources/Textures/Cookie/", "Kitty_Idle.xml", true);
LoadClip("Resources/Textures/Cookie/", "Kitty_Run.xml", true);
LoadClip("Resources/Textures/Cookie/", "Kitty_Jump.xml", false);
clips[JUMP]->SetEndEvent(bind(&Cookie::SetIdle, this));
clips[IDLE]->Play();
}
Cookie::~Cookie()
{
for (auto clip : clips)
delete clip;
}
void Cookie::Update()
{
if (KEY->Down('1'))
{
curState = IDLE;
clips[curState]->Play();
}
if (KEY->Down('2'))
{
curState = RUN;
clips[curState]->Play();
}
if (KEY->Down('3'))
{
curState = JUMP;
clips[curState]->Play();
}
clips[curState]->Update();
UpdateWorld();
}
void Cookie::Render()
{
worldBuffer->Set(world);
worldBuffer->SetVS(0);
clips[curState]->Render();
}
void Cookie::SetIdle()
{
curState = IDLE;
clips[curState]->Play();
}
void Cookie::LoadClip(string path, string file, bool isLoop, float speed)
{
tinyxml2::XMLDocument* document = new tinyxml2::XMLDocument();
document->LoadFile((path + file).c_str());
tinyxml2::XMLElement* atlas = document->FirstChildElement();
string textureFile = path + atlas->Attribute("imagePath");
vector<Frame*> frames;
tinyxml2::XMLElement* sprite = atlas->FirstChildElement();
while (sprite != nullptr)
{
float x, y, w, h;
x = sprite->FloatAttribute("x");
y = sprite->FloatAttribute("y");
w = sprite->FloatAttribute("w");
h = sprite->FloatAttribute("h");
frames.push_back(new Frame(ToWString(textureFile), x, y, w, h));
sprite = sprite->NextSiblingElement();
}
clips.push_back(new Clip(frames, isLoop, speed));
delete document;
}
6 .행동객체화
프레임은 30프레임정도도 충분하다못해 넘쳐난다.
과제:
'개인공부 > DirectX' 카테고리의 다른 글
dx_22일차 Action_MapEditor (0) | 2024.03.28 |
---|---|
DirectX 21일차_ Action / Animation (0) | 2024.03.27 |
DirectX 장비창 조합 구현 (0) | 2024.03.25 |
DirectX 13일차 Camera (0) | 2024.03.14 |
DirectX 9일차 (0) | 2024.03.08 |