Gegnerprogrammierung: Zufälliges Objekt auf einem veränderlichem Pfad generieren

  • GM 8

    Gegnerprogrammierung: Zufälliges Objekt auf einem veränderlichem Pfad generieren

    Hallo Community,

    wie einige von euch möglicherweise bereits über den Chat oder mein anderes Thema mitbekommen haben, arbeite ich derzeit an einem Spiel, in dem sich zwei Laserstationen bekämpfen sollen, indem sie in einem rundenbasierendem Kampf Spiegel platzieren oder einen Laser feuern.

    Damit ihr euch ein genaueres Bild vom Spiel machen könnt ist hier ein Screenshot:

    (Rechts oben wird angezeigt, welche Station gerade am Zug ist, auf der linken Seite das Quadrat ist die Auswahlbox, mit der man Spiegel platziert)

    Das Spiel als Multiplayer (zwei Spieler an einer Tastatur) funktioniert super, allerdings benötige ich einen Computer-gesteuerten Gegner für den Einzelspielermodus.

    Damit dieser COM-Gegner auch sinnvoll handelt habe ich einen Plan der verschiedenen Phasen erstellt:


    ************************************************************************
    Phase1: Angriff (diese Phase funktioniert bereits tadellos)

    Wenn die Variable global.Runde, die festlegt welcher Spieler dran ist, auf 2 (blauer COM-gegner) gewechselt wird, spawnt dieser einen unsichtbaren Laser, der an den Spiegeln apprallt wie ein normaler, und somit prüft, ob der COM den menschlichen Spieler mit einem richtigen Laser treffen würde.

    Sollte dies der Fall sein, wird ein richtiger Laser gespawnt und die menschliche Laserstation zerstört. Sollte dies allerdings nicht möglich sein, wird die Rundenvariable umgesetzt, sodass Phase2 eingeleitet wird.

    ************************************************************************
    Phase2: Verteidigung (hier kommt das erste Problem)

    Durch die Änderung der Rundenvariable wird an der roten, menschlichen Laserstation ein unsichtbarer Laser gespawnt, der somit prüft, ob der menschliche Spieler den COM-Gegner in der nächsten Runde treffen könnte.
    Sollte dies nicht der Fall sein, wird Phase 3 eingeleitet, sollte es allerdings der Fall sein, so soll der Weg des Lasers als Pfad gespeichert werden und auf einem zufälligen, freien Platz auf dem Pfad ein Spiegelobjekt erstellt werden, welches den menschlichen Laser davon abhält, den COM zu treffen. Nach platzieren des Spiegels müsste der gespeicherte Pfad natürlich für die nächste Runde gelöscht werden.


    Das Problem hierbei ist, dass ich keine Ahnung habe, wie ich den Pfad des unsichtbaren Lasers als solchen abspeichere ( habe bereits path_add() probiert, aber keine möglichkeit festzustellen, ob es diesen auch gespeichert hat, da noch keine interaktion mit dem Pfad erfolgte).
    Um jedoch einen zufälligen, freien Punkt auf dem Pfad mit einem Spiegel zu versehen, sollte dieser Code gehn, oder?

    GML-Quellcode

    1. var gridX, gridY;
    2. gridX=8+16*irandom(22);
    3. gridY=8+16*irandom(19);
    4. while (place_meeting(gridX,gridY,par_gridelement))
    5. {
    6. gridX=8+16*irandom(22);
    7. gridY=8+16*irandom(19);
    8. }//zufällige Position im Raumgitter, die nicht belegt ist
    9. if global.Runde=4.31 //4.31 = "wenn der Spieler die COM-Station treffen könnte"
    10. and place_meeting(gridX,gridY, PFAD1)//hier würde der vom unsichtbaren Laser generierte Pfad benötigt werden
    11. {
    12. instance_create(gridX,gridY,SPIEGELOBJEKT)
    13. }


    ************************************************************************
    Phase3: Spiegelplatzierung (das letzte Problem)

    Sollten die oberen 2 Phasen nicht dazu führen, dass der COM angreift oder einen Spiegel zur Verteidigung setzt, soll in der dritten Runde erneut mit einem unsichtbaren Laser geprüft werden, welchen Pfad der richtige COM-laser einschlagen würde. Dieser Pfad und dessen Endpunkt sollen ebenfalls kurzzeitig gespeichert werden und ein unsichtbarer, zufälliger Spiegel auf dem Pfad an einer freien Stelle platziert werden. Sollte der unsichtbare Spiegel dazu führen, dass der unsichtbare Laser (bei erneutem spawnen) seinen Pfad-endpunkt weniger weit von der gegnerischen Basis entfernt findet, als der Spawn ohne Spiegel, so soll an der Stelle des unsichtbaren Spiegels ein richtiger gespawnt werden. Andernfalls muss ein neuer unsichtbarer Spiegel platziert und ebenfalls geprüft werden.


    Ich weiß, dass es sehr viel ist, aber hoffe trotzdem das ihr mir bei diesem Problem helfen könnt :)

    PS: Falls es hilft könnte ich auch den Code posten, den ich bereits geschrieben habe, oder falls das Problem unklar ist, kann ich es noch genauer erklären.
    Im Internet weiß niemand, dass du ein Truthahn bist.
    Vielleicht wäre es hilfreich wenn du mal eine Gmk posten würdest. :thumbup:
    Aktuelle Projekte:
    - Super Mario Land (Level Editor)
    - Snout Space Landing Remastered

    Abgeschlossene Projekte:
    - Ski Remastered (Auf lsfgames.weebly.com)
    ich habe es noch nicht ganz kapiert aber man braucht glaube ich dafür nicht einmal einen pfad
    alles könnte auf computer logik gehen wenn ich das genau verstehe würde es besser gehen zu zeigen wie du das
    machen könntest
    Ein Bug ist mehr als nur ein Bug, es ist ein... Käfer!
    Egal, wie gut du eine Mauer baust, sie fällt um.... der klügere gibt nach :D

    Willst du mit mir auf Discord Chatten/Quatschen?
    Meine Husi's Tutorial Reihe
    So,

    tut mir leid dass ich einige Tage nicht ins Forum gesehen habe, war mit etwas Schulzeug für die Abschlussfahrt beschäftigt.


    @LSF Games

    Der Gedanke, den ich im Startpost hatte, lässt sich so ausdrücken:

    Ich habe ein Objekt, dieses Objekt bewegt sich bei Generierung in eine der vier Richtungen (0 -> , 90 ^ , 180 <- und 270 v ). Dadurch, dass das Objekt die Richtung wechselt, wenn es auf ein Spiegelobjekt trifft, wollte ich durch das Objekt prüfen, ob der Computergegner durch das Objekt getroffen werden kann. Falls das der Fall sein sollte, so sollte das Objekt nochmal den selben Weg nachfahren, dabei einen Pfad generieren, und dann auf einer zufälligen, freien Stelle auf dem Pfad ein Spiegelobjekt generieren, welches somit verhindert das der menschliche Spieler im nächsten Zug den Computergegner treffen kann.

    Diese Idee hab ich allerdings im Laufe der letzten Wochen nochmal überdacht.


    @husi012

    Du hast recht, dafür braucht man keinen Pfad,

    ich habe es jetzt so umgeschrieben, dass einfach nur erkannt wird ob sich das Laserobjekt, dass davon abgehalten werden soll den Computergegner zu treffen, oben links, oben rechts, links unten, rechts unten oder auf der x oder y Achse des gegnerischen Objekts befindet und dadurch entschieden wird, welche Art Spiegel auf der nächstliegenden freien Stelle generiert wird. Allerdings gibt es hierbei das Problem, dass meine Objekte in einem 8x8 Gitter platziert sind (da ihr x,y Punkt in der Mitte des 16x16 sprites ist), und deshalb auch nur zur hälfte in dem gewünschten 16x16 Gitter platziert werden können.


    Und um jetzt endlich einmal zu verhindern, dass Unklarheiten auftreten, ist hier eine detailierte Auflistung des jetzigen Problems/der gewünschten Situation.

    Das ist mein erstes, gewünschtes Szenario, bei dem die rote, menschliche Laserstation im links unteren Bereich der blauen, gegnerischen Laserstation ist.

    Hier würde der Laser, der von der roten Station aus nach oben fliegen würde, am Spiegel (ich hoffe mal nicht erklären zu müssen wie etwas an einem spiegel abprallt) abprallen und die Computerstation treffen.

    Da sich der Laser beim Enstehen direkt über der roten Station befinden würde und dort eine freie Stelle im 16x16 Gitter ist, würde sich dort ein Spiegel zur Ablenkung nach links bilden müssen(da der Laser so weiter vom Mittelpunkt, der blauen Station, entfernt):


    Hierbei gilt der Code(für den Laser,der den Spiegel platziert (später unsichtbar)) :

    GML-Quellcode

    1. if global.Runde=4.41 and place_snapped(8,8)=place_empty(x,y)//runde 4.41 bedeutet, dass bestätigt ist, dass der Laser die blaue Station treffen würde
    2. {
    3. if direction=90 and LaserblueCOM.x>AIlaser.x and LaserblueCOM.y<AIlaser.y//Bewegung nach oben, linker unterer Bereich
    4. {
    5. instance_create(x,y,mirrorright)//mirrorright ist mein \ spiegel, mirrorleft wäre /
    6. instance_destroy()
    7. global.Runde=1
    8. }



    Ein Anderes Szenario wäre, dass der Laser ungestört bis zu einer der gelb markierten X oder Y Achse der blauen Station kommt:


    Hierbei würde dann an der ersten freien Stelle, hier orange markiert, ein zufällig gewählter Spiegel ( instance_create(x,y,choose(mirrorright,mirrorleft)) ) bilden, falls der Laser nach rechts fliegt.


    Alles in einem bedeutet das:

    Laser im linken, oberen Bereich: Richtung nach rechts oder nach unten ( / Spiegel)
    Laser im rechten, oberen Bereich: Richtung nach links oder nach unten ( \ Spiegel)
    Laser im linken, unteren Bereich: Richtung nach oben oder nach rechts ( \ Spiegel)
    Laser im rechten, unteren Bereich: Richtung nach oben oder nach links ( / Spiegel)

    und bei den gelb markierten Bereichen würde ein zufälliger Spiegel enstehen, falls sich der Laser auf diese zubewegt.


    Mein Problem ist allerdings, dass sich die Objekte im 8x8 Gitter, auf denen sich ihre Mittelpunkt befinden, generiert werden und sich nicht nach dem 16x16 Gitter richten.
    Dass heißt das das Szenario 1 nicht in dem oberen Bild endet, sondern eher in soetwas:








    Kurze Steuerungserklärung:
    Leertaste: In roter Runde (1) wird ein Laser geschossen
    Pfeiltasten: Bewegen des Auswahlgitters links oben
    A-Taste: Ändern des zu platzierenden Spiegels ( der Sprite des Auswahlgitters verändert sich, ihr werdet wissen welchen Spiegel ihr platzieren werdet)
    D-Taste: Platzieren des ausgewählten Spiegels an der x und y position des Auswahlgitters.

    Rundenerklärung:
    1: Spielzug Rot
    3.1: Roter Spielzug, Ende (nach Laserschuss)
    3.2: Blauer Spielzug, Ende (nach Laserschuss)
    2: Spielzug Blau
    4.1: Angriffspielzug Blau (Fake-Laserspawn zum Überprüfen, ob Blau Rot treffen könnte)
    wenn Angriff möglich >4.2: Echter Laserspawn (dann 3.2)
    wenn nicht möglich
    > 4.3 und 4.31: Verteidigungszug Blau (Fake-Laserspawn zum Überprüfen, ob Rot Blau treffen könnte)
    wenn Verteidigung nötig 4.4 ( Erneuter Fake-spawn, diesmal mit Spiegelplatzierung an freier Stelle, nach Spiegelspawn Runde 1)
    wenn nicht nötig: 4.5 (Fake-Spawn, diesmal mit roter Laserstation im Mittelpunkt und dem Spiegel-Ziel, den Mittelpunkt zu erreichen)



    Jedenfalls: hier die GMK's.

    pewpew V0.6 hat noch keinen Code für die einzelnen Bereiche, es besitzt nur einen Code für den oberen, mittleren Bereich über der blauen Station. Aber dort stellt es in der Runde 4.41 einen wunderschönen Spiegel her.
    mediafire.com/download/0ud08a3soa16yth/pewpewV0.6.gm81

    pewpew V0.61 besitzt für jeden Bereich einen Code (leider nochnicht sortiert), man kann sich im Spiel entscheiden ob man direkt über der roten Station einen Spiegel oder über der blauen Station einen platzieren möchte.
    Beim Platzieren des rechten oberen, wird ein Spiegel \ zur hälfte in der roten Station gespawnt. Beim Platzieren eines Spiegels über der roten Station wird jedoch ein Spiegel im 16x16 Gitter gespawnt.
    mediafire.com/download/gkb0t952cs5wtv3/pewpewV0.61.gm81

    pewpew V0.61 (2) ist die Version, woran ich gerade arbeite (der Code ist sortiert), ist der Platz über der Station frei, funktioneirt es einwandfrei, ist dort allerdings schon ein Spiegel wird der neue Spiegel zwar im 16x16 gitter gespawnt, aber ohne rücksicht auf den anderen Spiegel (ein Spiegel platziert sich über dem anderen, dass in dem Bug ausartet, das der Laser durch die Spiegel hindurchfliegt, da er zuerst einen Spiegel trifft, somit nach <- geleitet wird und dann auf den zweiten, und somit nach oben gleitet wird)
    mediafire.com/download/39a9715…/pewpewV0.61_%282%29.gm81


    Huch, das war jetzt aber ein langer Post 8|

    Edit: Tut mir leid, dass mit den Links musste sein, da ich hier keine .gm81 Dateien anhängen kann :(
    Im Internet weiß niemand, dass du ein Truthahn bist.
    ich kann das jetzt nicht alles lesen aber du willst warscheinlich das der computer
    den anderen treffen soll
    dann prüfe bei den laser schuss der unsicht bar ist ob er den spieler berührt und wenn ....(hast du ja schon)
    dabei solltest du aber das machen:
    unsichbaren laser:
    create:

    Quellcode

    1. ho=0
    2. ver=0

    step:

    Quellcode

    1. if place_meeting(x,y,spieler)
    2. ho=0
    3. ver=0
    4. if x+ho>spieler.x
    5. ho-=1
    6. if x+ho<spieler.x
    7. ho+=1
    8. if y+ver>spieler.y
    9. ver-=1
    10. if y+ver<spieler.y
    11. ver+=1

    computer:
    step:

    Quellcode

    1. x=ho
    2. y=ver

    ich hoffe ich konnte dir helfen ^^
    an meinen codes gibt es oft fehler (nur so als tipp) ^^
    Ein Bug ist mehr als nur ein Bug, es ist ein... Käfer!
    Egal, wie gut du eine Mauer baust, sie fällt um.... der klügere gibt nach :D

    Willst du mit mir auf Discord Chatten/Quatschen?
    Meine Husi's Tutorial Reihe
    Wäre vielleicht auch ganz gut, wenn du mir erklärst was dein Code denn genau machen soll, denn ich kann gerade nicht wirklich viel in dem Code erkennen ?(


    Außerdem bin ich gerade dabei, den Verteidigungscode zu schreiben :)


    Zuerst wird mit dem unsichtbaren Laser geprüft, ob der menschliche Spieler (auf den Bilder ROT) die blaue Station des Computers treffen könnte.

    Wenn das der Fall ist wird eine weitere Runde (4.4) eingeleitet, welche dann, abhängig von dem Bereich in der sich der unsichtbare Laser befindet, einen Spiegel an der ersten, freien Stelle erstellt.
    (Das einzige Problem ist jetzt, dass der Laser durch die prezise Kollisionsmaske des Spiegels diesen nicht als "belegter" Gitterpunkt wertet)



    Für den Angriffscode kann ich ja einfach schreiben, dass ein Spiegel erstellt werden soll, wenn der Laser auf der selben x/y Achse der roten Station ist.
    Im Internet weiß niemand, dass du ein Truthahn bist.
    achso wenn du den verteidigungs code schreiben willst geht der nicht
    der war für den angriff gedacht
    Ein Bug ist mehr als nur ein Bug, es ist ein... Käfer!
    Egal, wie gut du eine Mauer baust, sie fällt um.... der klügere gibt nach :D

    Willst du mit mir auf Discord Chatten/Quatschen?
    Meine Husi's Tutorial Reihe