Anleitung 3: Markierungen

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • Anleitung 3: Markierungen

      Nach Anleitung 1 und Anleitung 2 möchte ich in einer dritten Anleitung noch auf die Markierungen eingehen. Ich sage schon im Voraus, dass es hier viele Erweiterungsmöglichkeiten gibt (z.B. hier ), aber es soll hier erstmal nur um die Grundlagen gehen.

      Das Ameisenvolk
      Erstmal ein neues Volk erstellen: Am besten kopiert ihr das Volk aus Anleitung 2 und gebt ihm z.B. den Namen "Markierungen.cs".

      Die Spielereinstellungen bleiben wie gehabt, und auch die Kasten werden einfach so übernommen.

      Markierungen sprühen
      Wenn eine Ameise etwas Interessantes sieht (z.B. einen Apfel), dann soll sie das den anderen Ameisen mitteilen, damit auch diese dorthin finden.
      Um das zu verwirklichen, habe ich eine Methode definiert, die einfach die Informationen eines Spielobjekts sprüht.

      [cs]
      /// <summary>
      /// Sprüht eine Markierung mit der Größe der Entfernung des Spielobjekts
      /// und der Information der Richtung des Spielobjekts.
      /// </summary>
      /// <param name="spielobjekt">Spielobjekt für Informationen</param>
      private void SprüheMarkierung(Spielobjekt spielobjekt)
      {
      int entfernung, richtung;
      entfernung = Koordinate.BestimmeEntfernung(this, spielobjekt);
      richtung = Koordinate.BestimmeRichtung(this, spielobjekt);
      SprüheMarkierung(richtung, entfernung);
      }
      [/cs]

      Diese Methode kann man dann wie folgt benutzen:

      [cs]
      public override void Sieht(Zucker zucker)
      {
      SprüheMarkierung(zucker); // Sprühe Markierung mit den Informationen des Zuckerstücks

      if (AktuelleLast == 0 && Ziel == null)
      {
      GeheZuZiel(zucker);
      }
      }
      [/cs]

      [cs]
      public override void Sieht(Obst obst)
      {
      SprüheMarkierung(obst); // Sprühe Markierung mit den Informationen des Obststücks

      if (AktuelleLast == 0 && Ziel == null)
      {
      if (BrauchtNochTräger(obst))
      {
      GeheZuZiel(obst);
      }
      }
      }
      [/cs]

      Auch wenn die Ameise einen Feind sieht, soll das den Anderen mitgeteilt werden:

      [cs]
      public override void SiehtFeind(Wanze wanze)
      {
      LasseNahrungFallen();

      SprüheMarkierung(wanze); // Sprühe Markierung mit den Informationen der Wanze

      if (Kaste == "Kämpfer" && AnzahlAmeisenDerSelbenKasteInSichtweite >= 3)
      {
      GreifeAn(wanze);
      }
      else
      {
      GeheWegVon(wanze);
      }
      }
      [/cs]

      [cs]
      public override void WirdAngegriffen(Wanze wanze)
      {
      LasseNahrungFallen();

      SprüheMarkierung(wanze); // Sprühe Markierung mit den Informationen der Wanze

      if (Kaste == "Kämpfer")
      {
      if (AnzahlAmeisenDerSelbenKasteInSichtweite >= 3)
      {
      GreifeAn(wanze);
      }
      }
      else
      {
      GeheWegVon(wanze);
      }
      }
      [/cs]

      [cs]
      public override void WirdAngegriffen(Ameise ameise)
      {
      LasseNahrungFallen();

      SprüheMarkierung(ameise); // Sprühe Markierung mit den Informationen der feindlichen Ameise

      if (Kaste == "Kämpfer")
      {
      if (AnzahlAmeisenDerSelbenKasteInSichtweite >= 3)
      {
      GreifeAn(ameise);
      }
      }
      else
      {
      GeheWegVon(ameise);
      }
      }
      [/cs]

      Damit wären die Sprüh-Methoden (fast) fertig.

      Markierungen riechen
      Jetzt fehlen noch die Methoden, die aufgerufen werden, wenn die Ameise eine Markierung riecht.

      [cs]
      public override void RiechtFreund(Markierung markierung)
      {
      if (Ziel == null)
      {
      DreheInRichtung(markierung.Information);
      GeheGeradeaus();
      }
      }
      [/cs]

      Wenn die Ameise nicht gerade ein anderes Ziel hat, soll sie sich in die Richtung der Information der Markierung drehen und dann geradeaus gehen.

      Eine Ameisenstraße bilden
      Um eine Ameisenstraße zu bilden, muss man die Methode Tick abändern, um dauernd zu überprüfen, ob die Ameise gerade ein Zuckerstück trägt.

      [cs]
      public override void Tick()
      {
      if (Ziel is Bau && AktuelleLast > 0 && GetragenesObst == null)
      {
      SprüheMarkierung(Richtung + 180);
      }
      }
      [/cs]

      Wenn die Ameise gerade zum Bau geht und etwas trägt, dass kein Obst ist (also muss es Zucker sein), dann soll sie eine Markierung sprühen, die als Informaion die Richtung der Ameise plus 180°, also die entgegengesetzte Richtung, enthält. Das bewirkt, dass alle Ameisen, die diese Markierung riechen, sich in die übergebene Richtung drehen und somit zum Zuckerhaufen gehen, von dem die Ameise herkommt.

      Das alles ist längst noch nicht alles, was man mit den Markierungen anfangen kann, aber es soll ja auch nur eine Einstieg sein.

      Im Anhang findet ihr wieder die .cs-Datei zum Downloaden.
      Dateien
      • Anleitung 3.zip

        (2,43 kB, 366 mal heruntergeladen, zuletzt: )

      Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von Bmeise ()

    • Information aus Sprühemarkierung auslesen

      Hey, kurze Frage ist es möglich die Information aus Sprühemarkierung auszulesen?
      Ein Beispiel wie ich mir das denke:


      [cs]public override void Sieht(Obst obst)
      {if (AktuelleLast == 0 && BrauchtNochTräger(obst) && Ziel == null)
      GeheZuZiel(obst);
      SprüheMarkierung(obst);}[/cs]

      Hier sagt die Ameise ja, hey ich hab Obst gefunden und sprüht das mit der Markierung an die anderen.
      Da stellt sich mir die Frage kann ich jetzt sagen das z. B. nur meine Kaste Sammler die Information annimmt und Ihr zu Hilfe kommt und die Kämpfer das ganze Ignorieren?

      Also so in etwa:

      [cs]public override void RiechtFreund(Markierung markierung)
      {
      if (Kaste == "Sammler" && Ziel == null && markierung.Information == zucker)
      }[/cs]

      und dann halt der normale Befehl was Sie tun sollte aber so wie ich mir das Vorstelle funktioniert das leider nicht weil ich zucker so nicht abfragen kann.
      (Fehler CS0103: Der Name "zucker" ist im aktuellen Kontext nicht vorhanden.)

      Wenn das gehen würde könnte man die Markierung auch nur für den Kasten geltend machen der Ihn auch Interessiert.


      Hat jemand eine Idee - wäre echt nett danke :)
    • Hallo Leute!
      Ich habe ein kleines Problem. Wenn bestimmte Ameisen bestimmten Markierungen zu nahe kommen, sollen sie sich davon entfernen. Dazu habe ich in der RiecheFreund-Methode eine if-Bedingung eingebaut:

      int entfernung = Koordinate.BestimmeEntfernung(this, markierung);

      if (entfernung <50) // Vertreibe Sucher

      {

      SprüheMarkierung(666, entfernung);

      GeheWegVon(markierung);

      }

      Die 666-Markierung habe ich bloß zum Debuggen eingebaut. Aber offenbar ist die Entfernung zur Markierung immer kleiner als 50, denn meine Scouts versuchen permanent, sich von den Markierungen fernzuhalten, und die 666-Markierungen sind auch immer sehr klein. Wird bei der Entfernungsmessung generell die gesamte Markierung genommen, an Stelle des Mittelpunkts? Und wenn ja, gibt es irgendeine Möglichkeit das Zentrum einer Markierung zu bestimmen? Oder geht das bloß mit statischen Ameisen?
      Danke für die Hilfe,
      Zardo
      Sonst muss ich mir etwas anderes überlegen, damit nicht immer alle meine Scouts an derselben Zuckerquelle warten. :D
    • @Martin
      Ich hatte schon mal die Idee "Modulo-Markierungen" zu verwenden. Denn eine Markierung enthält ja immer bloß eine Zahl als Information. Im Tutorial ist das der Winkel, man kann aber auch einfach 0 für Zucker, 1 für einen Apfel usw. verwenden, oder so ähnlich.
      Aber da Winkel immer zwischen 0 und 360 liegen, kann man die Zahlen von 360 bis 720 für andere Sachen verwenden. Zum Beispiel so:

      private void SprüheModuloMarkierung(Spielobjekt spielobjekt)

      {

      int entfernung, richtung, objekttyp;

      entfernung = Koordinate.BestimmeEntfernung(this, spielobjekt);

      richtung = Koordinate.BestimmeRichtung(this, spielobjekt); // liegt immer zwischen 0 und 359

      objekttyp = Typ(spielobjekt);

      SprüheMarkierung((richtung + 360*objekttyp, entfernung);

      }

      Die Typ-Funktion würde dann für jeden verschiedenen Objekttyp einen anderen Index zurückgeben. Das ginge wahrscheinlich mit einem Dictionary besser, so ungefähr so:

      private void Typ(Spielobjekt spielobjekt)

      {

      return dictObjekttypIndex[spielobjekt.GetType()]

      }

      Mit dictObjekttypIndex als Dictionary. Allerdings ist die zweite Funktion eher exemplarisch. Sie wird so wahrscheinlich nicht klappen.
      Ich hoffe ich konnte helfen - wenn es nich schon zu spät ist.
      Zardo