Feinderkennung bei RTS

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

  • Feinderkennung bei RTS

    Nabnd, über mein Problem hab ich noch nichts mit der Sufu gefunden, deswegen poste ich mal:

    WIe gelesen geht es um ein RTS, bei dem die Einheiten von selbst auf den Feind schießen sollen. WIe es mit der Reichweite usw. alles geht weiß ich ja, nur die Sache ist die:

    Woher weiß die Einheit das es ein Feind ist?

    Zum Aufbau: Es gibt keine 2 verschiedenen Fraktionen die sich in EIheiten unterscheiden; beide haben dieselben Einheiten. Deswegen soll jeder Einheitentyp als ein Objekt im GM vorhanden sein. Jedes produzierte Objekt bekommt bei der Variable "Team" eine Nummer zugewiesen. Alle Einheiten vom Spieler sind dann mal Team 1 und alle vom Computer Team 2. Ich würde es am liebsten so machen, das meine Einheiten automatisch kucken, ob
    1. die gegnerischen Einheiten in Reichweite sind,
    oder ob
    2. die Einheiten in Reichweite gegnerisch sind.

    Für beides wollte ich eine Art With-Funktion nehmen, die ungefähr so aussieht und die Variable Team scannt.:

    GML-Quellcode

    1. With(all.Team = 1)

    Also eine If-Anweisung in einer With (wobei ich nicht weiß ob das geht). Für beide Fälle brauch ich sowas, ansonsten fällt mir von der Theorie nichts anderes ein. Ich will auch nicht in jeder Einheit eine FOR-Schleife haben, die jede ID nach der anderen durchscant ob da ein Gegner bei ist und ob der in Reichweite ist. Das wäre meines erachtens zu Systemlastig, besonders wenn die ganzen Schüsse umherfetzten usw.

    Wäre supergeil wenn es da ne Antwort gibt (wollte mal das C&C RTS-Beispiel von gamemaker.nl laden, ist aber weg, oder ich bin zu doof das jetzt zu finden).
    Autosignatur für:

    Danke, Sorry usw. wenn ich mal was vergesse
    ...
  • da fällt mir spontan nur ein das man alle Einheiten desselben Types in eine liste schreibt, und sich dann die raussucht die am nähsten ist. beispiel:

    GML-Quellcode

    1. liste_einheit1 = ds_list_create();
    2. for(i=0; i<instance_number(obj_einheit1); i+=1) {
    3. a = instance_find(obj_einheit1,i);
    4. if ( a.team = 2 ) {
    5. ds_list_add(liste_einheit1,a);
    6. }
    7. }
    diese liste enthält nun alle gegnerischen Einheiten, des Types obj_einheit1. daraus die nähste herauszufinden, und zu überprüfen ob sie in Reichweite ist, sollte kein Problem sein denke ich.
    :) Nobody is perfect (-:

    "Dummköpfe sind Denkerköpfen weit überlegen. Zahlenmäßig." Ernst Ferstl
  • wenn man es in eine liste schreibt, kann man auch gleich dabei checken, ob sie in reichweite sind. und statt alle instanzen in einer for-schleife zu durchluafen, kann man auch with(all) nehmen. schließlich ist es auch unsinnig, erst alles in eine liste zu schreiben. mein vorschlag wäre (ersetze inReichweite durch die funktion, die prüft, ob es in reichweite ist)

    GML-Quellcode

    1. with(all)
    2. {
    3. if(inReichweite && team != other.team)
    4. //deine aktion
    5. }
    “Computers are good at following instructions, but not at reading your mind.” (Donald Knuth)

    Ich schreibe mit Neo.
  • 1.@iTeM:
    das geht so nicht, da ja instancen des gleichen objektes keine unterschiedlichen parrents haben können.
    2.@Bottleneck:
    das klappt ebenfalls nur eingeschränkt, und unkomfortabel. da die variable inReichweite nicht im anderen objekt vorhanden ist, bzw. anders sein kann, als von dem objekt von dem gemessen werden soll.

    ich gebe zu, meine Lösung ist auch nicht wirklich die genialste, aber ich habe mich länger damit beschäftigt, und keine wirklich perfekte lösung gefunden.
    währe auch dankbar wen mir jemand einen besseren Vorschlag anbieten würde.
    :) Nobody is perfect (-:

    "Dummköpfe sind Denkerköpfen weit überlegen. Zahlenmäßig." Ernst Ferstl
  • @nobody: ich sagte doch, man soll das ersetzten, es ist also keine variable. hab nur grad keine GML referenz zur hand, aber ich meine sowas wie
    distance_to_object(other)<100
    denn other ist in einem with-statement ja die aufrufende instanz.
    “Computers are good at following instructions, but not at reading your mind.” (Donald Knuth)

    Ich schreibe mit Neo.
  • ich mache es immer so das ich die eigenen einheiten in ein Array und die gegnerischen Einheiten in eine anderes Array schreibe denn dan must du nicht jedesmal alle objekte durchlaufen sondern nur die des gegners.

    mach einfach jedesmal wenn du einen einheit erstellst

    GML-Quellcode

    1. Liste1[Liste1Count] = instance_create(...)
    2. Liste1Count++;
    PI 0%(IN PROGRESS)
    [IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII]
    [IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII]

    Engine : 0.0 %
    KI : 0.0 %
    Grafik : 0.0%
    Sounds: 0.0 %
    Multiplayer: 0.0%
  • Original von bigmek

    GML-Quellcode

    1. Liste1[Liste1Count] = instance_create(...)
    2. Liste1Count++;
    Hehe, daran erkennt man die Gewohnheitler.
    Jetzt nochmal für alle: ++ funktioniert in Gml NICHT.
    Also bitte

    GML-Quellcode

    1. Liste1Count+=1;
    .
    Hier werden sie geholfen:
    [Regeln] [GML] [Hilfe] [Suche] [Posten] [Duden.de]
    [Wenn das alles nicht mehr hilft] [Dunning-Kruger]


    "Die Vernunft sollte Autorität definieren; nicht umgekehrt!"
    "Selber denken regt das Gehirn an."
    - Niffel f.k.a. Kilik
  • Upps danke habe ich garnicht bemerkt,
    kommt davon is ich es mit 3 programmiersprachen zu tun habe privat mach ich c++ und gml
    und in der Firma c#, da kann man schon mal ein bischen durcheinander kommen.
    PI 0%(IN PROGRESS)
    [IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII]
    [IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII]

    Engine : 0.0 %
    KI : 0.0 %
    Grafik : 0.0%
    Sounds: 0.0 %
    Multiplayer: 0.0%
  • Okay, hab ne Lösung gefunden (die sich an Bottleneck's orientier) und die funktioniert wie folgt:

    GML-Quellcode

    1. with(all)
    2. {
    3. if(variable_local_exists("team"))
    4. if(point_distance(other.x,other.y,self.x,self.y) < 200 && team != other.team)
    5. {
    6. other.target = id;
    7. }
    8. }


    Jedes Objekt wird gescannt (auch Objekte die nicht am Geschehen teilnehmen (irgendwelche Controller etc.)

    Deswegen wird erstmal gekuckt ob diese Objekte auch eine Team-Variable haben. Brauchen solche Controller eigentlich nicht. Dann wird die Reichweite geprüft und erst dann gekuckt ob die Teams verschieden sind.
    Ich hab die Erfahrung gemacht, wenn die Teamüberprüfung in der Anweisung ist, wo nachgesehen wird, ob die Varaible überhaupt vorhanden ist, das das Spiel abschmiert, mit der Bergründung das "Team" nicht vorhanden sei.

    Am Ende nehme ich die ID des gefunden Objektes und sage das dies das Ziel der Eiheit wird. Garnicht mal so unpraktisch wenn sich die Türme solange auf ein Ziel fixieren, bis es außer Reichweite ist.

    Okay, Danke für die Hilfe.
    Gruß vom grünen Plüschlindwurm "Frosti"
    Autosignatur für:

    Danke, Sorry usw. wenn ich mal was vergesse
    ...
  • das schreibst du ins step event

    GML-Quellcode

    1. if (target == null ) and (searchTarget == false)
    2. {
    3. alarm[0] = //die zeit wie oft er kontrollieren soll ob ein gegener in reichweite ist
    4. searchTarget = true
    5. }
    6. else if (target != null )
    7. {
    8. //hierer kommt der code den du ausführen möchtest wenn du ein ziel gefunden hast
    9. }


    im alarm0 event schreibst du

    GML-Quellcode

    1. searchtarget == false
    2. //hier rufst du eine der vorgeschlagenen lösungen auf
    PI 0%(IN PROGRESS)
    [IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII]
    [IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII]

    Engine : 0.0 %
    KI : 0.0 %
    Grafik : 0.0%
    Sounds: 0.0 %
    Multiplayer: 0.0%
  • Hab ich im Prinzip auch so und funktioniert auch gut.

    Jetzt werkel ich an einer "Grund-KI", damit ich testen kann, ob die Schlachten gut ausfallen. Bei meinen RTS geht das ja noch mit der KI, ist nämlich kein RTS wie man es sonst kennt.
    Autosignatur für:

    Danke, Sorry usw. wenn ich mal was vergesse
    ...
  • Original von Frosti
    Ich hab die Erfahrung gemacht, wenn die Teamüberprüfung in der Anweisung ist, wo nachgesehen wird, ob die Varaible überhaupt vorhanden ist, das das Spiel abschmiert, mit der Bergründung das "Team" nicht vorhanden sei.

    Das Problem beim GM ist, dass er bei if-abfragen immer alle bedingungen geprüft werden. Bei den meisten "richtigen" Programmiersprachen wird das if abgebrochen, wenn das ergebnis feststeht, das heißt: bei zwei mit UND verknüpften bedingungen wird abgebrochen, wenn die erste false ist. wenn man dann die beiden zeilen

    GML-Quellcode

    1. if(variable_local_exists("team"))
    2. if(point_distance(other.x,other.y,self.x,self.y) < 200 && team != other.team)

    zu einer zusammenfasst zu

    GML-Quellcode

    1. if(variable_local_exists("team") && point_distance(other.x,other.y,self.x,self.y) < 200 && team != other.team)

    dann sollte das zwar in anderen Sprachen von der Logik her gehen, in GML aber nicht, denn auch wenn "team" nicht existiert, wird weitergeprüft, und dann kommt eben der fehler.
    “Computers are good at following instructions, but not at reading your mind.” (Donald Knuth)

    Ich schreibe mit Neo.