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

15.01.2011 - Mateusz Osowski
TrudnośćTrudność

Zmiany w klasie TextLabeler

Zanim będziemy w stanie zrealizować wyświetlanie i odtwarzanie dialogów w należyty sposób, musimy dokonać pewnych usprawnień klasy TextLabeler. Do tej pory wszystkie tworzone etykiety tekstowe trafiały na jedną warstwę wyznaczaną przez obiekt nakładki. Nie mamy przez to możliwości określenia kolejności wyświetlania etykiet. Rodzi to także problemy z ustawianiem etykiety nad prostokątami służącymi za okienka rozmowy. Rozwiążemy ten problem zastępując pojedynczy obiekt klasy Overlay listą podobnych obiektów. W pierwszej kolejności stworzymy prostą klasę odpowiedzialną za wyświetlanie oteksturowanych prostokątów:

1
2
3
class SimpleQuad
{        
  public OverlayContainer Panel;
SimpleQuad.cs


Pole Panel będzie jedynym polem nowej klasy. Wykorzystamy jego właściwość MaterialName i wymiary.

Konstruktor prezentuje się następująco:

1
2
3
4
5
6
7
8
9
10
11
12
  public SimpleQuad(String name, String materialName, 
    float left, float top, float width, 
    float height, ColourValue colour)
  {            
    Panel = OverlayManager.Singleton.CreateOverlayElement("Panel", name) 
      as OverlayContainer;
    Panel.MetricsMode = GuiMetricsMode.GMM_RELATIVE;
    Panel.SetDimensions(width, height);
    Panel.SetPosition(left, top);
    Panel.MaterialName = materialName;
    Panel.Colour = colour;            
  }
SimpleQuad.cs


Dodajemy również właściwość sterującą widzialnością prostokąta:
1
2
3
4
5
6
7
8
9
10
11
12
  public Boolean IsVisible
  {
    get { return Panel.IsVisible; }
    set
    {
      if (value)
        Panel.Show();
      else
        Panel.Hide();
    }
  }
}
SimpleQuad.cs


Przechodzimy teraz do klasy TextLabeler, by dokonać w niej następujących zmian:
1
2
3
4
class TextLabeler
{
  Overlay[] Overlays;
  OverlayContainer[] Panels; 
TextLabeler.cs


Zamieniliśmy pola Overlay i Panel na odpowiednio Overlays i Panels.

Wraz z wprowadzeniem prostokątów dodajemy do klasy listę obiektów SimpleQuad.

1
  public List<SimpleQuad> Quads;        
TextLabeler.cs


Wprowadzimy też istotne zmiany w konstruktorze.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
  public TextLabeler(int layers)
  {
    Overlays = new Overlay[layers];
    Panels = new OverlayContainer[layers];
 
    for (ushort i = 0; i < layers; i++)
    {
      Overlays[i] = OverlayManager.Singleton.Create("TextLabeler" + i.ToString());
 
      Panels[i] = OverlayManager.Singleton.CreateOverlayElement("Panel", 
        "TextLabelerPanel" + i.ToString()) 
          as OverlayContainer;
      Panels[i].MetricsMode = GuiMetricsMode.GMM_RELATIVE;
      Panels[i].SetDimensions(1.0f, 1.0f);
      Panels[i].SetPosition(0, 0);
 
      Overlays[i].Add2D(Panels[i]);                                    
      Overlays[i].Show();
      Overlays[i].ZOrder = i;
    }
 
    Labels = new List<TextLabel>();
    Quads = new List<SimpleQuad>();
  }
TextLabeler.cs


Wzbogacamy konstruktor o parametr layers, który określać będzie liczbę warstw, które chcemy stworzyć. Utworzone w pętli warstwy posortowane będą od najdalszej do najbliższej - odpowiada za to linijka 17.

Odświeżenia domagają się także metody fabryki tworzące nowe etykiety:

1
2
3
4
5
6
7
  public TextLabel NewTextLabel(String fontName, float fontSize, 
    ColourValue colourtop, ColourValue colourbottom, int layer)
  {
    ...
    Panels[layer].AddChild(textLabel.TextArea);
    ...
  }
TextLabeler.cs


Dodaliśmy nowy parametr, a także zmieniliśmy rodzica nowej etykiety. Analogiczne zmiany należy zaprowadzić w metodzie NewTextLabel3D. Ponadto potrzebujemy dopisać funkcję tworzącą obiekty utworzonego przed chwilą, nowego typu:
1
2
3
4
5
6
7
8
9
10
11
  public SimpleQuad NewSimpleQuad(string materialName, float left, float top, 
    float width, float height, ColourValue colour, int layer)
  {
    SimpleQuad quad = new SimpleQuad(GetUniqueLabelName(), materialName, 
      left, top, width, height, colour);
 
    Overlays[layer].Add2D(quad.Panel);
    Quads.Add(quad);            
 
    return quad;
  }
TextLabeler.cs


Jako iż głownym elementem graficznym klasy SimpleQuad jest obiekt typu Panel, umieszczamy go na nakładce w podobny sposób, jak w przypadku paneli z listy Panels.

Zmiana konstruktora TextLabeler pociąga konieczność określenia argumentu w metodzie inicjującej klasy Engine:

1
2
3
4
5
6
7
8
9
10
class Engine
{
  ...
  public void Initialise()
  {
    ...
    Labeler = new TextLabeler(5);
    ...
  }
  ...
Engine.cs


Pięć warstw na chwilę obecną w zupełności wystarczy.

Przetestujmy klasę SimpleQuad.

1
2
3
4
class HumanController
{
  ...
  SimpleQuad TalkBg;
HumanController.cs


Nowe pole będzie odpowiadać za prostokąt widniejący pod napisami reprezentującymi rozmowę.
1
2
3
4
5
6
7
  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);
    TalkBg = Engine.Singleton.Labeler.NewSimpleQuad(
      "QuadMaterial", 0.05f, 0.85f, 0.9f, 0.1f, new ColourValue(1, 1, 1), 1);
  }
HumanController.cs


W związku z modyfikacjami klasy TextLabeler zmieniamy wywołanie NewTextLabel3D tworzące etykietę obiektu, na którym postać skupia swoją uwagę. Aktualizacja polega na dodaniu ostatniego parametru - numeru warstwy, na której umieszczony będzie obiekt dwuwymiarowy - w tym wypadku 0, najniższą warstwę. Wiersz piąty odpowiada za utworzenie prostokąta na dole ekranu, na warstwie pierwszej, ponad wcześniej utworzoną etykietą.

Aktualny kod źródłowy

Materiał QuadMaterial

5
Twoja ocena: Brak Ocena: 5 (2 ocen)

Copyright © 2008-2010 Wrocławski Portal Informatyczny

design: rafalpolito.com