Walljump mit fremder platformer Engine umsetzen

  • GM 8

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

  • Walljump mit fremder platformer Engine umsetzen

    Ich habe kürzlich eine nette Engine gefunden, welche eine super Kollisions-Abfrage hat. Credits gehen an Shaun Spalding.
    Das Problem ist jetzt, ich möchte einen Walljump einbauen, sodass man auch von der Wand abspringen kann.
    Ich komme aber mit der Engine nicht so wirklich klar und weiß nicht wie ich das umsetzen kann. Ein Versuch brachte mein Spieler "rutschend" in hohem Bogen über alle Wände.

    Create Event:
    Spoiler anzeigen

    GML-Quellcode

    1. grav = 0.8;
    2. hsp = 0;
    3. vsp = 0;
    4. jumpspeed = 12;
    5. movespeed = 4;

    Step Event:
    Spoiler anzeigen

    GML-Quellcode

    1. //smooth the camera
    2. camera_movement();
    3. //Get the player's input
    4. key_right = keyboard_check(vk_right);
    5. key_left = -keyboard_check(vk_left);
    6. key_jump = keyboard_check_pressed(vk_space);
    7. //React to inputs
    8. move = key_left + key_right;
    9. hsp = move * movespeed;
    10. if (vsp < 10) vsp += grav;
    11. if (place_meeting(x,y+1,obj_wall))
    12. {
    13. vsp = key_jump * -jumpspeed
    14. }
    15. //Horizontal Collision
    16. if (place_meeting(x+hsp,y,obj_wall))
    17. {
    18. while(!place_meeting(x+sign(hsp),y,obj_wall))
    19. {
    20. x += sign(hsp);
    21. }
    22. hsp = 0;
    23. }
    24. x += hsp;
    25. //Vertical Collision
    26. if (place_meeting(x,y+vsp,obj_wall))
    27. {
    28. while(!place_meeting(x,y+sign(vsp),obj_wall))
    29. {
    30. y += sign(vsp);
    31. }
    32. vsp = 0;
    33. }
    34. y += vsp;
    Alles anzeigen
  • Naja, du weißt ja, dass wenn links oder rechts vom Spieler eine Wand ist, und unter ihm kein Boden, ein Wall Jump ausgeführt werden kann. Und dann muss ja eigentlich nur die vspd und hspd gesetzt werden.

    GML-Quellcode

    1. // Wall Jump
    2. if((place_meeting(x + 1, y, obj_wall) ^ place_meeting(x - 1, y, obj_wall)) &! place_meeting(x, y + 1, obj_wall) && key_jump) {
    3. // Die vertikale Speed setzen wir hier auf die normale Sprunghöhe.
    4. vsp = -jumpspeed;
    5. // Wenn der Spieler rechts eine Wand trifft (x + 1), dann setzen wir die horizontale Speed auf -4. Wenn er links eine
    6. // Wand trifft (x - 1) auf 4, um ihn von der Wand abspringen zu lassen.
    7. hsp = place_meeting(x + 1, y, obj_wall) * -4 + place_meeting(x - 1, y, obj_wall) * 4;
    8. }

    Kann sein, dass der Code nicht oder nicht ganz funktioniert, ich habe ihn jetzt einfach hier im Post geschrieben. Es wäre trotzdem schöner dir zu helfen, wenn du uns deinen "Fehlversuch" zeigst und man darauf aufbauend eine Lösung findet. ;)

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von ghost ()

  • An sich schon mal ein super Ding, nur sollte ein Walljump nur von Wand zu Wand möglich sein.
    Jetzt kann man jedoch an einer Wand immer weiter nach oben springen.

    Zudem fällt der Walljump sehr schwer, da man die Tasten sofort drücken muss um einen Walljump auszuführen. Hoffe das ist verständlich.
    Der Spieler müsste ein wenig an der Wand "kleben" ähnlich wie bei SuperMeatBoy. Sodass man etwas mehr Zeit hat, den Sprung zu machen.
    Und es ist auch schwierig an Höhe zu gewinnen wenn man von Wand zu Wand springt.

    In folgendem Link wurde das ganze schon mal diskutiert. Allerdings in Englisch. Ich kann dem Thema leider nicht wirklich folgen. Vielleicht könnte es euch aber helfen, mir behilflich zu sein :)
    Link: gmc.yoyogames.com/index.php?showtopic=614107

    (Wenn sie fertig ist, würde ich hier die komplette Plattform Engine auch rein setzen)

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

  • Naja, du musst halt selbst mit den Werten spielen und den Teil mit der vertikalen Speed verschieben und bearbeiten. Das ist nicht schwer und erfordert eigentlich nur Fleiß.

    GML-Quellcode

    1. var stick;
    2. stick = false;
    3. // Wall Jump
    4. if((place_meeting(x + 1, y, obj_wall) ^ place_meeting(x - 1, y, obj_wall)) &! place_meeting(x, y + 1, obj_wall) && key_jump) {
    5. // Die vertikale Speed setzen wir hier auf die normale Sprunghöhe.
    6. vsp = -jumpspeed;
    7. // Wenn der Spieler rechts eine Wand trifft (x + 1), dann setzen wir die horizontale Speed auf -4. Wenn er links eine
    8. // Wand trifft (x - 1) auf 4, um ihn von der Wand abspringen zu lassen.
    9. hsp = place_meeting(x + 1, y, obj_wall) * movespeed + place_meeting(x - 1, y, obj_wall) * movespeed;
    10. stick = true;
    11. }
    12. //Gravity
    13. if(stick) {
    14. // Wenn der Spieler an der Wand klebt, soll er langsamer fallen
    15. if (vsp < 5) vsp += grav / 2;
    16. else vsp = 5;
    17. } else {
    18. // Wenn der Spieler nicht an der Wand klebt, soll er normal fallen
    19. if (vsp < 10) vsp += grav;
    20. }
    Alles anzeigen


    Das Problem, dass du einfach an der gleichen Wand hochspringen kannst liegt denke ich daran, dass die Bewegung keine Beschleunigung hat.

    GML-Quellcode

    1. hsp = move * movespeed;


    Hier müsste noch Beschleunigung rein. Also zum Beispiel so in der Art:

    GML-Quellcode

    1. if(hsp < move * movespeed) {
    2. hsp += acceleration;
    3. }
    4. if(hsp > move * movespeed) {
    5. hsp -= acceleration;
    6. }

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von ghost ()

  • @ghost Ja, mein Problem ist, dass ich nicht wirklich gut in Sachen Logik bin und mir deshalb so etwas sehr schwer fällt.
    Aber ich habe auch niemanden, der meine Ideen umsetzt und muss das daher alles selbst machen. Ich möchte mich natürlich dennoch bemühen :)

    Zu deinem Code, "acceleration" müsste ich ja nur durch einen beliebigen Wert ersetzen, oder?
    Jedenfalls funktioniert das nicht wirklich. Der Spieler bleibt jetzt nicht kleben, kann immer noch an einer Wand beliebig oft hinauf springen und die Sprunghöhe wird vermindert.
  • Ja dafür kannst du einsetzen was du willst. Ich habe es jetzt mal ausprobiert. Hier ist mein Kompletter Code:

    :event_create: Create
    Spoiler anzeigen

    GML-Quellcode

    1. grav = 0.8;
    2. hsp = 0;
    3. vsp = 0;
    4. jumpspeed = 12;
    5. movespeed = 4;
    6. acceleration = 0.75;


    :event_step: Step
    Spoiler anzeigen

    GML-Quellcode

    1. var stick;
    2. stick = false;
    3. //Get the player's input
    4. key_right = keyboard_check(vk_right);
    5. key_left = -keyboard_check(vk_left);
    6. key_jump = keyboard_check_pressed(vk_space);
    7. //React to inputs
    8. move = key_left + key_right;
    9. if(hsp < move * movespeed) {
    10. hsp += acceleration;
    11. }
    12. if(hsp > move * movespeed) {
    13. hsp -= acceleration;
    14. }
    15. if (place_meeting(x,y+1,obj_wall))
    16. {
    17. vsp = key_jump * -jumpspeed
    18. }
    19. //Horizontal Collision
    20. if (place_meeting(x+hsp,y,obj_wall))
    21. {
    22. while(!place_meeting(x+sign(hsp),y,obj_wall))
    23. {
    24. x += sign(hsp);
    25. }
    26. hsp = 0;
    27. }
    28. x += hsp;
    29. // Wall Jump
    30. if((place_meeting(x + 1, y, obj_wall) ^ place_meeting(x - 1, y, obj_wall)) &! place_meeting(x, y + 1, obj_wall)) {
    31. // Die vertikale Speed setzen wir hier auf die normale Sprunghöhe.
    32. if(key_jump) {
    33. vsp = -jumpspeed;
    34. // Wenn der Spieler rechts eine Wand trifft (x + 1), dann setzen wir die horizontale Speed auf -movespeed * 2. Wenn er links eine
    35. // Wand trifft (x - 1) auf movespeed * 2, um ihn von der Wand abspringen zu lassen.
    36. hsp = place_meeting(x + 1, y, obj_wall) * -movespeed * 2 + place_meeting(x - 1, y, obj_wall) * movespeed * 2;
    37. }
    38. stick = true;
    39. }
    40. //Gravity
    41. if(stick) {
    42. // Wenn der Spieler an der Wand klebt, soll er langsamer fallen
    43. if (vsp < 4) vsp += grav / 2;
    44. else vsp = 4;
    45. } else {
    46. // Wenn der Spieler nicht an der Wand klebt, soll er normal fallen
    47. if (vsp < 10) vsp += grav;
    48. }
    49. //Vertical Collision
    50. if (place_meeting(x,y+vsp,obj_wall))
    51. {
    52. while(!place_meeting(x,y+sign(vsp),obj_wall))
    53. {
    54. y += sign(vsp);
    55. }
    56. vsp = 0;
    57. }
    58. y += vsp;
    Alles anzeigen


    Ich hatte noch einen kleinen Fehler in der Zeile:

    GML-Quellcode

    1. if((place_meeting(x + 1, y, obj_wall) ^ place_meeting(x - 1, y, obj_wall)) &! place_meeting(x, y + 1, obj_wall) && key_jump) {


    Denn stick sollte auch auf true gesetzt werden, wenn der Spieler nicht die Sprungtaste (key_jump) drückt (ja, ich sollte den Code ausprobieren bevor ich ihn poste :pinch: ). Ansonsten hat das ganze jetzt auch viel mit dem ausprobieren der Werte zu tun. Zum Beispiel solltest mal schauen ob du anstatt (-) movespeed * 2 in Zeile 45 im Step Event nicht noch einen besseren Wert findest. Dieser bestimmt wie arg der Spieler horizontal von der Wand abgestoßen wird.

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

  • Also mit dem Script "schmiert" er jetzt durchgehend nach links.

    :event_step: Step:
    Spoiler anzeigen

    GML-Quellcode

    1. //smooth the camera
    2. camera_movement();
    3. var stick;
    4. stick = false;
    5. //Get the player's input
    6. key_right = keyboard_check(vk_right);
    7. key_left = -keyboard_check(vk_left);
    8. key_jump = keyboard_check_pressed(vk_space);
    9. //React to inputs
    10. move = key_left + key_right;
    11. if(hsp < move * movespeed) {
    12. hsp += acceleration;
    13. }
    14. if(hsp > move * movespeed) {
    15. hsp -= acceleration;
    16. }
    17. if (place_meeting(x,y+1,obj_wall))
    18. {
    19. vsp = key_jump * -jumpspeed
    20. }
    21. // Wall Jump
    22. if((place_meeting(x + 1, y, obj_wall) ^ place_meeting(x - 1, y, obj_wall)) &! place_meeting(x, y + 1, obj_wall) && key_jump) {
    23. // Die vertikale Speed setzen wir hier auf die normale Sprunghöhe.
    24. if(key_jump) {
    25. vsp = -jumpspeed;
    26. // Wenn der Spieler rechts eine Wand trifft (x + 1), dann setzen wir die horizontale Speed auf -movespeed * 2. Wenn er links eine
    27. // Wand trifft (x - 1) auf movespeed * 2, um ihn von der Wand abspringen zu lassen.
    28. hsp = place_meeting(x + 1, y, obj_wall) * -movespeed * 2 + place_meeting(x - 1, y, obj_wall) * movespeed * 2;
    29. }
    30. stick = true;
    31. }
    32. //Gravity
    33. if(stick) {
    34. // Wenn der Spieler an der Wand klebt, soll er langsamer fallen
    35. if (vsp < 4) vsp += grav / 1.5;
    36. else vsp = 4;
    37. } else {
    38. // Wenn der Spieler nicht an der Wand klebt, soll er normal fallen
    39. if (vsp < 10) vsp += grav;
    40. }
    41. //Horizontal Collision
    42. if (place_meeting(x+hsp,y,obj_wall))
    43. {
    44. while(!place_meeting(x+sign(hsp),y,obj_wall))
    45. {
    46. x += sign(hsp);
    47. }
    48. hsp = 0;
    49. }
    50. x += hsp;
    51. //Vertical Collision
    52. if (place_meeting(x,y+vsp,obj_wall))
    53. {
    54. while(!place_meeting(x,y+sign(vsp),obj_wall))
    55. {
    56. y += sign(vsp);
    57. }
    58. vsp = 0;
    59. }
    60. y += vsp;
    Alles anzeigen

    Zudem denke ich, dass es besser wäre, dass der Spieler auf die Seite abspringt, in welche die Pfeiltaste gedrückt wird.
    Und er kann immernoch auf einer Wand hoch. Musst mal testen. Eigentlich passt fast alles, nur das von eben erwähnte und an sich finde ich die Steuerung recht schwer. Man kommt an einer Wand genauso schwer hoch wie wenn man von Wand zu Wand hoppt.
    Danke dir schon mal für die große Hilfe. Ich packe dich auf jeden Fall in die Credits! :)
  • Du hast die eine wichtige Zeile (bei dir 32) nicht geändert... :D

    Richtig muss es heißen:

    GML-Quellcode

    1. if((place_meeting(x + 1, y, obj_wall) ^ place_meeting(x - 1, y, obj_wall)) &! place_meeting(x, y + 1, obj_wall)) {


    Nicht:

    GML-Quellcode

    1. if((place_meeting(x + 1, y, obj_wall) ^ place_meeting(x - 1, y, obj_wall)) &! place_meeting(x, y + 1, obj_wall) && key_jump) {
  • Oops :D

    Ich muss mich auch nochmal korrigieren.
    Es ist, wenn man nach SuperMeatBoy geht, eigentlich ganz praktisch an einer Wand springen zu können.
    Hier eine nette SMB Engine. Leider keine GameMaker Datei.
    sandbox.yoyogames.com/games/184833-super-meat-boy-gm-mkii

    Aber da kann man sehr schön sehen wie ich das gerne umgesetzt hätte, was die Steuerung betrifft.
    Wir sind ja schon recht nah dran.

    Edit: Er rutscht immer noch nach links.

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

  • Lunatic447 schrieb:

    Oops :D

    Ich muss mich auch nochmal korrigieren.
    Es ist, wenn man nach SuperMeatBoy geht, eigentlich ganz praktisch an einer Wand springen zu können.
    Hier eine nette SMB Engine. Leider keine GameMaker Datei.
    sandbox.yoyogames.com/games/184833-super-meat-boy-gm-mkii

    Aber da kann man sehr schön sehen wie ich das gerne umgesetzt hätte, was die Steuerung betrifft.
    Wir sind ja schon recht nah dran.

    Edit: Er rutscht immer noch nach links.


    Du musst darauf achten das die acceleration durch die movespeed teilbar ist. Nimm als acceleration zum Beispiel einfach mal 0.5 oder 1, dann sollte er glaube ich nicht mehr einfach so "rutschen". Ich habe bei den Beispielwerten leider nicht darauf geachtet, hatte es selbst mit 1 getestet.
  • ghost schrieb:

    Du musst darauf achten das die acceleration durch die movespeed teilbar ist. Nimm als acceleration zum Beispiel einfach mal 0.5 oder 1, dann sollte er glaube ich nicht mehr einfach so "rutschen". Ich habe bei den Beispielwerten leider nicht darauf geachtet, hatte es selbst mit 1 getestet.


    Ok so geht es. Er rutscht nicht mehr.
    Jetzt fehlt mir aber noch die Möglichkeit die Sprungrichtung durch die Pfeiltasten zu bestimmen. Dann müsste es eigentlich alles passen.