[DirectX] 바바이즈유 개발 일지, 엔진

라멘커비·2024년 4월 9일
0

DirectX 2D

목록 보기
10/24
post-custom-banner

바바이즈유

액터 상속 구조(미완성일지도몰라)

쉐도우복싱일수도 있지만 미리 생각해보고 짜는 중인 내 액터 클래스들 구조!!

Actor : (엔진의) 액터
Objects : 맵에 표시될 수 있는 모든 오브젝트
LerpMoveObject : 한 칸씩 Lerp 이동할 수 있는 모든 오브젝트
그리고 얘를 상속받아서
PlayerObject : 그 중에도 입력에 의해 이동할 수 있는 애들(Push일 때도 있음)
TextObject : (아직안만듦)Push에 의해서만 이동할 수 있는 TextObject들
그리고 PlayerObject 상속받아서 BabaObject 만들어놨음

근데 입력에 의해 이동하는 애들이랑 Push당해서 이동하는 애들 구분이 아니고 Type Switch하듯이 만들어야 하나??????

Lerp이동

void ALerpMoveObject::Move(float _DeltaTime)
{
	if (false == IsMove)
	{
		if (true == IsPress(VK_LEFT))
		{
			AddNextActorLocation(FVector::Left * TileSize);
			NewInputDir = EInputDir::Left;
			IsMove = true;
		}

		if (true == IsPress(VK_RIGHT))
		{
			AddNextActorLocation(FVector::Right * TileSize);
			NewInputDir = EInputDir::Right;
			IsMove = true;
		}

		if (true == IsPress(VK_UP))
		{
			AddNextActorLocation(FVector::Up * TileSize);
			NewInputDir = EInputDir::Up;
			IsMove = true;
		}

		if (true == IsPress(VK_DOWN))
		{
			AddNextActorLocation(FVector::Down * TileSize);
			NewInputDir = EInputDir::Down;
			IsMove = true;
		}
		if (true == IsMove)
		{
			InputCheck = true;
		}
	}
	LerpMove(_DeltaTime);
}

void ALerpMoveObject::AddNextActorLocation(FVector _Add)
{
	NextActorLocation = GetActorLocation() + _Add;
}

void ALerpMoveObject::LerpMove(float _DeltaTime)
{
	if (LerpTime <= 1.f && true == IsMove)
	{
		LerpTime += _DeltaTime * 4;
		SetActorLocation(LerpCal(LerpTime));
	}
	else
	{
		IsMove = false;
		LerpTime = 0.f;
		SetActorLocation(NextActorLocation);
		CurActorLocation = NextActorLocation;
	}
}

FVector ALerpMoveObject::LerpCal(float _Time)
{
	return CurActorLocation * (1 - _Time) + NextActorLocation * _Time;
}

되돌리기

z키 누르면 이전으로 돌아감 ⇒ 이동 정보 받는 스택 필요함
스택에 넣는 데이터 : 방향이랑 애니메이션 번호 필요함
근데 넣는 기준? 입력 1회 있으면 스택에 넣어야 함. 모든 움직일 수 있는 오브젝트에 해당됨.

이동할 때 스택에 이동 전 정보를 넣음 → Z를 누르면 이전 상태로 돌아감.

  • 입력있을 때마다 이동 전의 정보를 스택에 넣고, 되돌릴 때 스택에서 빼서 사용
void APlayerObject::Tick(float _DeltaTime)
{
	Super::Tick(_DeltaTime);

	Move(_DeltaTime);
	if (true == IsMove)
	{
		LerpMove(_DeltaTime);
	}
	

	if (true == IsPress('Z') && false == IsMove)
	{
		if (true == MoveStack.empty())
		{
			return;
		}
		IsMove = true;
		InputCheck = true;

		// 이동 : 현재 방향의 반대로 이동
		ReverseMoveSetting(NewInputDir, _DeltaTime);
		
		// 애니메이션에 필요한 정보 : 이전 상태의 정보로 되돌리고 삭제
		NewInputDir = MoveStack.top().second;
		AnimationNumber = MoveStack.top().first;
		MoveStack.pop();
		return;
	}

	if (true == InputCheck)
	{
		// 새로운 입력의 이동을 반영하기 전 정보를 넣음
		MoveStack.push(std::make_pair(AnimationNumber, CurDir)); 

		AnimationNumber = (AnimationNumber + 1) % 4;
	}
}
  • ReverseMove 하도록 세팅하는 함수
void ALerpMoveObject::ReverseMoveSetting(EInputDir _Dir, float _DeltaTime)
{
	IsMove = true;
	// 애니메이션 "방향"은 이전꺼여야 함.
	// 이동은 반대로.
	switch (_Dir)
	{
	case EInputDir::Right:
		AddNextActorLocation(FVector::Left * TileSize);
		NewInputDir = EInputDir::Right;	
		break;
	case EInputDir::Left:
		AddNextActorLocation(FVector::Right * TileSize);
		NewInputDir = EInputDir::Left;
		break;
	case EInputDir::Up:
		AddNextActorLocation(FVector::Down * TileSize);
		NewInputDir = EInputDir::Up;
		break;
	case EInputDir::Down:
		AddNextActorLocation(FVector::Up * TileSize);
		NewInputDir = EInputDir::Down;
		break;
	default:
		break;
	}
}

리소스 관련 메모

원본게임 1920 x 1080 화면에서 한 블록 사이즈 54 x 54
창 크기 1280 x 720 으로 만들면 한 블록 36 x 36 사이즈.

128 * 128로 자른 리소스에 내부 한 칸은 24 * 24 인듯?
리소스를 한칸 36 * 36으로 자르자

엔진

와우 너무 낙서라서 정리할 자신은 없음.

블렌드

"왜 검은색으로 나오냐?"
DestColor, SrcColor ← 이 두 개를 정확히 이해해야 블렌드에 대한 이해를 할 수 있음.

최초의 모니터 Clear색상 파랑일 때 Float4(0,0,1,1), 이걸 DestColor라고 한다.
이미지의 투명 부분 SrcColor라고 하는데 Float(0,0,0,0)일 것이다.

블렌드는 DESTCOLOR 연산자 SRCCOLOR 이다.

알파값은 따로 처리된다.

  • 연산자가 =일때

001 1 = 000 0 ⇒ DC가 000 됨. 덮어씌우는거

  • “+” 일 때

더하기가 아니라 옵션임. “+”말고 여러 연산자를 쓸 수 있다. 옵션 설정해서.

DESTCOLOR + SRCCOLOR

0011 + 0000

근데 알파값은 최종적으로 1이 된다. 우리가 윈도우 뒤가 보인 적이 있냐. 없음.

  • 블렌드 최종 공식
DestColor * DestFilter       +        SrcColor * SrcFilter 

Float3      Float3         연산자      Float3     Float3

우리가 바꿀 수 있는 건 연산자 : 더할거냐 뺄거냐

알파값은 따로 계산.

UEngineBlend 클래스 만듦.

AlphaToCoverageEnable ⇒ true로 하면 투명처리가 투명이 될 것인데 연산량 높아서 잘 안쓴다고 함. 다렉의 기본 공식으로 계산.

IndependentBlendEnable ⇒ true로 해두면 8개 하나씩 다 세팅해주는것, false는 다 0번 세팅으로 모두 통일

렌더타겟은 한 번 에 최대 8장까지 세팅가능. SV_Target 그림그릴곳 8개 세팅할 수 있고 블렌드 8개 할 수 있음.

0번에는 캐릭터만 그려 1번에는 몬스터만 그려 2번에는 무기만 그려. 타겟을 여러개 세팅할 수 있다는 것의 이득은 무궁무진함. 몬스터만 회색으로 칠하는 게 편해지는 등등.. 컵헤드 지지직거리는 효과 등등…

다렉 함수는 왜 빠르냐?
내부에서 SIMD 연산을 사용한다.
CPU에서 그래픽 카드와 같이 한번에 XYZW를 동시에 연산처리하는 기술
행렬 연산 빠르게하라고? 다렉에서 만든 자료형이 있음 DirectX::XMMATRIX, DirectX::XMVECTOR 언리얼에서도 씀. 다렉함수 쓰려면 이 자료형 써야 함.
내용은 SIMD연산 쓰는거 빼고 쌤이 계산하던거랑 다를 게 없다.

CPP

람다

IdleStart함수에서는 Idle애니메이션 만들기만 한다. 이런 경우 람다를 이용해서 코드를 많이 줄일 수 있음.

람다캡처의 내용안에 =을 쓰면 현재 스택에서 사용가능한 복사본을 만든다.
메모리를 할당해서 Renderer를 같은 이름으로 복사한다. 그래서 주솟값이 다르다.

State.SetStartFunction("Idle", [=]
	{
			// 새로운 함수다.
			// 스택이 달라진다.
			Renderer->ChangeAnimation("Idle");
	}
);
  • 장점 :
    코딩 치는 속력이 빨라진다. (헤더에 가서 IdleStart만들고 새로운 함수 정의할 필요 없음)
    간단한 함수는 람다 사용하는 것을 추천하신다고 함.
profile
일단 시작해보자
post-custom-banner

0개의 댓글