• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

SFML dynamiczny obiekt

Object Storage Arubacloud
0 głosów
471 wizyt
pytanie zadane 3 września 2016 w C i C++ przez sofnir Gaduła (4,690 p.)

[SFML]

Hej, mam problem, z którym nie potrafię sobie poradzić.

Zrobiłem klasę, która dziedziczy po Drawable i może być rysowana. Chciałbym móc tworzyć obiekt tej klasy w sposób dynamiczny, a gdy nie będzie mi on już potrzebny usunąć go. Dla uproszczenia przyjmijmy, że jest to gra, w której sterujemy ludzikiem, który jest nekromantą i ma moc przywoływania nieumarłych. Jeśli rzucimy magiczne zaklęcie, z ziemi wyrasta wampir (dynamicznie tworzymy obiekt). Ten wampir jest obiektem naszej klasy. Jeśli wampir wejdzie w nasłonecznione miejsce ma natychmiastowo zostać zniszczony (niszczymy nasz dynamiczny obiekt). 

Mam problem jak się do tego zabrać. W pętli gry zrobię sobie warunek,np. jeśli wciśniesz F1 to przyzwij wampira:

if (event.type == Event::KeyReleased && event.key.code == Keyboard::F1)
 Wampir *wampir = new Wampir;

Tylko jak teraz go narysować? 

_window->draw(*wampir);

To nie ma prawa zadziałać, dlatego zrobiłem dodatkowy wskaźnik i zmienną w głównej klasie:

Dialog *_dialog;
bool exist = false;

Wówczas:

if (event.type == Event::KeyReleased && event.key.code == Keyboard::F1)
{
 Dialog *dialog = new Dialog;
 _dialog = dialog;

 exist = true;
}

if(exist) _window->draw(*_dialog);

else if (event.type == Event::KeyReleased && event.key.code == Keyboard::F2)
{
  exist = false;
  delete _dialog;
}

Wtedy to działa, ale drażni mnie to, że musiałem stworzyć dodatkową zmienną i wskaźnik i za każdym razem, kiedy będę chciał użyć obiektu wampir lub jego metody muszę sprawdzać if (exist). Wydaje mi się, że źle to robię i jest na to jakiś sposób. Bo wyobrażam sobie, że mam grę w której może być sto różnych dynamicznych obiektów i wtedy do każdego obiektu robić wskaźnik i zmienną exist, a potem sprawdzać za każdym razem czy exist == true to by była jakaś masakra.

Zatem moje pytanie, jak za takie coś zabrać prawidłowo?

1 odpowiedź

+1 głos
odpowiedź 3 września 2016 przez damek1010 Obywatel (1,880 p.)
wybrane 3 września 2016 przez sofnir
 
Najlepsza
Jeżeli ma być wiele obiektów typu Wampir możesz stworzyć tablicę dynamiczną dla nich. Iterując po takiej tablicy rysujesz każdy obiekt. Jeżeli zawsze ma być maksymalnie jeden wystarczy wskaźnik. Kiedy obiekt ma zostać zniszczony ustawiasz go na NULL i po sprawie. W tym przypadku przed narysowaniem trzeba sprawdzić czy wskaźnik nie jest ustawiony na NULL.
komentarz 3 września 2016 przez C☺ndzi Stary wyjadacz (12,100 p.)

*nullptr, bardziej C++owe niż NULL wink

komentarz 3 września 2016 przez damek1010 Obywatel (1,880 p.)
nullptr jest w C++11, więc NULL jest bardziej uniwersalne :)
komentarz 3 września 2016 przez sofnir Gaduła (4,690 p.)
No spoko, działa :) Teraz to ma większy sens. Miałeś na myśli, że wskaźnik ustawiam na NULL? tzn. _wampir  = NULL i sprawdzanie if (wampir != NULL) _window->draw(*_wampir);?

Tylko co wtedy się dzieje z moim obiektem, on sobie gdzieś hula, czy jest usuwany z pamięci?
komentarz 3 września 2016 przez adrian17 Ekspert (344,860 p.)

C++ jest od 1983, więc C jest bardziej uniwersalne :)

C++ jest od 1983, więc C jest bardziej uniwersalne :)

A tak poważnie... daj spokój, każdy dzisiejszy popularny kompilator na x86 wspiera nullptr. Po to są nowe standardy, by je używać.

komentarz 3 września 2016 przez adrian17 Ekspert (344,860 p.)

Kiedy obiekt ma zostać zniszczony ustawiasz go na NULL i po sprawie. W tym przypadku przed narysowaniem trzeba sprawdzić czy wskaźnik nie jest ustawiony na NULL.

Prościej: std::vector<Typ *>.

Chcesz dodać obiekt? vec.push_back(wskaznik)

Chcesz usunąć?

delete vec[i];
vec.erase(vec.begin() + i);

Nie trzeba się przejmować nullami, bo sami gwarantujemy że w vectorze są tylko istniejące obiekty.

 

komentarz 3 września 2016 przez Lafoniz Gaduła (4,370 p.)

Mam do Was pytania. Po co wskaźniki zamiast zwykłego typu? Skoro już wybraliście wskaźniki, dlaczego chcecie manualnie zarządzać ich pamięcią i narażać się na różne nieprzyjemności?

Jak już ktoś proponuje wykorzystanie nullptr zamiast makra NULL, to radzę podać powody. Wtedy inni będą bardziej skłonni słuchać.

komentarz 3 września 2016 przez sofnir Gaduła (4,690 p.)

Użyłem klasy szablonowej vector i wtedy mam:

for (int i = 0; i < vectorowaTablicaWskaznokow.size(); i++)
  _window->draw(*vectorowaTablicaWskaznokow[i]);

O to ci chodziło? Tylko co jeśli maksymalnie korzystam z jednego obiektu? Wtedy też działa, ale czy wtedy jest sens z tego korzystać? Bo zgadzam się, że dla wielu obiektów ten vector jest wygodniejszy, ale jeśli mam jeden, to może faktycznie ten NULL będzie lepszy, bo wtedy nie muszę robić pętli for?

PS Lafoniz - korzystamy ze wskaźników, bo tworzymy obiekt dynamiczny.

komentarz 3 września 2016 przez damek1010 Obywatel (1,880 p.)
Jak ma być maksymalnie jeden obiekt danego typu w grze to moim zdaniem bez sensu jest używać vectora. Lepiej skorzystać ze wskaźnika- wtedy kod jest bardziej przejrzysty.

Podobne pytania

0 głosów
0 odpowiedzi 411 wizyt
pytanie zadane 11 czerwca 2016 w C i C++ przez L33TT12 Gaduła (3,950 p.)
0 głosów
1 odpowiedź 471 wizyt
pytanie zadane 26 czerwca 2017 w HTML i CSS przez sapero Gaduła (4,100 p.)
0 głosów
3 odpowiedzi 607 wizyt
pytanie zadane 7 stycznia 2017 w C i C++ przez Evelek Nałogowiec (28,960 p.)

92,555 zapytań

141,403 odpowiedzi

319,554 komentarzy

61,940 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...