이번엔 Time 클래스에서 구해지는 Delta Time을 통해서 기존에 사용한 Rect_Control 클래스에 점프 구현과 중력등을 구현
Delta Time 이란? 1초에 그려지는 FPS를 시간을 나눈 값을 애기하는데 예를들어 FPS 60이라고 하면 1초에 60번 그리기 때문에 0.1초의 값이 반환 되는것이다. FPS값이 높을수록 점점 소수로 변해지고 범위는 0 ~ 1로 생각 하면 된다.
1. Rect_Control.h
점프 구현에 필요한 함수와 변수를 선언
※ velocity 같은 경우는 추후에 쓰이는곳에 따라 다르지만 대부분 힘, 속도 같은 값을 표현 할 때 많이 사용함
#pragma once
#include "Rect.h"
class Rect_Control : public Rect
{
public:
Rect_Control(Shader* shader);
Rect_Control(Shader* shader, Vector2 position, Vector2 scale, D3DXCOLOR color = D3DXCOLOR(1, 1, 1, 1));
void Update(Matrix& V, Matrix P) override;
void MoveLeft();
void MoveRight();
void Jump();
void StopJump();
void Movespeed(float val); //셋팅용
FORCEINLINE float Movespeed() { return Speed; }
private:
float Speed = 0.1f;
float velocity = 0.0f; // 점프에 필요한 기본 힘의 값
float gravity = 1.5f; // 중력
bool Ground = true; // true 지상 판정 false 공중 판정
};
2. Rect_Control.cpp
void Jump() 함수 정의
※ 조건은 Ground가 true 이면 현재 velocity, Ground을 셋팅 한다 (점프력 0.35 / 바닥판정 false)
void Rect_Control::Jump()
{
if (Ground == true)
{
velocity = 0.35f;
Ground = false;
}
}
void StopJump() 함수 정의
※ 해당 조건은 점프키를 땔때 사용되는 점프값 초기화 하는 목적
void Rect_Control::StopJump()
{
if (velocity > 0)
velocity = 0.0f;
}
void Update(Matrix& V, Matrix P) 수정
※ 기존의 Update 값을 수정 하는데 정리를 하면
1. pos에 현재의 위치값을 저장 한다
2. 조건에 따른 점프 했을때의 값을 셋팅 또는 초기화 시켜주는 조건
3. 어떠한 조건이 걸리게 되든 셋팅 하는값은 조건 마지막 아래 부분에 넣어서 공통으로 사용
4. ImGui 통해서 화면 출력
void Rect_Control::Update(Matrix& V, Matrix P)
{
//부모꺼 한번 호출
//Rect::Update(V, P);
__super::Update(V, P);
Vector2 pos = Position();
if (Ground == false)
{
velocity -= gravity * Time::Delta(); // 점프력에 중력만큼 뺌
pos.y += velocity;
}
//바닥 도착시 초기화용
if (pos.y < Scale().y * 0.5f) // 자기 크기의 절반 만큼 에서 걸리게 만듬
{
Ground = true;
velocity = 0.0f;
pos.y = Scale().y * 0.5f;
}
Position(pos);
//출력용
ImGui::LabelText("Delta Time", "%.5f", Time::Delta());
ImGui::LabelText("Velocity", "%.1f", velocity);
ImGui::LabelText("Rect Center ", "%.1f", pos.y);
ImGui::LabelText("Ground ", "%d", Ground);
}
3. Scene.cpp
Update() 수정
※ 키보드 이벤트 추가 해서 점프 관련 함수를 호출
void Update()
{
//Camera
Vector3 eye = Vector3(0, 0, 0);
Vector3 at = Vector3(0, 0, 1);
Vector3 up = Vector3(0, 1, 0);
D3DXMatrixLookAtLH(&View, &eye, &(eye + at), &up);
D3DXMatrixOrthoOffCenterLH(&Projection, 0, (FLOAT)Width, 0, (FLOAT)Height, -1.0f, +1.0f);
//Test Pass
static bool check = false;
ImGui::Checkbox("Rect Pass", &check);
check ? rect->PASS() = 0 : rect->PASS() = 1;
//Test speed
float mvSpeed = R_c->Movespeed();
ImGui::SliderFloat("MoveSpeed", &mvSpeed, 0.001f, 1.0f);
R_c->Movespeed(mvSpeed);
if (Key->Press('A'))
R_c->MoveLeft();
else if (Key->Press('D'))
R_c->MoveRight();
if (Key->Down(VK_SPACE))
R_c->Jump();
else if (Key->Up(VK_SPACE))
R_c->StopJump();
//FPS
ImGui::Text("%.1f", ImGui::GetIO().Framerate);
ImGui::Text("FPS : %.1f", Time::Get()->FPS());
ImGui::Text("Running Time : %.1f", Time::Get()->Running());
BackGround->Update(View, Projection);
rect->Update(View, Projection);
R_c->Update(View, Projection);
}
실행
처음에 true값이 들어 가기 때문에 처음에만 공중 상태 일때 점프가 가능하고 바닥에 닿아야만 점프가 가능하고 하며 중력도 구현을 해서 점프 최고 지점에서 천천히 떨어지는 형태로 구현
점프력 원리는 간단하게 Space를 누르게 되면 Velocity에 값에 넣어지면서 y축 방향으로 나아가는 힘과 추가적으로 점프를 못하게 Ground를 false로 넣어서 다시 Space 눌렀을때 못들어 오게 하는 용도 이다.
중력과 점프를 다시 할 수 있는 원리는 Rect_Control -> Update 영역에 정의 되어 있는 해당 코드에서 구현이 되는데 다음과 같다.
1. pos 변수에 자기 자신의 위치값을 실시간을 받는다
2. Ground가 false 즉 공중에 있다고 판정이 되면 현재 y축의 값에 대해 계속 값을 더해지는데 gravity값이 높을 수록 점프력이 낮아지는 형태이다 또한 Time::Deta를 중력에 곱하면서 빼기 때문에 자연스럽게 하강 하는것처럼 보이게 만들수 있다.
3. 바닥에 있다면 점프를 다시 할 수 있게 값을 초기 화 하고 조건 같은 경우는 자기 크기의 반(전체 크기100.0f) 에서 0.*를 곱해서 지면에 붙을수 있게 만든다 (네모가 그려지는 원리는 이전 글에서 확인)
https://github.com/ascher8159/DX2D
DX2D_13 Rect_Control
'DirectX > DirectX 2D' 카테고리의 다른 글
DX2D_14 Texture (Sampler state, Blend State) (0) | 2023.03.22 |
---|---|
DX2D_12 Time (System) (0) | 2022.12.15 |
DX2D_11 Rect_Control (상속, 다형성) (0) | 2022.12.14 |
DX2D_10 Rect (0) | 2022.12.07 |
DX2D_9 WVP2 (1) | 2022.12.04 |