Move till solid contact problem

  • GM 7

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

  • Move till solid contact problem

    Hi.
    Ich habe heute angefangen, mal wieder nach dem yoyogames-tutorial eine platformengine aufzubauen, diesmal aber mit gml. bin grade beim jumpen, aber ich werde das problem nicht los, dass er durch das move_contact_solid kurz stehenbleibt, und zwar, während er sich nach dem collision-event zum block bewegt.
    Hat irgendjemand eine Ahnung, wie man das umgehen kann? In meiner ersten engine, in der ich drag'n'drop verwendet habe, hatte ich das problem nicht :S

    Danke schonmal,
    Raffo
    Dateien
    • game.zip

      (14,41 kB, 139 mal heruntergeladen, zuletzt: )
  • Hallo

    versuche es mal so in dein player movement script

    GML-Quellcode

    1. if (keyboard_check(vk_right) && place_free(x + 1,y)){
    2. x += 8;
    3. } else if (keyboard_check(vk_left) && place_free(x - 1, y)){
    4. x -= 8;
    5. }
  • Okay, danke schonmal.
    Das ist wahrscheinlich sauberer als mein Code, aber es hat das Problem leider nicht gelöst... nach dem landen bleibt der block immer noch kurz stehen.
    Ausserdem bin ich verwirrt: der origin der blocksprite sitzt doch in der linken ecke oben, oder? muss man die place_free - angaben nicht ensprechend anpassen?
    Und: der block "zittert" jetzt kurz hin und her, wenn er seitlich auf einen anderen block trifft.
    neue datei angehängt.
    Dateien
    • game.zip

      (11,57 kB, 147 mal heruntergeladen, zuletzt: )
  • Um mal ein paar DInge klarzustellen: der erste Vorschlag von bommel ist wohl eher eine Verschlimmbesserung. Wenn ich den Spieler 8 pixel nach rechts verchieben will, muss ich auch prüfen, ob 8 pixel rechts von mir frei ist, und nicht nur der erste Pixel.

    Dass die Figur "zittert" und sich beim schrägen Landen trotzdem senkrecht nach unten bewegt, liegt an der direction. Der Befehl "move_contact_solid(direction, 12)" macht nichts anderes, als die Figur bei der bevorstehenden Kollision (Kollisonen mit solids werden immer einen Step im Voraus berechnet) in die Richtung "direction" zu setzen, maximal 12 pixel (maximal daher, da es weniger wären wenn ein solid im Weg ist).
    So. Das Problem liegt an der direction: die ergibt sich aus den eingebauten Variablen hspeed und vspeed. Wenn die Bewegungen nach links und rechts aber nicht mit hspeed, sondern z.B. mit "x+=5" gemacht werden, bleibt hspeed logischerweise aus 0. Das "x+=5" ist ja nichts anderes als ein Sprung an eine andere Stelle, die von GameMaker nicht automatisch als Bewegung erkannt wird. In deinem Fall ist die direction also immer entweder 90 (nach oben) oder 270 (nach unten). Daher geht das move_contact_solid immer gerade nach unten, obwohl es manchmal auch diagonal, also in Bewegungsrichtung gehen sollte.
    Als Lösung würde sich eine Hilfsvariable anbieten, die die korrekte direction angibt, etwa delta_dir. Die lässt sich durch "point_direction(xprevious, yprevious, x, y)" berechnen. Das gehört in das end_step-Event, da xprevious und x ansonsten immer gleich sind (die Objekte werden erst nach dem normalen step-Event verschoben). Ins move_contact_solid kommt dann logischerweise statt direction unser delta_dir.

    Aber der lustige Teil kommt noch: jetzt wird er zwar korrekt an den Boden oder die Wände "herangezogen", was das schlimmste ruckeln beseitigt. Aber es ruckelt immer noch unter betimmten Bedingungen. Ich selbst kenne das, und es gibt auch ein paar ungelöste Threads in den offiziellen Foren dazu. Warum die seitliche Bewegung manchmal für einen step anhält, weiß offenbar niemand - vermutlich Programmierfehler im GM. Workauround: crank that shit up. Setz den room_speed auf 60, und das ruckeln wird so kurz, dass man es nicht mehr bemerkt.

    Nachtrag: bei Kollisionsfunktionen wie place_free wird nicht vom Origin ausgegangen, sondern von der gesamten Kollisionsmaske. Also ist x-1 in dem Fall ein Pixel links daneben, und y + 12 wäre 12 Pixel unter der Figur.
  • Okay, vielen vielen dank. das hat mir sehr geholfen. ich hab das genauso umgesetzt (glaub ich zumindest), und es ruckelt jetzt auch nicht mehr.
    aber die bounding box oder etwas ähnliches spielt verrückt. Wenn man mal so herumspringt, "schwebt" die box manchmal ein paar pixel über dem boden, und manchmal kann man sich ganz seitlich an die boxes ranbewegen, manchmal ist da aber eine unsichtbare grenze (auch ein paar pixel gross).
    Dateien
    • game.zip

      (16,11 kB, 146 mal heruntergeladen, zuletzt: )
  • Habe mich schnell an die 'arbeit' gemacht und das Problem mit der Unsichtbaren Grenze behoben.
    Du hattest in deinem Code vorher geprüft ob neber dem Spieler 10 Pixel frei sind, wenn ja bewegt er sich.
    Aber sind bei einem falschen Movement nur z.B. 9 Pixel frei bleibt er davor stehen.
    Also hier die verbesserung:

    Edit:
    Mir ist aufgefallen das auch das zweite Problem leicht zu beheben war, ungefähr genau das gleiche wie beim ersten.
    Also nochmals die verbesserung ;D :
    Dateien

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

  • Im Player-Movement:

    GML-Quellcode

    1. //check the keys
    2. if (keyboard_check(vk_right) && place_free(x + 1, y))
    3. {x += 10}
    4. else if (keyboard_check(vk_left) && place_free(x - 1, y))
    5. {x -= 10}
    6. if (keyboard_check(vk_up))
    7. {vspeed = -10}
    8. //and the gravity settings
    9. if (place_free(x,(y + 1)))
    10. {
    11. gravity_direction = 270
    12. gravity = 2
    13. }
    14. else
    15. {
    16. gravity = 0
    17. }
    18. if (vspeed > 12)
    19. {
    20. vspeed = 12
    21. }
    Alles anzeigen



    Edit:
    Also das ist das einzigste, einfach kopieren und ersetzen.

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