버그 해결을 위한 모든 질문을 던져
0 votes
172 views
bool Rigidbody::OnRectColliderEnter_Check_PLAYER(PlayerObject* player, Rect& playercol, ColliderInfo& mapinfo) {

	PlayerScript* pScript = player->GetComponent<PlayerScript>();
	Rect Mapcol = mapinfo.col;
	Rect Mergecol;

	if (mapinfo.nType != 0) {
		return false;
	}

	std::function<bool()> SetPosition = [&]() mutable -> bool {
		Vector2 movew = player->GetWorldPosition() + m_strstay.m_coord;
		Vector2 move = player->GetPosition() + m_strstay.m_coord;
		pScript->SetComparePosition(move, movew);
		m_strstay.m_coord = Vector2::Zero;
		return true;
	};

	Mergecol.Left = (playercol.Left > Mapcol.Left) ? playercol.Left : Mapcol.Left;
	Mergecol.Right = (playercol.Right < Mapcol.Right) ? playercol.Right : Mapcol.Right;
	Mergecol.Top = (playercol.Top > Mapcol.Top) ? playercol.Top : Mapcol.Top;
	Mergecol.Bottom = (playercol.Bottom < Mapcol.Bottom) ? playercol.Bottom : Mapcol.Bottom;

	float MergecolHorizontal = Mergecol.Right - Mergecol.Left;
	float MergecolVertical = Mergecol.Bottom - Mergecol.Top;

	if (MergecolHorizontal < MergecolVertical)
	{
		// 수평 충돌
		if (playercol.Right > Mapcol.Right && playercol.Left > Mapcol.Left || playercol.Left < Mapcol.Left && playercol.Right < Mapcol.Right)
		{
			if (Mergecol.Right == Mapcol.Right)
			{
				m_strstay.m_coord.x = MergecolHorizontal;
				player->SetBlockState(LEFT_BLOCK);
			}
			else if (Mergecol.Left == Mapcol.Left)
			{
				m_strstay.m_coord.x = -MergecolHorizontal;
				player->SetBlockState(RIGHT_BLOCK);
			}
			m_strstay.m_bOnHWall = true;
			return SetPosition();
		}
	}
	else
	{
		// 수직 충돌
		if (playercol.Bottom > Mapcol.Top && playercol.Top < Mapcol.Bottom || playercol.Top < Mapcol.Bottom && playercol.Bottom > Mapcol.Top)
		{
			if (Mergecol.Top == Mapcol.Top) { // 바닥 착지
				m_strstay.m_coord.y = -MergecolVertical + /*보정값*/2;
				m_strstay.m_bOnMap = true;
				player->SetJump(false);
				SetGravity(Vector2::Zero);
			}

			else if (Mergecol.Bottom == Mapcol.Bottom) { // 천장 충돌
				m_strstay.m_coord.y = MergecolVertical;
			}
			return SetPosition();
		}
	}
	return false;
}

void PlayerScript::SetComparePosition(Vector2 vPos, Vector2 vWorldPos)
{
	Rect screen = GAME_MGR->Getrect();
	double recthalfsize_X = screen.Right / 2;
	double recthalfsize_Y = screen.Bottom / 2;

	if (IsScrolling(true)) {
		vPos.x = recthalfsize_X;
	}

	if (IsScrolling(false)) {
		vPos.y = recthalfsize_Y;
	}

	m_pPlayer->SetPosition(vPos);
	m_pPlayer->SetWorldPosition(vWorldPos);
}

void PlayerScript::ProcessPlayer(float dt)
{
	if (input::GetKey(VK_LEFT))
		m_ChangeDirection = false;
	else if (input::GetKey(VK_RIGHT))
		m_ChangeDirection = true;

	m_pPlayer->SetDirection(m_ChangeDirection);
	m_pPlayer->GetShotpos()->ShotPosChangeofDir(m_ChangeDirection);

	ChangePlayerAnimState(m_pMachine->GetCurAnimState());

	if (m_pRigidbody->OnRectColliderEnter_PLAYER(m_pPlayer)) {
		
	}
	else if (m_pRigidbody->GetGravity() == Vector2::Zero) {
		m_pRigidbody->SetGravity(Vector2(0, 300.f));
	}
}

void Camera2D::Scroll(PlayerObject* player, Vector2 rectpoint)
{
	PlayerScript* script = player->GetComponent<PlayerScript>();
	Vector2 point = player->GetWorldPosition();
	Vector2 prevCamPos = m_tr->GetPosition();
	float rectcenterX = rectpoint.x *0.5;
	float rectcenterY = rectpoint.y *0.5;
	Vector2 calcCameraPoint = (point - (rectpoint / 2)) *(-1); // 이미지는 반대로 움직여야한다.
	Vector2 moveCameraPoint = Vector2::Zero;

	if (point.x >= rectcenterX && point.x <= m_mapRect.x - rectpoint.x / 2)
	{
		m_tr->SetPosition(Vector2(calcCameraPoint.x, m_tr->GetPosition().y));
	}
	else
	{
		if(m_tr->GetPosition().x > 0)
			m_tr->SetPosition(Vector2(0, m_tr->GetPosition().y));
		else if(m_tr->GetPosition().x < -(m_mapRect.x - rectcenterX)) // (맵 최대치 - 화면 절반) *(-1) 보다 작으면 허용치를 넘은것.
			m_tr->SetPosition(Vector2(-(m_mapRect.x - rectcenterX), m_tr->GetPosition().y));
	}

	if (point.y >= rectcenterY && point.y <= m_mapRect.y - rectpoint.y / 2)
	{
		m_tr->SetPosition(Vector2(m_tr->GetPosition().x, calcCameraPoint.y));
	}
	else
	{
		if (m_tr->GetPosition().y > 0)
			m_tr->SetPosition(Vector2(m_tr->GetPosition().x, 0));
		else if (m_tr->GetPosition().y < -(m_mapRect.y - rectcenterY)) // (맵 최대치 - 화면 절반) *(-1) 보다 작으면 허용치를 넘은것.
			m_tr->SetPosition(Vector2(m_tr->GetPosition().x ,-(m_mapRect.y - rectcenterY)));
	}
}

 

게임 프로그래밍을 독학하고있는 학생입니다! 현재 2d winapi 횡스크롤 게임을 만드는데, 렉트 충돌로 모든 충돌을 구현 하고 있습니다. 그리고 맵은 흔히 보이는 마리오나 소닉 같이 스크롤링해서 움직이려고 하는데요, 캐릭터를 중심에 두고 클라이언트 화면 (윈도우 크기) 의 반을 수직이든 수평이든 넘어가면 캐릭터는 가운데에 이미지를 위치시키고 맵을 스크롤링 하는 방식인데요, 수평을 움직일때는 문제없습니다. 수직도 움직이긴하는데, 문제는 수직스크롤링 시에 반을 넘어가면 맵을 스크롤링 하는데 충돌 검사가 잘못된 탓인지, 아니면 화면에 강제로 중앙으로 위치시키는 동작 때문인지 맵이 위아래로 가끔씩 버벅입니다. 그래서 지진난것처럼 보이구요.. 제가 너무 어렵게 코딩하는것 같아서, 어떻게 하면 효과적으로 중력을 포함해 맵을 스크롤링 할 수 있을까요? 주위에 게임 프로그래머가 없어서 여기에 질문드려요.. ㅠㅠ 코드 스니펫은 관련된 코드의 함수들이구요. processplayer는 항상 업데이트 되는 업데이트 함수입니다. setcompareposition 은 맵의 중앙에 플레이어를 배치시키는 부분이 들어있는 함수입니다. 

asked (2 point)
수정됨 , 172 views

1 답변

+1 vote

아래 조건문이 잘 이해가 가지 않습니다 정확히 어떤 상황을 처리하고 싶으셨던 건가요?

일단 &&와 ||가 괄호 없이 연결되어 있어서 실제 작동이 의도처럼 되고 있을지부터도 조금 의심이 되기는 하는데;;

// 수직 충돌 
if (playercol.Bottom > Mapcol.Top && playercol.Top < Mapcol.Bottom || playercol.Top < Mapcol.Bottom && playercol.Bottom > Mapcol.Top) {

 

answered (89 point)
음.. 지금보니 의심이 조금 가네요.. 충돌 검사는 의도대로 되는것 같아 보여서 냅두었는데..

or 연산자 이전 부분은 플레이어 렉트의 bottom 값이 맵 렉트 top 보다 크면 안으로 들어간 것으로 판단하여 충돌 판정이 되고, 확실하게 검사하기 위해 플레이어 렉트의 top 이 맵 렉트의 bottom 보다 작으면 정상적인 렉트 충돌로 판정하는 것입니다. or 이후는 반대의 상황이구요 (천장 충돌)

버그 해결을 위해 도움을 구하고, 도움을 주세요. 우리는 그렇게 발전합니다.

throw bug 는 프로그래밍에 대한 전분야를 다룹니다. 질문,논의거리,팁,정보공유 모든 것이 가능합니다. 프로그래밍과 관련이 없는 내용은 환영받지 못합니다.

96 질문
186 answers
194 댓글
211 users