tBane Temat założony przez niniejszego użytkownika |
Prosty System Dialogów » 2024-06-02 20:56:50 Witam. Napisałem prosty system Dialogów. Co o nim sądzicie ? #ifndef Dialogues_hpp #define Dialogues_hpp
class DialogueOption { public: string text; int nextDialogueID; DialogueOption( string text, int nextDialogueID ) { this->text = text; this->nextDialogueID = nextDialogueID; } };
class Dialogue { public: int id; string text; std::vector < DialogueOption > options; Dialogue( int id, string text ) { this->id = id; this->text = text; } };
std::vector < Dialogue * > dialogues; Dialogue * currentDialogue;
enum class dialogueStates { dialogue, choose };
dialogueStates dialogueState; int chooseOption = 0;
void loadDialogues() { dialogues.clear(); Dialogue * dial0 = new Dialogue( 0, "Witam w grze One - The Beginning." ); dial0->options.push_back( DialogueOption( "ok", - 1 ) ); Dialogue * dial1 = new Dialogue( 1, "Witaj w czym mogę Ci pomóc?" ); dial1->options.push_back( DialogueOption( "Kim Jesteś?", 2 ) ); dial1->options.push_back( DialogueOption( "Co tutaj robisz?", 3 ) ); dial1->options.push_back( DialogueOption( "Żegnaj.", - 1 ) ); dialogues.push_back( dial1 ); Dialogue * dial2 = new Dialogue( 2, "Nazywam się Jack i jestem handlarzem, chcesz może rzucić okiem na moje towary?" ); dial2->options.push_back( DialogueOption( "Kim Jesteś?", 2 ) ); dial2->options.push_back( DialogueOption( "Co tutaj robisz?", 3 ) ); dial2->options.push_back( DialogueOption( "Żegnaj.", - 1 ) ); dialogues.push_back( dial2 ); Dialogue * dial3 = new Dialogue( 3, "Hanlduje towarami, a na co Ci to wygląda?" ); dial3->options.push_back( DialogueOption( "Kim Jesteś?", 2 ) ); dial3->options.push_back( DialogueOption( "Co tutaj robisz?", 3 ) ); dial3->options.push_back( DialogueOption( "Żegnaj.", - 1 ) ); dialogues.push_back( dial3 ); Dialogue * dial4 = new Dialogue( 4, "Czego chcesz od starego Johna. Daj mi spokój" ); dial4->options.push_back( DialogueOption( "Ja tylko chciałem...", - 1 ) ); dialogues.push_back( dial4 ); }
Dialogue * getDialogue( int id ) { for( auto & d: dialogues ) if( d->id == id ) return d; cout << "incorrect dialog id\n"; return nullptr; } #endif
|
|
pekfos |
» 2024-06-02 22:30:01 Jeśli działa, to działa. Undertale ma dialogi w jednym wielkim switch case, więc Twój mechanizm nie jest złym pierwszym podejściem ;) Co do samego kodu
Powtórzenia możesz wyeliminować rozdzielając opcje dialogowe od wyświetlanego tekstu. Na przykład: |
|
tBane Temat założony przez niniejszego użytkownika |
» 2024-06-03 18:47:10 No właśnie jeszcze nie zastanawiałem się nad tym. Pewnie będzie trzeba stworzyć cały system skryptów. Na początek stworzyłem dialog, który będzie potrzebował dodatkowego przetwarzania tzn. będzie potrzebował jakiegoś skryptu, który sprawdzi czy gracz posiada określony item w danej ilości. Dialogue* dial5 = new Dialogue(5, L"Czego chcesz?"); dial5->options.push_back(DialogueOption(L"Kim jesteś?", 6)); dial5->options.push_back(DialogueOption(L"Co tutaj robisz?", 7)); dial5->options.push_back(DialogueOption(L"Mam skórę wilczura, chcesz ją odkupić?", 8)); dial5->options.push_back(DialogueOption(L"Żegnaj", -1)); dialogues.push_back(dial5);
Dialogue* dial6 = new Dialogue(6, L"Jestem myśliwym. Poluję na zwierzynę."); dial6->options.push_back(DialogueOption(L"Kim jesteś?", 6)); dial6->options.push_back(DialogueOption(L"Co tutaj robisz?", 7)); dial6->options.push_back(DialogueOption(L"Mam skórę wilczura, chcesz ją odkupić?", 8)); dial6->options.push_back(DialogueOption(L"Żegnaj", -1)); dialogues.push_back(dial6);
Dialogue* dial7 = new Dialogue(7, L"Obecnie odpoczywam, ale gdy tylko zbiorę siły, ruszę na polowanie."); dial7->options.push_back(DialogueOption(L"Kim jesteś?", 6)); dial7->options.push_back(DialogueOption(L"Co tutaj robisz?", 7)); dial7->options.push_back(DialogueOption(L"Mam skórę wilczura, chcesz ją odkupić?", 8)); dial7->options.push_back(DialogueOption(L"Żegnaj", -1)); dialogues.push_back(dial7);
Dialogue* dial8 = new Dialogue(8, L"Bardzo chętnie, dam ci za nią miksturę leczniczą."); dial8->options.push_back(DialogueOption(L"Proszę, oto skóra wilczura", 5)); dial8->options.push_back(DialogueOption(L"Może innym razem ... ", 5)); dialogues.push_back(dial8);
teraz ten dialog bym oskryptował np. tak dial7->options.push_back(DialogueOption(L"<ifItem "wolf skin" 1>Mam skórę wilczura, chcesz ją odkupić?", 8)); wtedy by trzeba było za każdym razem gdy chcemy wyświetlić dialog sprawdzić czy spełnia on warunki. W dobrą stronę idę tym tokiem rozumowania ? |
|
pekfos |
» 2024-06-03 19:31:08 Jeżeli nie planujesz wczytywać tych dialogów z pliku, skryptowanie mija się z celem. Skoro wszystkie dialogi są wprost w kodzie, możesz warunki wyrazić w C++. Do DialogueOption możesz dodać pole std::function<bool()> z opcjonalnym predykatem mówiącym czy opcja dialogowa powinna być dołączona. dial7->options.push_back( DialogueOption( L"Mam skórę wilczura, chcesz ją odkupić?", 8,[ ] { return player->getNumberOfItems( "wolf skin" ) > 0; } ) );
i wchodząc z stan z opcjami do wyboru byś przygotowywał efektywne opcje na podstawie wyniku warunku for( auto & option: dial->options ) { if( option.condition && !option.condition() ) continue; effectiveOptions.push_back( option ); } |
|
tBane Temat założony przez niniejszego użytkownika |
» 2024-06-03 19:36:00 ok. Spróbuję tym sposobem. Co oznaczają te nawiasy kwadratowe ?
[ ] { return player->getNumberOfItems( "wolf skin" ) > 0; } ) ); |
|
pekfos |
» 2024-06-03 19:39:49 To jest składnia wyrażenia lambda. Można powiedzieć że to anonimowa funkcja definiowana w miejscu użycia ( Wyrażenia lambda (C++11)). |
|
tBane Temat założony przez niniejszego użytkownika |
» 2024-06-03 20:28:23 jednak to Lambda się nie sprawdza za dużo kombinowania z dopisywaniem funkcji do każdej opcji dialogowej. Lepiej jak oskryptuję text po prostu. |
|
pekfos |
» 2024-06-03 21:13:44 Ale jak do każdej? Nagle wszystkie opcje są warunkowe? Domyślnie byś miał brak warunku. DialogueOption( string text, int nextDialogueID, std::function < bool() > cond = { } ) { }
dial7->options.push_back( DialogueOption( L"Mam skórę wilczura, chcesz ją odkupić?", 8,[ ] { return player->getNumberOfItems( "wolf skin" ) > 0; } ) ); dial7->options.push_back( DialogueOption( L"Żegnaj", - 1 ) ); |
|
« 1 » 2 3 4 |