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 은 맵의 중앙에 플레이어를 배치시키는 부분이 들어있는 함수입니다.