Tworzenie gry w C# z użyciem silnika Ogre - cz.4

15.01.2011 - Mateusz Osowski
TrudnośćTrudność

Przebieg rozmowy

Konwersacja z bohaterami niezależnymi przebiegać będzie zgodnie ze schematem:

Każdy dialog zaczynać się będzie kwestią bohatera niezależnego. W szczególności może być to kwestia pusta. Następnie graczowi zaprezentowane zostaną możliwości odpowiedzi. Dla uproszczenia implementacji graficznego interfejsu ograniczymy ich liczbę do ośmiu. Nie oznacza to jednak ograniczenia liczby możliwych faktycznych odpowiedzi - można bowiem przemianować ostatnią opcję na "Więcej..." i sprawić, by prowadziła poprzez pustą reakcję BN do dodatkowych odpowiedzi. Gdybyśmy chcieli mieć możliwość wyświetlenia większej liczby opcji na ekranie, należałoby zaimplementować kontrolkę listy lub też zastosować gotowy, rozbudowany system graficznego interfejsu użytkownika, przykładowo MyGUI, czy też QuickGUI. Wybrana opcja wyróżniać się będzie kolorem czcionki. Zatwierdzenie wyboru doprowadzi do wyświetlenia kwestii gracza na ekranie. Następnie, w zależności od tego, czy wybrana odpowiedź prowadzi do końca rozmowy - nastąpić może wyjście ze stanu konwersacji. Za obsługę tego stanu odpowiadać będzie klasa HumanController. Odpowiednie informacje muszą znaleźć się w tej klasie:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class HumanController
{
  public enum HumanControllerState
  {
    FREE,
    TALK
  }
 
  public enum HumanTalkState
  {
    CHOOSING_REPLY,
    REPLYING,
    LISTENING,
    PAUSE 
  }
HumanController.cs


Nazwy pól typu wyliczeniowego HumanControllerState pozwolą rozróżnić nowy stan gry. Typ HumanTalkState oprócz trzech oczywistych podstanów wprowadza stan pauzy. Pozwoli on na oddzielenie wypowiedzi bohatera gracza od reakcji bohatera niezależnego krótkim odstępem.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  ...
  SimpleQuad TalkBox;
  List<TextLabel> TalkLabels;
 
  HumanControllerState State;
  HumanTalkState TalkState;
 
  List<TalkReply> ValidReplies;
  int SelectedReply = 0;
 
  float TextRemainingTime = 0.0f;        
  int TextIndex;
  TalkReply CurrentReply;
  TalkNode CurrentNode;
HumanController.cs


Pole TalkBox reprezentować będzie szary prostokąt stanowiący tło dla wypowiedzi i opcji odpowiedzi. TalkLabels będzie listą etykiet tekstowych wykorzystywanych do wyświetlania konwersacji. Zgodnie z projektem - będzie ich osiem, przy czym ostatnia, najniżej położona będzie wykorzystywana także do wyświetlania wypowiadanych kwestii. Lista ValidReplies przechowywać będzie odpowiedzi gracza, których predykaty wstępne zostały spełnione. SelectedReply będzie indeksem wybranej spośród poprawnych odpowiedzi. Licznik TextRemainingTime odliczać będzie czas, przez który ma być wyświetlana aktualna kwestia. TextIndex pozwoli iterować przez listę wyświetlanych zdań, zaś CurrentNode określać będzie aktualną pozycję w drzewie konwersacji.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public HumanController()
{            
  TargetLabel = Engine.Singleton.Labeler.NewTextLabel3D(
    "Primitive", 0.04f, 
    new ColourValue(0.7f, 0.4f, 0), new ColourValue(1, 1.0f, 0.6f), 0);
 
  TalkBox = Engine.Singleton.Labeler.NewSimpleQuad(
    "QuadMaterial", 0.05f, 0.85f, 0.9f, 0.1f, new ColourValue(1, 1, 1), 1);
  TalkBox.IsVisible = false;
 
  TalkLabels = new List<TextLabel>();
  for (int i = 0; i < 8; i++)
  {
    TalkLabels.Add(Engine.Singleton.Labeler.NewTextLabel(
      "Primitive", 0.04f, 
      new ColourValue(0.7f, 0.4f, 0), new ColourValue(1, 1.0f, 0.6f), 2));
    TalkLabels[i].SetPosition(0.07f, 0.63f + i * 0.037f);
  }
  ValidReplies = new List<TalkReply>();
}
 
HumanController.cs


Pętla w wierszu 9 tworzy osiem etykiet ustawionych jedna pod drugą w odstępie 0.037 wysokości ekranu. Jest to umowna wartość dobrana metodą prób i błędów.

Potrzebujemy metody ukrywającej wszystkie elementy związane z trybem konwersacji:

1
2
3
4
5
6
  public void HideTalkOverlay()
  {
    foreach (TextLabel lab in TalkLabels) lab.IsVisible = false;
    TalkBox.IsVisible = false;            
  }
 
HumanController.cs


Ukrywamy wszystkie etykiety i okienko tła.
1
2
3
4
5
6
  public void BeginTextDisplay(TalkText text)
  {
    TalkLabels.Last().Caption = text.Text;
    TalkLabels.Last().SetPosition(0.5f - TalkLabels.Last().GetTextWidth() * 0.5f, 0.889f);
    TextRemainingTime = text.Duration;
  }
HumanController.cs


Metoda BeginTextDisplay, jak sama nazwa wskazuje, rozpoczyna wyświetlanie jednego zdania. Etykieta pozycjonowana jest na środku szerokości ekranu.
1
2
3
4
5
6
7
  public void ShowReplies()
  {
    TalkBox.IsVisible = true;
    foreach (TextLabel lab in TalkLabels) lab.IsVisible = true;
    TalkBox.SetDimensions(0.05f, 0.6f, 0.9f, 0.35f);  
    TalkLabels.Last().SetPosition(0.07f, TalkLabels.Last().TextArea.Top);    
  }
HumanController.cs


Ta metoda będzie odpowiedzialna za wyświetlenie okienka odpowiedzi gracza. W wierszu 5 zmieniamy rozmiar prostokąta tła tak, by pokrywał wszystkie etykiety. Ostatnią etykietę przesuwamy do lewej krawędzi ramki, ponieważ podczas wyświetlania kwestii znajdowała się na środku szerokości ekranu.
1
2
3
4
5
6
7
  public void ShowTalkBox()
  {
    TalkBox.IsVisible = true;
    foreach (TextLabel lab in TalkLabels) lab.IsVisible = false;
    TalkLabels.Last().IsVisible = true;            
    TalkBox.SetDimensions(0.05f, 0.85f, 0.9f, 0.1f);
  }
HumanController.cs


Metoda ShowTalkBox przygotowuje interfejs do wyświetlenia kwestii - ukrywa wszystkie za wyjątkiem ostatniej etykiety i zmniejsza prostokąt tła tak, by ją pokrywał.
1
2
3
4
5
6
7
8
9
10
11
12
  public void UpdateRepliesColours()
  {
    for (int i = 0; i < ValidReplies.Count; i++)
    {
      if (i == SelectedReply)
        TalkLabels[i].SetColor(
          new ColourValue(1, 1, 1), new ColourValue(1, 1, 1));
      else
        TalkLabels[i].SetColor(
          new ColourValue(0.7f, 0.4f, 0), new ColourValue(1, 1.0f, 0.6f));
    }
  }
HumanController.cs


Wybrana odpowiedź oznaczona będzie kolorem białym, pozostałe zaś jasnożółtym gradientem.
5
Twoja ocena: Brak Ocena: 5 (2 ocen)

Copyright © 2008-2010 Wrocławski Portal Informatyczny

design: rafalpolito.com