Hyppää sisältöön

Aivot ja tekoäly

Joskus olioita halutaan saada liikkumaan pelissä automaattisesti ilman ihmisen ohjaamista. Tätä varten Jypelissä on olemassa muutamia erilaisia yksinkertaisia tekoälyjä.

Tekoälyn saa käyttöön antamalla halutulle oliolle aivot.

Aivojen luominen ja käyttöönotto

Kaikkien aivojen käyttäminen toimii periaatteessa samalla tavalla:

  • Ensin täytyy luoda halutunlaiset aivot.

  • Sen jälkeen aivojen ominaisuuksia voi muokata juuri omaan peliin sopiviksi.

  • Lopuksi aivot voidaan antaa olion käyttöön.

Esimerkki, satunnaisesti liikkuvat aivot:

PhysicsObject randomOlio = new PhysicsObject(20.0, 20.0);
Add(randomOlio);

//Tehdään uudet satunnaisaivot, jotka liikkuvat nopeudella 200
RandomMoverBrain satunnaisaivot = new RandomMoverBrain(200);

//Ominaisuuksien muokkaaminen
satunnaisaivot.ChangeMovementSeconds = 3;

//Aivot käyttöön oliolle
randomOlio.Brain = satunnaisaivot;

Erilaiset aivot

Tarkastellaan lähemmin, mitä eri aivotyypeillä voi tehdä.

Yleisiä ominaisuuksia kaikille aivoille

Speed säätää nopeutta, jolla aivojen omistaja liikkuu.

aivot.Speed = 100;

Aivot päälle:

aivot.Active = true;

Aivot pois päältä:

aivot.Active = false;

TurnWhileMoving käskee aivoja kääntämään oliota menosuuntaan.

aivot.TurnWhileMoving = true;

FollowerBrain

Seuraajaolion aivot saavat olion seuraamaan yhtä tai useampaa oliota. Aivojen luonnin yhteydessä niille annetaan kohde, jota seurata:

FollowerBrain seuraajanAivot = new FollowerBrain(pelaaja);

Useampien olioiden tapauksessa seurattavat oliot erotetaan pilkulla.

FollowerBrain seuraajanAivot = new FollowerBrain(pelaaja1, pelaaja2);

Voit antaa aivoille myös merkkijonon (lainausmerkeissä), jolloin aivojen omistaja seuraa kaikkia olioita, joilla on kyseinen Tag-arvo.

FollowerBrain seuraajanAivot = new FollowerBrain("pelaaja");

Seuraajaolion aivoilla on muita aivoja enemmän muuttujia, jotka vaikuttavat sen toimintaan.

PhysicsObject seuraaja;  // Attribuutti, jotta olioon päästään käsiksi myös tapahtumankäsittelijässä

...

seuraaja = new PhysicsObject(30.0, 30.0);
Add(seuraaja);

RandomMoverBrain satunnaisaivot = new RandomMoverBrain(200);
FollowerBrain seuraajanAivot = new FollowerBrain("pelaaja");

seuraajanAivot.Speed = 300;                 // Millä nopeudella kohdetta seurataan
seuraajanAivot.DistanceFar = 600;           // Etäisyys jolla aletaan seurata kohdetta
seuraajanAivot.DistanceClose = 200;         // Etäisyys jolloin ollaan lähellä kohdetta
seuraajanAivot.StopWhenTargetClose = true;  // Pysähdytään kun ollaan lähellä kohdetta
seuraajanAivot.FarBrain = satunnaisaivot;   // Käytetään satunnaisaivoja kun ollaan kaukana

// Tapahtuma, joka tapahtuu kun ollaan lähellä kohdetta
seuraajanAivot.TargetClose += MitaTapahtuuKunOllaanLahella;

seuraaja.Brain = seuraajanAivot;
...

// Aliohjelma joka ajetaan kun olio on tarpeeksi lähellä kohdetta.
void MitaTapahtuuKunOllaanLahella()
{
    seuraaja.Color = Color.Red;
}

FollowerBrainilta voi kysyä myös, mitä oliota se seuraa (seuraajanAivot.CurrentTarget), ja miten kaukana seurattava olio tällä hetkellä on (seuraajanAivot.DistanceToTarget). Jälkimmäinen on mittari (DoubleMeter), joten sille voi esimerkiksi lisätä tapahtuman, kun on päästy tietyn matkan päähän kohteesta.

PhysicsObject zombi = new PhysicsObject(30.0, 30.0);
Add(zombi);

FollowerBrain seuraajanAivot = new FollowerBrain("pelaaja");
seuraajanAivot.DistanceToTarget.AddTrigger(30, TriggerDirection.Down, Huuda);
zombi.Brain = seuraajanAivot;
...

// Aliohjelma joka ajetaan kun olio on tarpeeksi lähellä kohdetta.
void Huuda()
{
    PlaySound("Braaiins");
}

RandomMoverBrain

Satunnaisesti liikkuvan olion aivot laittavat olion liikkumaan satunnaisesti (leijuen) kentässä. Satunnaisaivoille voi kertoa sekunneissa, miten usein ne vaihtavat liikesuuntaa:

satunnaisaivot.ChangeMovementSeconds = 3;

Satunnaisaivoille voi myös antaa säteen, jonka ulkopuolelle se ei voi lähteä harhailemaan:

satunnaisaivot.WanderRadius = 200;

Harhailuympyrän keskipisteen pitäisi määräytyä automaattisesti, mutta sen voi myös asettaa itse.

satunnaisaivot.WanderPosition = new Vector(200, 300);

PathFollowerBrain

Polkua seuraavat aivot kulkevat pitkin niille annettua reittiä tasaisella nopeudella.

Polku, jota aivot seuraavat, annetaan vektorilistana. Listan käyttöä varten ohjelmakoodin alkuun tulee lisätä seuraava using-lause, jos se sieltä puuttuu. Näin saadaan käyttöömme List-tyyppi.

using System.Collections.Generic;

Tehdään uusi lista, joka pitää sisällään vektoreita, ja lisätään siihen ne vektorit, joiden kautta haluamme polun kulkevan.

List<Vector> polku = new List<Vector>();
polku.Add(new Vector(-50, -100));
polku.Add(new Vector(-100, 50));
polku.Add(new Vector(-250, -200));

Sen jälkeen luodaan aivot ja annetaan polku niille:

PathFollowerBrain polkuaivot = new PathFollowerBrain();
polkuaivot.Path = polku;

Asetetaan aivot kiertämään reittiä jatkuvasti, viimeisen pisteen jälkeen palataan takaisin ensimmäiseen.

polkuaivot.Loop = true;

Aivoille täytyy määrittää nopeus, jolla liikutaan:

polkuaivot.Speed = 100;

Lopuksi aivot annetaan oliolle:

PhysicsObject vartija = new PhysicsObject(30.0, 30.0);
Add(vartija);

vartija.Brain = polkuaivot;

PlatformWandererBrain

Tasoa pitkin kulkevat aivot voi lisätä ainoastaan PlatformCharacter-tyyppisille olioille.

Esimerkki:

PlatformCharacter rotta = new PlatformCharacter(20.0, 20.0);
Add(rotta);

PlatformWandererBrain tasoaivot = new PlatformWandererBrain();
tasoaivot.Speed = 100;

rotta.Brain = tasoaivot;

Jos haluaa, että aivoilla kävelevä hahmo voi tippua alas tasoilta:

tasoaivot.FallsOffPlatforms = true;

Jos haluaa, että aivot yrittävät hyppiä ylemmälle tasolle törmätessään seinään:

tasoaivot.JumpSpeed = 700;
tasoaivot.TriesToJump = true;

Hyppimisen laatua voi parantaa muuttamalla kävelynopeutta ja hyppynopeutta sopivaan suhteeseen keskenään.

LabyrinthWandererBrain

Labyrintissä vaeltelevat aivot voi lisätä PhysicsObject-tyyppisille olioille.

Aivot käyttävät liikkumisessa hyväkseen tietoa labyrintin/kentän yhden "ruudun" koosta, joten ruudun koko on annettava uusia aivoja luotaessa. Aivoille on mahdollista antaa seinien tagi, jolloin aivot väistelevät ainoastaan seiniä. Jos tagia ei anneta, aivot väistelevät kaikkia muitakin olioita.

Esimerkki:

//Kentän yhden "ruudun" koko, käytä samaa lukua kuin jos kenttä luotu esimerkiksi ColorTileMapilla.
const int RUUDUN_KOKO = 40;

PhysicsObject rotta = new PhysicsObject(RUUDUN_KOKO / 2, RUUDUN_KOKO / 2);
Add(rotta);

LabyrinthWandererBrain labyrinttiaivot = new LabyrinthWandererBrain(RUUDUN_KOKO);
labyrinttiaivot.Speed = 100.0;
labyrinttiaivot.LabyrinthWallTag = "seina";

rotta.Brain = labyrinttiaivot;