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:

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 ;)

0

Aaaa, nie lubię pisać w unity czy ue4. Nie sprawia mi to frajdy. Lubie sobie właśnie posiedzieć nad takim czystym kodem, jest to przyjemne dla mnie. I jakby udało mi się kiedyś tak rozwinąć, to silnik fajnie też by było zrobić. Podoba mi się takie spędzanie czasu.
Jak wyglądałoby w takim razie coś "fajniejszego" i działającego do rzeczy typu przeciwnicy, strzelanie, itp.?

1
donpedro5555 napisał(a):

Jak wyglądałoby w takim razie coś "fajniejszego" i działającego do rzeczy typu przeciwnicy, strzelanie, itp.?

Najważniejsza jest możliwość osiągnięcia rzeczy podstawowych dla współczesnych gier (kolizje, fizyka, wyświetlanie, udźwiękowienie), zachowując porządek w projekcie (im mniej kodu piszemy, tym mniej błędów generujemy).

  1. Strzelanie.
  • Robisz sobie w edytorze prefab pocisku,
  • dołączasz do niego skrypty: collider (np. prostokąt, i zaznaczasz, że jest triggerem), rigidbody (ciało fizyczne), twój własny nowy skrypt dla pocisku;
  • w skrypcie dla pocisku piszesz kod, co pocisk ma robić w przypadku kolizji, czyli metodę OnTriggerEnter2D() (zmniejszenie życia wroga, pokazanie efektu cząsteczkowego, puszczenie dźwięku), oraz metodę Start(), która ustawia pociskowi wektor kierunku przemnożony przez prędkość pocisku;
  • w ustawieniach fizyki w macierzy kolizji klikasz sobie, że obiekty na warstwie pocisków mogą kolidować tylko z wrogami;
  • kiedy gracz chce strzelić, wystarczy dodać pocisk na scenę funkcją Instantiate(prefabPocisku, pozycjaPocisku, obrótPocisku);, pozycję i obrót można pobrać z obiektu, który dodajemy jako dziecko obiektu broni gracza. Skrypt pocisku zadba o to, żeby pocisk leciał i kolidował z wrogami ;)
  1. Przeciwnicy
    Podobnie jak przy pociskach, można zrobić prefaby przeciwników, które tylko dodajemy na scenę w odpowiednich miejscach, wspomagając się edytorem.

  2. Inne rzeczy
    W Unity każdy build na PC jest wyposażony w menu wyboru rozdzielczości. Do builda dołączane są wszystkie pliki potrzebne do uruchomienia gry.
    Efekty cząsteczkowe, animowanie modeli 3D, podział gry na sceny/poziomy. W Unity to zrobisz, nie pisząc żmudnego, wadliwego kodu.

0

Jak w takim razie powinna wyglądać taka funkcja Instantiate? Trochję szukałem w necie, nie znalazłem wnętrza tej metody żeby zrobić wzorzec i spróbować go w swoim kodzie.

0

Przerób sobie jakiś kurs Unity, zobacz co Instantiate robi. Zobacz jak wygląda drzewo obiektów w edytorze. Z doświadczeniem wyniesionym z innych silników, będziesz miał podstawy by zaprojektować własny.

Dostęp do kodu Unity też można uzyskać...

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