Broń, strzelanie, platformówka

0

Witam, próbuje zrobić strzelanie postaci. Gdy próbuje strzelić wyskakuje błąd, który mówi, że wyszedłem za range wektora.
Posiadam klasę Entity, która odpowiada za pozycje postaci itd., jak i za broń, a tak naprawdę kule. Klasa GameplayScreen odpowiada za to co się dzieje na mapie, wczytuje tile map, postacie i obrazy. Stworzyłem dwuwymiarowy wektor Entity std::vector<std::vector<Entity*>> vEntity; i metodę, która "tworzy broń". Tą metodę wywołuję w czasie, kiedy przycisnę dobry przycisk, w tym czasie gra się kraszuje i wyskakuje błąd.
Tak wygląda kod : https://pastebin.com/0DmUdsRd

System::getManager() zwraca klasę, która wczytuje np. menu, opcje, nową gre itd. ->getGame() zwraca instancje do GameplayScreen ->getGame()->getPosX() zwraca pozycje x mapy (mapa się rusza jeśli pozycja postaci jest większa niż pozycja ekranu). vEntity[i][j]->getBlockID() zwraca numer obrazka, w tym przypadku 4, ustawione w klasie PlayerGun oznacza grafikę kuli.

Projekt wzorowany https://github.com/jakowskidev/uMario_Jakowski

0

W metodzie Update usuwasz elementy vectora, po którym iterujesz. Najlepiej w takich przypadkach iterować w odwrotnej kolejności (od końca).

0

Od końca, to znaczy?

0

To znaczy, że w pętli zamiast od pierwszego indeksu (0), iterujesz od ostatniego indeksu.

0
	for (int i = vEntity.size() - 1; i >= 0; i--)
	{
		for (int j = vEntity[i].size() - 1; j >= 0; j--)
		{
			if (vEntity[i][j]->entityState == -1)
			{
				delete vEntity[i][j];
				vEntity[i].erase(vEntity[i].begin() + j);
				continue;
			}
		}
	}

Coś takiego? Tylko tego punktu zrobić tak, czy dla całej metody? Co to zmienia? Nadal w sumie jest błąd.

2

Jest tak, bo masz warunek na usunięcie, więc nie wszystko jest usuwane po kolei. Podczas usuwania iteratory są "invalidowane" co oznacza, że nie mozesz ich już używać. Nejlepiej użyć funkcji std::remove_if:

for (int i = vEntity = 0; i < vEntity.size(); i++)
    {

        vEntity[i].erase(
            std::remove_if(
                vEntity[i].begin(), 
                vEntity[i].end(), 
                [](const Entity* entity){ return entity->entityState == -1; }
            ), 
            vEntity[i].end());
    }

Wówczas powinno zadziałać.
Więcej informacji na temat remove i remove_if masz tutaj.

0

Oki, wszystko fajnie, tylko nadal pokazuje się błąd: "(vector subscript out of range");. Tutaj coś jest skopcone z dodawaniem do vectora w metodzie addPlayerGun(int, int, int);

0

źle, że odwołujesz się do tego vectora przez magic number.

Skoro piszesz nową aplikację, to może skorzystaj ze smart pointerów?

Czy musisz pisać własny silnik, czy po prostu nie znasz innych opcji, żeby stworzyć własną grę?

0

Szczerze, nie jestem jeszcze w tych sprawach tak obeznany, chce po prostu się czegoś nowego nauczyć. NIe chce żeby było to na jakiejś "prostackiej" zasadzie, chociaż skoro nie działa to nie jest na żadnej zasadzie :D. Nie rozumiem ostatniego pytania.

0
donpedro5555 napisał(a):

Nie rozumiem ostatniego pytania.

To co teraz robisz jest dość "niskopoziomowe". Jeśli nikt Cię nie zmusza, żebyś pisał grę "na czysto", to poleciłbym zapoznanie się z Unity 3D.
Tam po prostu dodajesz obiekty na scenę i one po prostu się renderują ;) Jeśli to gra 2D, to jak chcesz mieć obiekty renderowane w odpowiedniej kolejności, po prostu ustawiasz dla obrazków (sprite'ów) odpowiedni sorting layer i sorting order.

Jak tworzysz nowy obiekt, to nie musisz się martwić o to, czy dodasz go do odpowiedniego wektora. Po prostu dodajesz go gdzieś w drzewie obiektów, ewentualnie ustawiając obiekt rodzica.

Jeśli nie chcesz być programistą silników, tylko chcesz stworzyć grę, to przy obecnych technologiach nie ma sensu, żebyś zawracał sobie głowę tym co teraz robisz ;)

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