Step Event vor End Step Event- Funktioniert manchmal, manchmal nicht?

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

  • Step Event vor End Step Event- Funktioniert manchmal, manchmal nicht?

    Hallo Community,

    Ich habe mich schon eine Weile nichtmehr blicken lassen, die meisten von euch haben wahrscheinlich garnicht von mir gehört, weil ich in letzter Zeit mit der Arbeit schon genug zu tun habe, aber das ist jetzt egal:

    Ich habe ein Problem mit dem Nutzen vom Step und EndStep Event. Ich habe bereits einiges an Google-ergebnissen deswegen durchsucht und auch befreundete Programmierer, die mehr Ahnung von GM haben als ich, befragt, aber die konnten mir auch nicht weiterhelfen, deswegen bin ich hier.


    Für die eigentliche Frage bitte nach unten Scrollen,
    ich erkläre jetzt nur wie das Spiel aufgebaut ist, um euch eine Idee davon zu geben was ich erreichen will:

    Das Spiel ist ein Multiplayer (Mehrspieler -an einem Computer) Spiel, dass in Runden gespielt wird. Jeder Spieler besitzt eine Laserstation.
    Ziel des Spieles ist es, jeden Zug dazu zu nutzen, Spiegelobjekte so zu platzieren, dass man seine Gegner ausschalten kann, oder so, dass der Gegner einen in seinem Zug nicht treffen kann.
    Jedem Spieler steht dazu eine begrenzte Zeit zur Verfügung, weshalb man schnell reagieren muss, bevor der Zug umsonst war.

    Eine GIF-Animation des Spielsystems findet sich in diesem Spoiler:


    Der Spielmodi für menschliche Spieler funktioniert bereits ohne Probleme(ausgenommen einiger Bugs, deren Lösung mir aber schon im Kopf liegt)



    Ich arbeite seit einiger Zeit an einem System für einen virtuellen Gegner (a.k.a AI-Gegner), ich habe bereits ein volles System, dass seinen Zweck erfüllt, zusammengeschrieben und bin dabei, es in GM umzusetzen, bin dabei allerdings auf ein Problem gestoßen.

    Ich arbeite beim AI-Gegner mit Objekten (AI-Lasern), die sich im Step-Event bewegen und ebenfalls im End-Step-Event "Pfeilobjekte" (genaueres unten) platzieren, um schnellstmöglichst herauszufinden, ob und aus welcher Richtung eine der Lasterstation getroffen wird. Zusätzlich dazu wird im End-Step geprüft, ob der AI-Laser sich auf einem Spiegelobjekt befindet (wodurch die .direction geändert wird) oder ob er sich auf einer Laserstation befindet (wodurch, abhängig von einer global variable, die global variable verändert wird, womit die AI weiß, ob der Gegner sie treffen kann/sie den Gegner treffen kann).

    Im Spoiler ist der Code vom AI-Laser, einmal Step und einmal End-Step:

    Spoiler anzeigen

    GML-Quellcode

    1. //STEP-EVENT für die Bewegung des AI-Lasers in die entsprechende Richtung (50 entspricht einem Quadrat im Grid)
    2. if direction=90
    3. {
    4. AIlaserb.y=AIlaserb.y-50
    5. }
    6. else if direction=180
    7. {
    8. AIlaserb.x=AIlaserb.x-50
    9. }
    10. else if direction=270
    11. {
    12. AIlaserb.y=AIlaserb.y+50
    13. }
    14. else if direction=0
    15. {
    16. AIlaserb.x=AIlaserb.x+50
    17. }
    Alles anzeigen



    Spoiler anzeigen

    GML-Quellcode

    1. //END-STEP-EVENT für das Prüfen von Kollisionen
    2. if place_meeting(x,y,red) // red=Laserstation Menschlicher Spieler
    3. {
    4. if global.runde=2.31// Runde-Angriff möglich? (Runde prüft, ob bluai(AI-Gegner) den menschlichen Spieler trifft und leitet dann die nächste Runde ein)
    5. {
    6. global.runde=2.32// Runde-Angriff möglich. Selbstkill?(Angriff wäre möglich, aber der AI-Laser wird nicht zerstört, um zu prüfen ob sich die AI im weiteren Flug des Lasers selber treffen würde)
    7. }
    8. }
    9. if place_meeting(x,y,bluai) // bluai="werhätteeserraten?"Laserstation AI-Gegner
    10. {
    11. if global.runde=2.31 or global.runde=2.32// Wenn der AI-Laser den AI-Gegner trifft, wird die nächste Runde (zur Verteidigungsprüfung) eingeleitet, da sie sich selber treffen würde, wenn sie schießt
    12. {
    13. instance_destroy()
    14. global.runde=2.51//Runde zur Prüfung, ob Verteidigung nötig wäre(sprich, ob red bluai abschießen könnte)
    15. }
    16. }
    17. // vv Prüfen, ob der AI-Laser durch einen Spiegel abgelenkt werden muss, bevor der nächste Step beginnt vv
    18. if place_meeting(x,y,mirl)
    19. {
    20. if direction = 90
    21. {
    22. direction = 180
    23. }
    24. else if direction = 270
    25. {
    26. direction = 0
    27. }
    28. else if direction = 0
    29. {
    30. direction = 270
    31. }
    32. else if direction = 180
    33. {
    34. direction = 90
    35. }
    36. }
    37. if place_meeting(x,y,mirr)
    38. {
    39. if direction = 90
    40. {
    41. direction = 0
    42. }
    43. else if direction = 270
    44. {
    45. direction = 180
    46. }
    47. else if direction = 0
    48. {
    49. direction = 90
    50. }
    51. else if direction = 180
    52. {
    53. direction = 270
    54. }
    55. }
    56. //////////////////////////
    57. // vv Platzieren eines "Pfeilobjekts", damit man die Flugbahn nachverfolgen kann und später, wenn nötig, an den entsprechenden Stellen einen Spiegel platzieren kann vv
    58. if direction=90
    59. {
    60. if place_meeting(x,y,bluup)
    61. {
    62. instance_destroy() // Instance_destroy ist dafür da, falls der AI-Laser im Kreis fliegen sollte, damit er sich zerstört, statt endlos im Kreis zu fliegen
    63. }
    64. else
    65. instance_create(x,y,bluup)
    66. }
    67. else if direction=0
    68. {
    69. if place_meeting(x,y,bluri)
    70. {
    71. instance_destroy()
    72. }
    73. else
    74. instance_create(x,y,bluri)
    75. }
    76. else if direction=180
    77. {
    78. if place_meeting(x,y,blule)
    79. {
    80. instance_destroy()
    81. }
    82. else
    83. instance_create(x,y,blule)
    84. }
    85. else if direction=270
    86. {
    87. if place_meeting(x,y,bludo)
    88. {
    89. instance_destroy()
    90. }
    91. else
    92. instance_create(x,y,bludo)
    93. }
    Alles anzeigen


    Aber jetzt kommt das Problem:
    Der Code im End-Step Event, für die Prüfung dessen, ob der AI-Laser von einem Spiegel apprallt oder nicht und der, der für das Platzieren der "Pfeilobjekte" zuständig ist, funktioniert tadellos.
    Aber manchmal passiert es, dass der Code für die Kollisionsprüfung mit der roten Laserstation und der blauen AI-Laserstation einfach nicht abgespielt wird, als ob die Stationen garnicht dawären.

    Ich hab schon probiert End-Step und Step Event zu tauschen, ich hab schon probiert den Sprite des AI-Lasers zu ändern, weil die Zwischenräume bei den Stationen genausogroß sind wie der Laser, ich hab schon probiert die Codeelemente für die Laserstation-Kollisionen über / unter denen für die Spiegel zu platzieren, aber irgendwie hat nichts geholfen.



    Und hier endlich die eigentliche Frage:
    Die Kollisionsprüfung für die Spiegel und das Platzieren funktioniert immer, ausnahmslos, aber die für die Laserstationen klappt manchmal- und manchmal nicht, obwohl sie gleich aufgebaut sind. Wieso ist das so, und wie behebe ich das?
    (Ich arbeite mit GM: Studio, falls das wichtig sein sollte)


    Hier übrigens noch ein Gif, das zeigt, dass der AI-Laser mal wahrnimmt, dass er etwas getroffen hat, und mal nicht. Eigentlich sollte es in dem Szenario nie soweit kommen, dass der rote AI-Laser gefeuert wird, da die blaue AI-Station freie Bahn auf die rote Spieler-Station hat, ohne sich dabei selbst zu töten:



    Ich möchte ürbigens allen danken, die sich die Zeit nehmen das hier zu lesen.
    Im Internet weiß niemand, dass du ein Truthahn bist.
  • Es kann sein, dass es an dem Vergleich in Zeile 4 oder 12 liegt. Das Problem ist, dass Gleitkommazahlen sehr selten exakt sind und somit als nicht gleich gewertet wird. Es ist möglich eine gewisse Toleranz einzustellen. Es sollte dafür genügen einmal die Funktion math_set_epsilon(0.001); aufzurufen.

  • Chris987 schrieb:

    Das Problem ist, dass Gleitkommazahlen sehr selten exakt sind und somit als nicht gleich gewertet wird. Es ist möglich eine gewisse Toleranz einzustellen. Es sollte dafür genügen einmal die Funktion math_set_epsilon(0.001); aufzurufen.

    Eigentlich sollte es mit der Genauigkeit der Kommazahlen keine Probleme geben, da sie immer auf einen fest vorgegebenen Wert gesetzt wird, aber ich hab es trotzdem mal mit math_set_epsilon probiert (im End-Step und einmal im Create-Event), leider ohne Erfolg.
    Ich habe auch zum Testen alle Kommazahlen des global.-Werts kurzerhand in ganze Zahlen umgeschrieben, aber das Problem ist immernoch vorhanden.
    Im Internet weiß niemand, dass du ein Truthahn bist.