Autor Wątek: Postać poruszająca się po określonej przestrzeni x,z  (Przeczytany 3016 razy)

Offline JasonVoorhees

  • Użytkownik
    • FotoGry

# Czerwiec 11, 2007, 02:38:58
Próbowałem takie coś napisać, ale jak na razie to mnie przerasta...
mam określony kwadrat po którym się porusza "bardzo sztuczna inteligencja" :D
W jej ruchach ma ona chodzić tylko do przodu wg. funkcji trygonometrycznych, jak natrafia na koniec zakresu ruchów to ma nieco zmieniać kont swojego chodzenia, tylko że wg. mojego kodu postać się kręci w kółko... bo jak już wyjdzie poza obszar to ciągle zmienia kąt, czyli kręci się w kółko :D...
Tak wygląda kodzik:
void enemyS::AI()
{
    angle=DegToRad(ry);
    if ((position[0]<Space1[0])||(position[0]>Space2[0]) ||(position[2]<Space1[1])||(position[2]>Space2[1])) ry+=50;
    glTranslatef(position[0],position[1],position[2]);
    glRotatef(ry+90,0,1,0);
    glRotatef(90,0,0,1);
    MoveForward();
    Model.DrawFrame(0);
}
angle jest użyte w funkcji MoveForward(); to poruszania się w określonym kierunku, ry, to obrót wkoło osi y, Space1,Space2 to współrzędne x,z
kwadratu, position to współrzędne x,y,z postaci.

Jest jakiś dobry sposób na to ?? Może znacie namiary na jakiś art o pisaniu AI ?

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Haxy.M

  • Użytkownik

# Czerwiec 11, 2007, 03:06:31
Nasuwają mi się dwa rozwiązania:

1. Może zmiane kąta dać losową, a nie o stałą wartość?

2. Coś co kiedyś sam stosowałem i co bardo sie sprawdzało przy "gonieniu" gracza. Mianowicie:

a) Dzielisz sobie planszę na małe kwadraty
b) Cel (a w zasadzie kwadat na którym stoi) dostaje najniższy numer (powiedzmy 0)
c) Idąc od celu (i zwracając uwagę na przeszkody) każdy kolejny kwadrat dostaje numer o jeden więszy
d) Twoja postać zawsze wybiera sąsadujący (do swojego) kwadrat z najmniejszą wartością (oczywiscie po wyborze kwadraty Twoja postać będzie musiała się odwrócić twarzą do wybranego)

Jeśli chcesz tylko łazić po planszy bez celu to Twój cel może być losowy i  zmieiać się po dotarciu do niego. W ten sposób nigdy nie będziesz usiłował przejść przez scianę, więc nie bedziesz się kręcić.

upshader

  • Gość
# Czerwiec 11, 2007, 03:11:28
Kolega chyba staral sie opisac algorytm BFS, ale gorszego opisu to jeszcze nie widzialem ;)

Offline Haxy.M

  • Użytkownik

# Czerwiec 11, 2007, 03:18:47
heh widac kiepsko tlumaczę więc kawałek kodu wicięty z napisaej już dawno temu prostej gierki 2d
void ghost :: movebegin(void)
{
 bool modified = true;
 int i;
 int j;
 int lookfor;
 int* aihelper;
 aihelper = new int[info->height * info->width];
 for(i = 0;i < info->height;i++)
 {
  for(j = 0;j < info->width;j++)
  {
   aihelper[getindex(j,i)] = 0; //pusta plansza
  }
 }  
 aihelper[getindex(info->player->x,info->player->y)] = 1; //zaznacz gracza
 for(i = 0;i < info->ghostcount;i++)
 {
  if((info->ghosts[i].x != x) && (info->ghosts[i].y != y))
  {
   aihelper[getindex(info->ghosts[i].x,info->ghosts[i].y)] =- 1; //zaznacz inne duchy (aby na siebie nie wpadały)
  }
 }
 lookfor = 1;
 while(modified)
 {
  modified = false;
  for(i = 0;i < info->height;i++)
  {
   for(j = 0;j < info->width;j++)
   {
    if(aihelper[getindex(j,i)] == lookfor)
    {
     if(inbound(j - 1,i))
     { //czy mozna w lewo
      if(info->areas[getindex(j,i)].left)
      { //zerknij czy nie ma ścianki
   if(aihelper[getindex(j - 1,i)] == 0) //albo czegoś innego
   {
        aihelper[getindex(j - 1,i)] = lookfor + 1; //zaznacz to pole
        modified = true;
   }
      }
     }
     if(inbound(j + 1,i))
     { //zobacz w prawo
      if(info->areas[getindex(j,i)].right)
      {
   if(aihelper[getindex(j + 1,i)] == 0)
       {
        aihelper[getindex(j + 1,i)] = lookfor + 1;
        modified = true;
   }
  }
     }
     if(inbound(j,i - 1))
     { //zobacz w górę
      if(info->areas[getindex(j,i)].up)
      {
   if(aihelper[getindex(j,i - 1)] == 0)
       {
        aihelper[getindex(j,i - 1)] = lookfor + 1;
        modified = true;
       }
      }
     }
     if(inbound(j,i + 1))
     { //zobacz w dół
      if(info->areas[getindex(j,i)].down)
      {
   if(aihelper[getindex(j,i + 1)] == 0)
       {
        aihelper[getindex(j,i + 1)] = lookfor + 1;
        modified = true;
   }
  }
     }
}
   }
  }
  lookfor++;
 }
   
  //obecnie w tablicy aihelper s 'odległości' od gracza
 
 lookfor = aihelper[getindex(x,y)]; //x,y współrzędne obecego ducha
 //lookfor teraz zawiera dolegoc od gracza
 //spróbujmy zmniejszyc dystans
 destx = x;
 desty = y;
 if(info->player->immortal)
 {
  lookfor++;
 }
 else
 {
  lookfor--;
 }
 if(inbound(x - 1,y))
 { //zobacz w lewo
  if(aihelper[getindex(x - 1,y)] == lookfor)
  {
   if(info->areas[getindex(x,y)].left)
   {
    destx--;
    delete [] aihelper;
    return;
   }
  }
 }
 if(inbound(x + 1,y))
 { //zobacz w prawo
  if(aihelper[getindex(x + 1,y)] == lookfor)
  {
   if(info->areas[getindex(x,y)].right)
   {
    destx++;
    delete [] aihelper;
    return;
   }
  }
 }
 if(inbound(x,y - 1))
 { //zobacz w górę
  if(aihelper[getindex(x,y - 1)] == lookfor)
  {
   if(info->areas[getindex(x,y)].up)
   {
    desty--;
    delete [] aihelper;
    return;
   }
  }
 }
 if(inbound(x,y + 1))
 { //zobacz w dół
  if(aihelper[getindex(x,y + 1)] == lookfor)
  {
   if(info->areas[getindex(x,y)].down)
   {
    desty++;
    delete [] aihelper;
    return;
   }
  } 
 }
 //printf("No Choose\n");
 delete[] aihelper;
}
« Ostatnia zmiana: Czerwiec 11, 2007, 03:21:15 wysłana przez Haxy.M »

Offline counterClockWise

  • Użytkownik

# Czerwiec 18, 2007, 17:58:43
Mam lepszy pomysł - mieliśmy jako tygodniowy projekt napisać symulację wody z rozchodzeniem się fal (jak w perełkach 1), załamaniem fresnela, oświetleniem anizotropowym i .... pływającą KACZK¡! zaburzającą powierzchnię wody tam gdzie wpłynie.
Kaczka poruszała się po krzywej B-Spline stycznie do niej - żeby zawsze miała główkę do przodu - po prostu na początku losowała sobie 4 punkty kontrolne B-Spline a jak dojeżdzała do końca to dolosowywała kolejny (oczywiście z ograniczeniem do powierzchni wody - czyli tutaj byłoby do Twojego kwadratu). Miałeś dwukrotnie różniczkowalny LOSOWY ruch (ciągła prędkość i przyspieszenie :).

Offline Pierdek

  • Użytkownik

# Czerwiec 19, 2007, 09:22:19
Brakuje mi w tym kodzie jakiegos opoznienia, zeby ta postac mogla sobie polazic zanim zacznie motac w ustawieniach ruchu:)
bo z tego co widze jezeli wywolasz co klatke, funkcje decydujaca o zachowaniu - to bedzie sie caly czas krecic:), ale moze to masz w innym miejscu.

Offline JasonVoorhees

  • Użytkownik
    • FotoGry

# Czerwiec 19, 2007, 11:12:59
Właśnie mam co klatkę. Cóż może wystarczy dać raz na ileś tam klatek :)

Offline Charibo

  • Redaktor

# Czerwiec 19, 2007, 12:34:00
raczej raz co jakis czas ;)

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

# Czerwiec 19, 2007, 13:44:28
Animacja powinna być przeprowadzana co klatkę - inaczej będziemy wyświetlali taki sam obraz kilkukrotnie, co by było bez sensu. Raz co jakis czas odpada, bo wtedy animacja przestaje być płynna. Najlepiej oprzeć się na pomiarach czasu pomiędzy klatkami i na podstawie tego przesuwac animację co klatkę o okresloną odległośc/obrót. :)

Offline Charibo

  • Redaktor

# Czerwiec 19, 2007, 14:48:10
Cytuj
Najlepiej oprzeć się na pomiarach czasu pomiędzy klatkami i na podstawie tego przesuwac animację co klatkę o okresloną odległośc/obró
Dokladnie o to mi chodzilo, tylko troche kiepsko to sprecyzowalem (:)) - rendering powinien byc wykonywana co klatke, animacja rowniez, jednak kontrolowana czasem (zeby chodzila tak samo na wszystkich kompach, czy mamy 10 czy 1000 fpsow)