Point and Click Steuerung führt zu infinite loop

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

  • Point and Click Steuerung führt zu infinite loop

    Hallo,

    Ich versuche mich grade an einer point-to-click Steuerung. Sinn und zweck solle sein, das Objekt in dessen STEP das Skript liegt, zur geklickten Stelle zu bewegen und dann stehen zu bleiben. Meine ersten Versuche führten dazu das es sich zwar bewegte, dann aber nicht mehr stehen blieb. Also hab ich die das "if distance_to_point" mal rausgeworfen und das ganze auf eine while schleife umgeschrieben. Jedoch wird diese zwar aktiviert, das Object bewegt sich aber nicht, daher wird sie nie erfüllt und läuft infinite.

    Hier mal der Code:

    GML-Quellcode

    1. /// scr_move_to_mouse
    2. // script to move the object to the clicked position
    3. if (mouse_check_button(mb_left)) { // check if the player was clicking the mouse
    4. click_pos[0] = mouse_x;
    5. click_pos[1] = mouse_y; // fetch the actual X and Y coordinates of the clicked point
    6. while (distance_to_point(click_pos[0], click_pos[1]) >= 10) { // as long as the distance to the position is greater or equal 10 ..
    7. move_towards_point(click_pos[0], click_pos[1], 5); // move towards the clicked position.
    8. }
    9. }


    Kann jemand sehen wo ich was falsch mache? Sollte ich vielleicht mal ins Bett gehen?

    Grüße, VB

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von VoidByte ()

  • hi ich hab mal was ähnliches gemacht

    funtzt

    nicht vergessen im create variable move =0 setzen

    GML-Quellcode

    1. if mouse_check_button_released(mb_left)
    2. {
    3. posx = mouse_x;
    4. posy = mouse_y;
    5. move=1
    6. }
    7. if move =1
    8. {
    9. if distance_to_point(posx, posy) >= 30
    10. {
    11. move_towards_point(posx, posy, 5);
    12. }
    13. if move =1
    14. {
    15. if distance_to_point(posx, posy) < 10
    16. {
    17. move_towards_point(posx, posy, 0);
    18. move=0;
    19. }
    20. }
    21. }
    Alles anzeigen
  • Das Check ich nicht ganz.
    Das Event feuert ja 60 mal in der Sekunde. Jedoch wird in der Zeit nur einmal "mouse_check_button_released(mb_left)" true sein.
    Und damit der unten stehende Codeblock nur einmal ausgeführt. Will ja die Maustaste nicht gedrückt halten.
    Wieso weiß das System dann, wie groß die Distanz ist? Er prüft es bei deinem Skript ja nur einmal nach dem klick, und nicht alle 60 FPS
    ergo würde der Wert ja nicht aktualisiert?!
  • Nicht ganz.
    Zum Zeitpunkt wo die linke Maustaste losgelassen wird, speichert er die aktuellen x und y koordinaten in posx und posy und die variable move wird auf 1 gesetzt.
    Dann wird der Codeblock geschlossen per " } "

    Dann fängt eine neue Abfrage an und zwar ob move gleich 1 ist. Da die Variable noch nicht zurückgesetzt wurde, wird dieser Codeblock 60 mal die sekunde abgefragt bis die move wieder 0 ist.


    Ich hoffe ich konnte das halbwegs verständlich erklären. :)
    Für jene, die ständig das Scheitern fürchten, sind Erfolge auf ewig unerreichbar.
  • also ich hab das jetzt mal so übernommen mit der Move Variable:

    GML-Quellcode

    1. /// scr_move_to_mouse
    2. // script to move the object to the clicked position
    3. if (mouse_check_button(mb_left)) { // check if the player was clicking the mouse
    4. click_pos[0] = mouse_x;
    5. click_pos[1] = mouse_y; // fetch the actual X and Y coordinates of the clicked point
    6. move_towards_point(click_pos[0], click_pos[1], 5); // move towards the clicked position.
    7. moving = true;
    8. if (distance_to_point(click_pos[0], click_pos[1]) < 10 && moving = true) { // as long as the distance to the position is greater then 10 ..
    9. speed = 0; // stop moving if target is reached
    10. moving = false; // set the moving state to hold
    11. }
    12. }
    Alles anzeigen

    Und bei mir hört das object nicht auf sich zu bewegen.
    Wenn ich es allerdings anklicke, während es sich bewegt, dann stopt es sofort.. wie erwartet.
  • So wie der code da steht kann er doch gar nicht funktionieren?
    Du fragst ja ab ob die linke Maustaste gedrückt wird aber wenn du los lässt ist die Bedingung ja nicht mehr erfüllt somit kann auch distance_to_point auch nicht weiter ausgeführt werden und moving niemals false werden.
    Für jene, die ständig das Scheitern fürchten, sind Erfolge auf ewig unerreichbar.
  • abfragen ob der objekt ziel erreicht hat solltest als extra abfrage einbauen.

    manchmal denken die menschen zu umständlich obwohl es einfacher auch geht.
    ob du bei einem objekt jetzt 1 oder 3 if abfragen hast wird kein unterschied machen.

    estelle doch statt move towards point einfach nen pfad. dann stopt er automatisch, dh brauchst keine abfrage mehr
  • Rotfuchs7 schrieb:


    Du fragst ja ab ob die linke Maustaste gedrückt wird aber wenn du los lässt ist die Bedingung ja nicht mehr erfüllt somit kann auch distance_to_point auch nicht weiter ausgeführt werden und moving niemals false werden.


    Ja.. genau DAS hab ich ja in meinem Vorposting schon hinterfragt weil ichs nicht verstand. Dann sagtest du "doch die abfrage ob bedingung erfüllt bleibt offen" und ich dachte mir "nun gut.. son game maker ding halt". Und jetzt sagst du, das es nicht geht, weil das Event zur Laufzeit nicht mehr die Bedingungen erfüllt ;D,

    Edit: Sorry, habs schon gechecked! Ich seh jetzt erst das bei Crusher nicht eine riesige verschachtelte if abfrage läuft, sondern 5 Separate. Das erklärt auch die Verwirrungen

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von VoidByte ()

  • move_towards_point setzt nur die speed und direction variable, desshalb muss es nur einmal aufgerufen werden.
    dann brauchst du nur eine Abfrage

    GML-Quellcode

    1. if (point_distance(x,y,dest_x,dest_y) < speed) { //wenn Distanz zu Ziel kleiner als Geschwindigkeit
    2. speed = 0; //Setze Geschwindigkeit auf 0
    3. x = dest_x; // Platziere Objekt an Zielposition
    4. y = dest_y; //
    5. }
    132 little bugs in the code. 132 little bugs. Fix a few, set the compiler to stew, 172 little bugs in the code... :vogel:
  • Habs jetzt so gelöst:

    Im CREATE =

    GML-Quellcode

    1. /// init variables
    2. moving = false;
    3. posx ="";
    4. posy ="";

    Haupsächlich zum Scopen, da ich die Scopes in GMS noch nicht checke.


    Im STEP:

    GML-Quellcode

    1. /// scr_move_to_mouse
    2. grid = mp_grid_create(0,0,room_width/32,room_height/32,32,32);
    3. mp_grid_add_instances(grid, obj_wall, true);
    4. // script to move the object to the clicked position
    5. if (mouse_check_button_released(mb_left)) { // check if the player was clicking the mouse
    6. posx = mouse_x;
    7. posy = mouse_y; // fetch the actual X and Y coordinates of the clicked point
    8. moving = true;
    9. }
    10. if (distance_to_point(posx, posy) < 10){ // check the distance between the object and the clicked position
    11. speed = 0;
    12. moving = false;
    13. }
    14. if (moving == true && mp_grid_path(grid, walkpath, x, y,posx, posy, true)){
    15. path_start(walkpath, 5, path_action_stop, true);
    16. }
    Alles anzeigen


    der Pfad hat nur einen Startpunkt, der Rest wird generiert. Funktioniert genau wie erhofft.
    Jetzt muss ich nur noch kapieren wieso mein Sprite sich nicht mehr in die richtige Richtung dreht, was es vorher noch fleißig tat.

    Zwischenstand:
    (Grün = Begehbar, Rot = nicht begehbar.. hab mir zur Kontrolle das Grid zeichnen lassen.)
    VoidByte Happy!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von VoidByte ()

  • Du erstellst im Moment 60 mal die Sekunde ein neues Grid ohne jemals eins zu löschen, das wird nicht gut gehen
    @Problem
    Es fehlt jetzt das setzen der image_angle variable.
    image_angle = point_direction(xprevious,yprevious,x,y);
    132 little bugs in the code. 132 little bugs. Fix a few, set the compiler to stew, 172 little bugs in the code... :vogel:
  • rhazul ---warst schneller..

    edit: du solltest das mp_grid_create ins CREATE verschieben
    ich benutze bei paths zb

    GML-Quellcode

    1. image_angle=direction

    vobei der origin sprite nach rechts also auf direction 0 ausgerichtet sein sollte

    mfg. CodeCrusher
  • Ok, also ich hab das jetzt mal dahingehend optimiert das dass Grid im CREATE event aufgebaut wird. Ausserdem musste ich die Größe etwas justieren, weil ich gemerkt habe dass ich trotz "percise"-Collision Mask nicht wirklich durch die Wege komme (habe mir ein kleines Wegfindungs-Testgebiet zumannengeklatscht, siehe video).

    Wegen der Rotation bzw. der Direction hab ich allerdings noch etwas probleme. Wenn man die Figur jetzt direkt steuert funktioniert sie. Wenn man der Figur aber einen Punkt gibt, bei der sie sich selbst den Weg suchen muss, dann geht das vorn und hinten nicht mehr.
    Jetzt ist die Frage: Gibts nicht irgend ne Möglichkeit, sowas zu machen, dass sich der Sprite je nach path-direcion ändert? Also wenn das Männlein sich einen Pfad sucht, der nach rechts oben läuft, dann soll er "sprite_index = spr_player_up_right" ausführen? mit rotation zu arbeiten bietet sich bei Isometrischer perspektive nur bedingt an, vielleicht für einen letzten Feinschliff.

    Frage zur Isometrie. Also dieses Motion Planner System scheint entweder nicht für isometrie gemacht zu sein, oder ich bin schlichtweg zu blöde dazu (vermutlich isses das!). Denn wenn ich die Collision Mask auf Precise setze, dann habe ich zwar korrekt geblockte Felder, aber der Flair der Isometrie geht dadurch vollends verloren, da man halt auch nicht mehr hinter mauern laufen kann. Das manuelle Setzen von collision masks (so wies aktuell machte) is dagegen ein schlechter Witz.
    Kann ich nicht irgendwie meine Sprites doppelt erstellen und dann sagen "dieses ist die Mask für jenes"? So wie ne Height oder Bumpmap?

    Hier schonmal das Status Video:

    Und wers sehen mag, die listings:
    Spoiler anzeigen

    STEP Event - Player

    GML-Quellcode

    1. /// scr_move_to_mouse
    2. // script to move the object to the clicked position
    3. if (mouse_check_button_released(mb_left)) { // check if the player was clicking the mouse
    4. posx = mouse_x;
    5. posy = mouse_y; // fetch the actual X and Y coordinates of the clicked point
    6. moving = true; // set the system in "Moving" State
    7. }
    8. if (distance_to_point(posx, posy) < 10){ // if the distance between clicked position and the object is less then 10 ..
    9. speed = 0; // stop moving
    10. moving = false; // reset the moving state
    11. }
    12. // Pathfinding
    13. mp_grid_add_instances(grid, obj_wall_left, true);
    14. mp_grid_add_instances(grid, obj_wall_right, true);
    15. mp_grid_add_instances(grid, obj_wall_corner_down, true);
    16. mp_grid_add_instances(grid, obj_wall_corner_up, true);
    17. mp_grid_add_instances(grid, obj_wall_corner_left, true);
    18. mp_grid_add_instances(grid, obj_wall_corner_right, true);
    19. mp_grid_add_instances(grid, obj_wallTCross_down_left, true);
    20. mp_grid_add_instances(grid, obj_wallTCross_down_right, true);
    21. mp_grid_add_instances(grid, obj_wallTCross_up_left, true);
    22. mp_grid_add_instances(grid, obj_wallTCross_up_right, true);// adds obstacles to the grid
    23. if (moving == true && mp_grid_path(grid, walkpath, x, y, posx, posy, true)){ // check for everything is ready to move
    24. path_start(walkpath, 5, path_action_stop, true); // start moving and plan a path
    25. }
    26. // set the character in the right direction while moving around
    27. if (moving == true && posx <= x && posy <= y) {
    28. sprite_index = spr_player_up_left;
    29. }
    30. if (moving == true && posx >= x && posy <= y) {
    31. sprite_index = spr_player_up_right;
    32. }
    33. if (moving == true && posx >= x && posy >= y) {
    34. sprite_index = spr_player_down_right;
    35. }
    36. if (moving == true && posx <= x && posy >= y) {
    37. sprite_index = spr_player_down_left;
    38. }
    39. if (moving == false){
    40. sprite_index = spr_player_idle; // dont make anything while not wandering around
    41. }
    Alles anzeigen


    CREATE Event - Player

    GML-Quellcode

    1. /// Variables
    2. moving = false;
    3. posx = 1;
    4. posy = 1;
    5. grid = mp_grid_create(0,0,room_width/4,room_height/4,10,10);
    6. walkpath = path_add();


  • Mit den sprites für die jeweilige direction kannst du so mache:

    GML-Quellcode

    1. ​var dir = round(direction/45);
    2. if(dir==0)
    3. sprite_index = rechts;
    4. if(dir==1)
    5. sprite_index = obenrechts;
    6. //...

    am besten wäre das ja noch mit switch-case:

    GML-Quellcode

    1. ​var dir = round(direction/45);
    2. switch(dir){
    3. case 0:
    4. sprite_index...
    5. break;
    6. //...
    7. }
    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