Grawitacja, a kolizja na jeden klocek przerwy

0

Witam! Tworzę platformówkę 2d, a mój problem polega na tym, że postać "nie widzi" dziur i gładko po niej przechodzi.

Mapę czytam z pliku, więc wczytałem id klocka w klasę vector

Vector2* GameplayScreen::IDklocka(int x, int y)
{
	return new Vector2(x < 0 ? 0 : x / 32, y > System::GetScreenHeight() ? 0 : (y + 32) / 32);
}

i sprawdzam kolizję za pomocą takiego kodu:

int GameplayScreen::checkCollision(Vector2* ID)
{
        //multiplierY - żeby zapobiegać wyskoczeniu za mapę
        // dodałem parę linijek 0 w pliku
        // te linijki przesuwają mapę lekko w dół, dlatego dodaję tutaj liczbę,
        // ilość dodanych linijek żeby kolizja działała dobrze
        // pewnie nie wyjaśniłem tego dobrze, nie oczekuje zrozumienia, można wykasować to
        // ale chciałem dać cały kod
        return atoi(map[ID->getY() + multiplierY - 1][ID->getX()].c_str());
}

i teraz sprawdzanie poszczególnych kątów postaci i zwrócenie true/false
Podzieliłem klocki na część lewą górną, prawą górną
i lewą dolną, prawą dolną

//Sprawdza pozycję i hitBox naszej postaci do id klocka
bool GameplayScreen::CollisionRightBottomPlayer(int x, int y, int hitBoxX, int hitBoxY)
{
	return checkCollision(IDklocka(x + hitBoxX, y + hitBoxY));
}
bool GameplayScreen::CollisionLeftBottomPlayer(int x, int y, int hitBoxY)
{
	return checkCollision(IDklocka(x, y + hitBoxY));
}

I klasa postaci

        // hitBoxX - szerokość postaci
        // hitBoxY - wysokość postaci
        // ->getPosX() i ->getPosY() - zwraca pozycję mapy, bo rusza się góra, dół, prawo, lewo, w zależności od pozycji postaci
	bool collisionLB = Config::getSM()->GetGame()->CollisionLeftBottomPlayer(posX - System::GetGameplayeScreen()->getPosX() + 2, posY - System::GetGameplayeScreen()->getPosY() + 2, HitBoxY);
	bool collisionRB = Config::getSM()->GetGame()->CollisionRightBottomPlayer(posX - System::GetGameplayScreen()->getPosX() - 2, posY - System::GetGameplayeScreen()->getPosY() + 2, HitBoxX, HitBoxY);

	if (!System::keySpace && velY < minJumpDist)
	{ 
                // minimalna wysokosc skoku -6.5
		velY = minJumpDist;
	}
	if (!collisionLB  && !collisionRB)
	{
		velY += gravity;
               // jumpState to różne stany postaci zapisany w enumie, np. w locie, spada, na ziemi itp.
		jumpState = Grounded;
	}
	else if (jumpState == Grounded)
	{
		resetJump();
	}
        // Updateuje posY i posiada dodatkowe funkcje
        // standartowe posY += velY
	UpdatePosY(velY / 3.2);
}

Tak jak wspominałem na początku, kiedy jest dziura w mapie 32x32 postać ją omija, nie wpada. Jak mógłbym to naprawić? Może powinienem zmienić sprawdzanie kolizji? Jeśli tak, to w jaki sposób powinienem to zrobić?

0

Sądzę, że powinieneś zaznajomić się z tutorialami:


A nawet lepiej zacząć kurs od samego początku ;)

Gość bardzo dokładnie wyjaśnia implementację kolizji i poruszania się w świecie 2D. Jak uda Ci się zaimplementować raycastowanie jak w Unity, to będziesz mógł bez bezpośredniego odwoływania się do terenu wiedzieć gdzie prostokąt postaci z czymś koliduje.

Przed wykonaniem ruchu w dowolnym kierunku sprawdzamy raycastem, czy nastąpi kolizja, jeśli tak, to zmniejszamy wektor ruchu tak aby ta kolizja w ogóle nie wystąpiła. Jeśli raycasty w dół wykazują, że nie mamy gruntu pod nogami, to zaczynamy spadać.

1 użytkowników online, w tym zalogowanych: 0, gości: 1