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

28.10.2011 - Mateusz Osowski
TrudnośćTrudność

Test na brudno

Nasz nowy zestaw algorytmów przetestujemy skupiając się na natychmiastowych efektach, dopisując tymczasową gałąź do drzewa decyzyjnego postaci. Strukturę drzewa dotyczącą przemieszczania się postaci rozplanujemy lepiej w kolejnych częściach cyklu.

Dobrze jest umieć wykorzystywać dopiero co zaimplementowane części programu w miarę możliwości 'na brudno', ponieważ ma to dokładnie takie same zalety jak pisanie na brudno wypracowania do szkoły - pozwala wyłapać błędy i lepiej zaprojektować ostateczną wersję.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public CharacterDecTree()
{ 
  ...
  DecTree.FirstFail followPathNode = new DecTree.FirstFail(
    new DecTree.Assert(ch => ch.FollowPathOrder),
    new DecTree.Job(ch =>
    {                        
      if (Op2D.Dist(ch.Position, ch.WalkPath[0]) < 0.5f)
      {
        ch.WalkPath.RemoveAt(0);
      }
      if (ch.WalkPath.Count == 0)
      {
        ch.FollowPathOrder = false;
        return true;
      }
      else
      {
        ch.Orientation = Quaternion.Slerp(
          0.2f, 
          ch.Orientation, 
          Vector3.UNIT_Z.GetRotationTo(
            (Op2D.XZ * (ch.WalkPath[0] - ch.Position)).NormalisedCopy), 
          true
        );
        ch.Velocity = ch.Orientation * Vector3.UNIT_Z * ch.Profile.WalkSpeed;
        ch.AnimBlender.SetAnimSet("Walk");
      }
      return false;
    }
  ));
  ...
  Children.Add(pickItemNode);
  Children.Add(followPathNode);
  Children.Add(walkNode);
  Children.Add(idleNode);
}
CharacterDecTree.cs, CharacterDecTree()

Gałąź zawiera działanie zakodowane 'na sztywno'. Dopiszemy do klasy postaci następujące pola: listę WalkPath zawierającą scieżkę, po której ma przejść postać i flagę FollowPathOrder sterującą nowym zachowaniem. Działanie polega na zbliżaniu się do kolejnych punktów ścieżki na odległość mniejszą od 0.5m. Obrót postaci będzie gładki, dzięki interpolacji sferycznej.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
static void Main(string[] args)
{
  NavMesh navMesh = new NavMesh();
  navMesh.LoadFromOBJ("Navmesh.obj");
  
  ...
  
  while (true)
  {
    ...
    if (Engine.Singleton.IsKeyTyped(MOIS.KeyCode.KC_P))
    {
      navMesh.AStar(npc.Position, player.Position);
      if (navMesh.TriPath.Count > 1)
      {
        navMesh.GetPortals();
        npc.WalkPath = navMesh.Funnel();
 
        npc.FollowPathOrder = true;
      }
    }
    ...
  }
  ...
}
 
Main.cs, Main()

W powyższym fragmencie kodu tworzymy nowy obiekt NavMesh, ładujemy dane z pliku, a wciśnięcie klawisza P wykona algorytmy znajdujące trasę od jedynego w grze bohatera niezależnego do postaci gracza i wyda rozkaz przejścia tej trasy temu bohaterowi.

Aktualny kod źródłowy

Plik siatki nawigacyjnej

Udało nam się zaimplementować kluczowy fragment sztucznej inteligencji. Bohater niezależny nie gubi się już, podążając za postacią gracza. Wciąż jednak są to dość surowe algorytmy. Wraz z drzewami decyzyjnymi, stanowią one podstawę tego, czym zajmować się będziemy w kolejnych częściach kursu. Zbliża się też moment, w którym zaczniemy tworzyć mechanizmy walki w grze.

5
Twoja ocena: Brak Ocena: 5 (1 ocena)

Copyright © 2008-2010 Wrocławski Portal Informatyczny

design: rafalpolito.com