DX11 2D Game Programming

DX11_2020_0720_월_Texture Render

HI2 2020. 7. 20. 16:12

200720_DX112D_MyFramework.zip
2.14MB

 

 

1. Texture class

  a. 클래스 생성시 원본 image의 size값으로 Vertex 좌표 할당

더보기
void Texture::SetVerticesAndIndices()
{
	// Image file의 원본 크기를 이용하여 Vertices를 세팅한다
	vertices.resize(4);
	vertices[0].uv = { 0, 0 };
	vertices[0].pos = { -size.x * 0.5f, +size.y * 0.5f, 0.0f };
	vertices[1].uv = { 1, 0 };
	vertices[1].pos = { +size.x * 0.5f, +size.y * 0.5f, 0.0f };
	vertices[2].uv = { 0, 1 };
	vertices[2].pos = { -size.x * 0.5f, -size.y * 0.5f, 0.0f };
	vertices[3].uv = { 1, 1 };
	vertices[3].pos = { +size.x * 0.5f, -size.y * 0.5f, 0.0f };

	indices.emplace_back(0);
	indices.emplace_back(1);
	indices.emplace_back(2);

	indices.emplace_back(2);
	indices.emplace_back(1);
	indices.emplace_back(3);

	vertexBuffer = new VertexBuffer(vertices.data(), sizeof(Vertex), vertices.size());
	indexBuffer = new IndexBuffer(indices.data(), indices.size());
}

 

2. GameObject class

  a. Player class는 GameObject를 상속받고, 기능 추가(점프)

  b. 배경 Texture는 기본 GameObject에 Texture를 별도로 할당

더보기
#pragma once

class GameObject
{
public:
	GameObject();
	virtual ~GameObject();
	//
	virtual void Update();
	virtual void Render();
	//
	virtual bool Active() { return isActive; }
	virtual void Active(bool value) { isActive = value; }
	//
	virtual void SetTexture(wstring file);
	//
	virtual Float2 GetPos() const { return pos; }
	virtual void SetPos(Float2 value) { pos = value; }


protected:
	bool isActive;
	//
	Texture* texture;
	MatrixBuffer* worldBuffer;
	Float2 pos;
};
///////////////////////////////////////////////////////////////////////////////////////////////
#include "Framework.h"

GameObject::GameObject()
	:isActive(true), texture(nullptr), worldBuffer(nullptr), pos(0, 0)
{
	worldBuffer = new MatrixBuffer();
	worldBuffer->Update();
}

GameObject::~GameObject()
{
	if (texture)
	{
		delete texture;
		texture = nullptr;
	}
	delete worldBuffer;
	worldBuffer = nullptr;
}

void GameObject::Update()
{
	if (Active() == true)
		worldBuffer->Update();
}

void GameObject::Render()
{
	if (Active() == true)
	{
		worldBuffer->SetVSBuffer(0);
		if (texture)
			texture->Render();
	}
}

void GameObject::SetTexture(wstring file)
{
	if (texture != nullptr)
	{
		delete texture;
		texture = nullptr;
	}
	texture = new Texture(file);
}

 

5. Player class

  a. 이동, 점프 구현

더보기
#pragma once

class Texture;

class Player : public GameObject
{
public:
	Player();
	~Player();
	//
	virtual void Update() override;
	virtual void Render() override;
	//
	void Move();
	void Jump();

private:
	float moveSpeed;
	float gravity;
	float jumpPower;
	float forceOfJump;
};
///////////////////////////////////////////////////////////////////////////////////////////////
#include "Framework.h"
#include "Player.h"

Player::Player()
	: moveSpeed(500.0f), gravity(980.0f), jumpPower(0.0f), forceOfJump(500.0f)
{
	// texture 변수는 부모 class인 GameObject에 선언되어있다.
	// 파일명만 사용하여 GameObject class에 선언된 함수를 사용, texture를 생성 & 할당
	SetTexture(L"Textures/player.png");
}

Player::~Player()
{
}

void Player::Update()
{
	if (Active() == true)
	{
		Move();
		Jump();
	}
	GameObject::Update();
}

void Player::Render()
{
	GameObject::Render();
}

void Player::Move()
{
	if (KeyPress(VK_RIGHT))
	{
		pos.x += moveSpeed * (float)DeltaTime;
		// 화면 경계 움직임 제한(우측)
		if (pos.x >= (WinWidth * 0.5) - (texture->Size().x * 0.5))
			pos.x = (WinWidth * 0.5) - (texture->Size().x * 0.5);
	}
	else if (KeyPress(VK_LEFT))
	{
		pos.x -= moveSpeed * (float)DeltaTime;
		// 화면 경계 움직임 제한(좌측)
		if (pos.x <= -(WinWidth * 0.5) + (texture->Size().x * 0.5))
			pos.x = -(WinWidth * 0.5) + (texture->Size().x * 0.5);
	}
	// matrix 수정
	XMMATRIX world = XMMatrixTranslation(pos.x, pos.y, 0);
	worldBuffer->Set(world);
}

void Player::Jump()
{
	if (KeyDown(VK_SPACE))
	{
		jumpPower = forceOfJump;
	}
	/* 중력 */
	jumpPower -= gravity * (float)DeltaTime;
	// DX에서 스크린 좌표는 중앙이 (0,0), 위쪽이 +, 아래가 - 이므로
	// pos.y는 jumpPower를 더한값으로 계산한다(API의 스크린좌표와 반대)
	pos.y += jumpPower * (float)DeltaTime;

	if (pos.y <= -(WinHeight * 0.5) + (texture->Size().y * 0.5))
	{
		// texture는 pos를 중점으로 네 Vertex가 +- size * 0.5 로 계산되어 있다(Texture class 생성자)
		// 따라서 바닥과의 충돌처리를 위한 좌표를 Size()를 이용하여 계산한다
		pos.y = -(WinHeight * 0.5) + (texture->Size().y * 0.5);
		jumpPower = 0;
	}
}

 

4. Scene Camera 기능

  a. F1 : 카메라 위치 초기화

  b. F2 : Target Camera Mode 설정

더보기
#pragma once

class WVPScene : public Scene
{
private:
	MatrixBuffer* viewBuffer;
	MatrixBuffer* projectionBuffer;
	//
	GameObject* bg;	
	GameObject* player;
	//
	Float2 camPos;
	bool followTarget;

public:
	WVPScene();
	~WVPScene();
	
	virtual void Update() override;
	virtual void Render() override;
	//
	void CamMove();
	void InitVPBuffers();
	void SetVPBuffers();
	void SetProjectionBuffer();
	void InitGameObjects();
};
///////////////////////////////////////////////////////////////////////////////////////////////
#include "Framework.h"
#include "WVPScene.h"

WVPScene::WVPScene()
	: camPos(0, 0)
{
	InitVPBuffers();
	InitGameObjects();
}

WVPScene::~WVPScene()
{
	delete viewBuffer;
	delete projectionBuffer;
	//
	delete bg;
	delete player;
}

void WVPScene::Update()
{
	player->Update();
	CamMove();
}

void WVPScene::Render()
{
	SetVPBuffers();
	//
	bg->Render();
	player->Render();
}

void WVPScene::CamMove()
{
	if (KeyPress('W'))
	{
		camPos.y += 500 * DeltaTime;
	}
	else if (KeyPress('S'))
	{
		camPos.y -= 500 * DeltaTime;
	}
	if (KeyPress('A'))
	{
		camPos.x -= 500 * DeltaTime;
	}
	else if (KeyPress('D'))
	{
		camPos.x += 500 * DeltaTime;
	}

	if (KeyDown(VK_F1))
	{ // Reset CamPos
		camPos.x = 0.0f;
		camPos.y = 0.0f;
	}
	if (KeyDown(VK_F2))
	{ // Toggle Follow Target Mode
		followTarget = !followTarget;
	}
	/* set viewBuffer */
	XMMATRIX view{};
	if (followTarget)
		view = XMMatrixTranslation(-player->GetPos().x, -player->GetPos().y, 0);
	else
		view = XMMatrixTranslation(camPos.x, camPos.y, 0);
	viewBuffer->Set(view);
	viewBuffer->Update();
}

void WVPScene::InitVPBuffers()
{
	viewBuffer = new MatrixBuffer();
	projectionBuffer = new MatrixBuffer();
	//
	SetProjectionBuffer();
}

void WVPScene::SetVPBuffers()
{
	viewBuffer->SetVSBuffer(1);
	projectionBuffer->SetVSBuffer(2);
}

void WVPScene::SetProjectionBuffer()
{
	Matrix projection = XMMatrixOrthographicLH((float)WinWidth, (float)WinHeight, -1.0f, 1.0f);
	projectionBuffer->Set(projection);
	projectionBuffer->Update();
}

void WVPScene::InitGameObjects()
{
	bg = new GameObject;
	bg->SetTexture(L"Textures/bg.png");
	//
	player = new Player;
}