Auf der unteren Plattform weiterlaufen

  • GM 8
  • Auf der unteren Plattform weiterlaufen

    Hallo Leute,

    folgendes Problem:



    Wenn mein Player auf einer Plattform läuft (untere Plattform) und dann mit dem Kopf eine andere Plattform berührt (obere plattform), dann bewegt er sich nach oben in richtung obere Plattform, bis er da oben draufsteht. Das soll er aber nicht, er soll die obere plattform ignorieren und auf der unteren weiterlaufen.

    Es liegt wohl am Collision Event mit der Plattform:

    set variable y to -speed
    Move to Contact with Plattform in Direction 270 maxiumum -1


    Kann mir einer helfen?

    Vielen Dank im Voraus!

    Gruß,
    Pascal

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

  • Kann mir denn keiner helfen...? :(

    Woran liegt´s? Versteht ihr das Problem nicht? Oder fällt euch auch keine Lösung ein?

    Hier ist die Datei, vielleicht hilft das ja:

    Jump N Run Template.gm81.zip



    Wär echt super wenn ihr mir helfen könntet, denn das ist echt wichtig für mein Spiel und ich komm leider nicht von selbst drauf...

    Vielen Dank im Voraus!

    Gruß,
    Pascal
  • Hi

    Ich kenne mich mit den D&D nicht sonderlich aus, sondern ich proge im GML
    Aber eins kann ich dir verraten was du machen kannst. Setze erste ein mal dein Origin unter die Füße, damit man wenn man mit dem GMl programmiert besser rechen kann. Von der Mitte aus
    ist es etwas schwerer, aber auch machbar.
    Jetzt zu deinen Problem, ich habe einfach mal deine Kolisionsmaske verkleiner auf left 14 / right 34 / top 20 / botton 42 aber nur auf den Laufsprite bezogen
    Es ist zwar nicht das gelbe vom Ei aber es wirkt.
    Ansonsten müsste man es programmieren an welcher stelle die Plattform den Sprite trifft und dann entsprechend handeln.
    Leider habe ich jetzt nicht so viel Zeit. Sonst könnte ich es mir mal ausdenken. Werde heute Abend nochmal reinschauen. Wenn dann du immer noch Probleme haben sollst, setzte ich mich mal ran
    und denke mir mal was aus in dieser Sache.

    Gruss Drachen :)
  • Hallo Drachen,

    vielen Dank erstmal dass Du Dir das mal angeguckt hast!

    Die Kollisionsmaske verkleinern hab ich auch schon ausprobiert. Zwar war das Problem dadurch gelöst, doch dann sind andere Probleme aufgetreten, z.B. ist der Player dann beim Springen in der Plattform steckengeblieben (warum auch immer?)... Ist also, wie Du schon richtig sagst, nicht das Gelbe vom Ei...

    Drachen schrieb:

    Ansonsten müsste man es programmieren an welcher stelle die Plattform den Sprite trifft und dann entsprechend handeln.

    Das hab ich mir auch schon überlegt, nur weiß ich leider nicht wie das geht. Hab es mit "check object" versucht, aber das hat leider nicht geklappt.
    Also wenn Du mir da was programmieren könntest wär das echt super! :D

    Vielen Dank im Voraus!

    Gruß,
    Pascal
  • Du deaktivierst einfach das Kollisionsverhalten für alle Plattformen, die sich oberhalb des Spielers befinden.
    Oder, andersrum: Du wertest die Kollision nur, wenn die untere Kante der Spielerfigur sich oberhalb der unteren Kante der Plattform befindet:

    Das Kollisionsevent mit der Wand aus der Sicht der Spielfigur:

    GML-Quellcode

    1. if (bbox_bottom <= other.bbox_bottom) {
    2. // Kollisionscode
    3. }

    Anmerkung: Die bbox_-Variablen geben die Positionen der Ränder der Kollisionsmaske im Raum an.

    Das setzt aber voraus, dass deine Wandobjekte sehr waagerecht sind. Sollten sie eine Linie oder gar eine Kurve beschreiben, müsstest du für jede dieser Wände other.bbox_top mit einer Funktion ersetzen, die einen y-Wert für den x-Wert der Spielfigur zurückliefert. Dabei solltest du dann aber auch festlegen, welches x der Spielfigur du dabei verwendest. Am besten ist vermutlich (bbox_left + bbox_right)/2, da dies dem Mittelpunkt der Kollisionsmaske entspricht.
  • Hi

    Entschuldige, gersten ging es länger als ich gedacht habe. Werde mich heute Abend mal dran setzen und was austüfteln. Die Idee von MewX ist nicht schlecht.
    Die versuche ich mal um zu setzten. Kann aber eine Weile daueren. Werde mich dann wieder hier Melden. Damit jeder was davon hat.

    Gruss Drachen :D
  • Drachen schrieb:

    Werde mich heute Abend mal dran setzen und was austüfteln. Die Idee von MewX ist nicht schlecht.

    Die versuche ich mal um zu setzten. Kann aber eine Weile daueren. Werde mich dann wieder hier Melden. Damit jeder was davon hat.


    Hallo Drachen,

    bevor Du anfängst etwas zu programmieren muss ich Dich noch auf was hinweisen, das ist glaub ich wichtig. Und zwar sollten sich alle Plattformen eines Levels später in nur EINEM Sprite und somit in nur einem Objekt befinden. Das ist in dem Template welches ich hochgeladen noch nicht der Fall. Ich werde das Template morgen dementsprechend ändern und es dann wieder hier hochladen. Dann kannst Du dich ans Werk machen ;)

    MewX schrieb:

    Du deaktivierst einfach das Kollisionsverhalten für alle Plattformen, die sich oberhalb des Spielers befinden.
    Oder, andersrum: Du wertest die Kollision nur, wenn die untere Kante der Spielerfigur sich oberhalb der unteren Kante der Plattform befindet:

    Das Kollisionsevent mit der Wand aus der Sicht der Spielfigur:

    GML-Quellcode

    1. if (bbox_bottom <= other.bbox_bottom) {
    2. // Kollisionscode
    3. }

    Anmerkung: Die bbox_-Variablen geben die Positionen der Ränder der Kollisionsmaske im Raum an.

    Das setzt aber voraus, dass deine Wandobjekte sehr waagerecht sind. Sollten sie eine Linie oder gar eine Kurve beschreiben, müsstest du für jede dieser Wände other.bbox_top mit einer Funktion ersetzen, die einen y-Wert für den x-Wert der Spielfigur zurückliefert. Dabei solltest du dann aber auch festlegen, welches x der Spielfigur du dabei verwendest. Am besten ist vermutlich (bbox_left + bbox_right)/2, da dies dem Mittelpunkt der Kollisionsmaske entspricht.
    @MewX

    Danke für Deinen Lösungsvorschlag. Ich konnte ihn noch nicht ausprobieren da ich dieses Wochenende nicht zu Hause bin. Aber wie schon gesagt sollten sich alle Plattformen eines Levels später in nur EINEM Sprite und somit in nur einem Objekt befinden. Ich bin mir nicht sicher ob Deine Lösung dann immernoch funktioniert. Werde es morgen mal ausprobieren und meld mich dann nochmal.


    Bis dann,

    Gruß,
    Pascal
  • Pascal2851981 schrieb:

    Aber wie schon gesagt sollten sich alle Plattformen eines Levels später in nur EINEM Sprite und somit in nur einem Objekt befinden. Ich bin mir nicht sicher ob Deine Lösung dann immernoch funktioniert. Werde es morgen mal ausprobieren und meld mich dann nochmal.

    Das mag zwar einfach erscheinen, wird dich aber innerhalb des Game Makers in Teufels Küche bringen. Ich sehe innerhalb des Game Makers keine halbwegs effiziente Methode, pixelgenaue Abfragen auf die Sprites zu starten bzw. sich gegebener Funktionen zu bedienen, um dieses Problem zu lösen.

    Du könntest ansonsten versuchen, Rückschlüsse aus der vorherigen Position der Spielfigur (oder deren speed/direction) Rückschlüsse zu ziehen - ist die Kollision zustande gekommen, wenn sich die Figur nach oben bewegt hat, ignorierst du sie. Damit stößt du aber später vermutlich auf ganz andere Probleme. Probieren kannst du es aber. Einfach meinen Code von oben nehmen und die if-Abfrage durch ein (vspeed > 0) austauschen.
  • Hier ist das Template, in dem alle Plattformen in einem Sprite sind:

    Jump N Run Template.gm81.1.zip

    MewX schrieb:

    Du könntest ansonsten versuchen, Rückschlüsse aus der vorherigen Position der Spielfigur (oder deren speed/direction) Rückschlüsse zu ziehen - ist die Kollision zustande gekommen, wenn sich die Figur nach oben bewegt hat, ignorierst du sie. Damit stößt du aber später vermutlich auf ganz andere Probleme. Probieren kannst du es aber. Einfach meinen Code von oben nehmen und die if-Abfrage durch ein (vspeed > 0) austauschen.

    Das funktioniert leider nicht... :(
  • Doch, funktioniert wohl. Das Problem ist leider, dass man beim Abwärtslaufen mit dem Kopf in die andere Plattform läuft. Folglich musst du ein paar Änderungen vornehmen:

    1. Mach einen Sprite, der als Maske fürs Laufen dient. Dieser ist nur ~8 Pixel hoch und befindet sich an den Füßen deiner Figur. Nimm einfach deine bestehende Maske als Vorbild und zeichne einen Sprite (einfaches Schwarz reicht). Setze bei den Spielerobjekten die Maske auf diesen Sprite. Nun passt dein Spieler auch durch enge Passagen durch.

    2. Damit du nach wie vor von Gegnern getroffen werden kannst, machst du ein zweites, unsichtbares Spielerobjekt, das die Maske deiner bisherigen Sprites hat. Dieses hat dann auch die Kollisionsevents zu Projektilen (und auch Decken. Das wird evtl. aber noch problematisch).


    Wie du was genau trennst und wo du welchen Code auslagerst, musst du gucken. Es ist aber aus GM-Sicht vollkommen in Ordnung, für jede Art von Interaktion ein eigenes Objekt mit einer eigenen Maske zu haben.
  • MewX schrieb:

    1. Mach einen Sprite, der als Maske fürs Laufen dient. Dieser ist nur ~8 Pixel hoch und befindet sich an den Füßen deiner Figur. Nimm einfach deine bestehende Maske als Vorbild und zeichne einen Sprite (einfaches Schwarz reicht). Setze bei den Spielerobjekten die Maske auf diesen Sprite. Nun passt dein Spieler auch durch enge Passagen durch.
    Ok ich verstehe was das bringen soll, aber wieso muss ich dafür eine Maske anlegen? Kann ich nicht einfach die Collision Mask des Sprites ändern? Oder gibt es da einen Unterschied?

    MewX schrieb:

    2. Damit du nach wie vor von Gegnern getroffen werden kannst, machst du ein zweites, unsichtbares Spielerobjekt, das die Maske deiner bisherigen Sprites hat. Dieses hat dann auch die Kollisionsevents zu Projektilen (und auch Decken. Das wird evtl. aber noch problematisch)
    Was meinst Du mit "unsichtbares Spielerobjekt"? Und wo/wie soll ich das einsetzen?
  • Du steckst in einem einfachen Dilemma:
    Für die Kollisionen mit dem Boden reicht ein recht flacher Block. Wenn du diese Maske aber für alle Kollisonen verwendest, wird deine Figur z.B. nicht mehr am Kopf verwundbar sein. Du musst also irgendwie zwischen verschiedenen Kollisionsmasken unterscheiden. Da der Game Maker aber einfach nur sagt "da ist eine Kollision" und nicht genau, wo diese sich befindet, kannst du bei exakten Kollisionen (wie deinen Bahnkurven) ohne Weiteres keine sinnvollen Rückschlüsse aus den Positionen der Beteiligten ziehen.

    Stattdessen legst du für jede Kategorie von Kollision ein eigenes Spielerobjekt an. Von denen sind alle bis auf eines unsichtbar (man soll ja nur eine Spielfigur sehen können). All diese Hilfsobjekte orientieren sich am "Masterobjekt". Erstelle die Hilfsobjekte zeitlich nach dem Masterobjekt (also z.B. in dessen Create-Event), damit deren Stepevents nach dem des Masterobjekts ausgeführt werden. In den Step-Events setzt du dann die Hilfsobjekte auf die Position des Masterobjekts. Weise jedem Hilfsobjekt eine entsprechende Maske und die zugehörigen Kollisionsevents zu. In den Kollisionsevents änderst du dann von den Hilfsobjekten aus direkt das Masterobjekt (und setzt es z.B. auf "durch Gegner getroffen").

    Die Schwierigkeit bei einem solchen System ist natürlich, dass verschiedene Kollisionsevents "gegeneinander" arbeiten können. Das solltest du vermeiden. Also ein Schuss, der dich nach hinten wegdrückt, darf dich nicht in eine Wand befördern, denn das würde im anderen Kollisionsevent unter Umständen nicht mehr berücksichtigt werden. Falls du dennoch in so eine Situation kommen solltest, kannst du solche Fehler im End-Step-Event ausbügeln, welches nach den Kollisionen, aber vor den Draw-Events ausgeführt wird.

    Ja, das ist alles etwas kompliziert und die Kollisionen im Game Maker habe ich selbst bis heute nicht ganz durchschaut, aber solange du nicht deine eigene Kollisionsengine schreiben willst, ist das wohl der einfachste Weg. ich empfehle dir aber auch, alle deine bisherigen Spielerobjekte zusammenzulegen und auf GML umzusteigen. Du kannst die Unterscheidung zwischen laufend und fallend auch in einer weiteren Zustandsvariable festhalten.


    Edit: Ich habe meinen Post ein bisschen lesbarer gemacht.
  • Hi

    Also ich habe es mal so gemacht, wie es MewX gesagt hat. Ich habe mal ein extra Objekt gemacht das die Kollisionsabfrage für die Plattforme übernehmen soll.
    Jetzt ist aber bei dir das Problem das du alles in D&D gemacht hast. Und ist es für mich schwer dazwischen was rein zu setzen.
    Wenn du etwas Geduld mit bringst, Versuche ich alles was mit dem Laufen zu tun hat im GML umzuschreiben. Aber das Dauert ein Wenig.
    Also lass den Kopf nicht hängen, das kriegen wir schon hin.

    Gruss Drachen :)
  • So Pascal2851981

    Habe es fertig.
    Muss aber gleich sagen das ich an deinen Code so gut wie nichts geändert. Habe es wirklich vor gehabt, aber das ist so verschachtelt, das ich die Finger weg gelassen habe.
    Da du ja noch weiter programmieren willst, ist es besser wenn du das jetzt so fertig machst mit D&D.
    Um es um zu schreiben, müsste man von ganz vorne anfangen. Und da nicht weis wie weit du im GML bist, habe ich es so gelassen. Habe nur zwei Sachen geändert.
    So nun verrate ich dir was ich geändert habe.
    Ich habe ein neuer Sprite gemacht mit den Namen "spr_mask_zool_fuss"
    und dieser Sprite habe ich dann in obj_player_land ein gesetzt. Ja und das war es dann auch schon.
    Das ging deswegen bei dir so einfach, weil bei dir im Programm die Sprites gedrawt werden.
    Das war dein Glück. Das habe ich aber erst festgestellt als ich mir deinen Code genauer angeschaut habe. :D

    So jetzt wünsche ich dir noch viel Spass mit deinen Spiel. Bin gespannt wie es ist wenn es fertig ist. Da ich die Figur Zool kenne, entweder aus einen PC-Spiel oder einer Konsole. Weis es leider nicht mehr, zu lange her.

    Hier die geänderte Datei:
    Jump N Run Template - neu.zip

    Wenn du noch Probleme bekommen sollst, gib Bescheid.
    Kannst du mir dann noch mitteilen ob so für dich in Ordnung ist

    Gruss Drachen
  • Drachen schrieb:

    So Pascal2851981

    Habe es fertig.
    Muss aber gleich sagen das ich an deinen Code so gut wie nichts geändert. Habe es wirklich vor gehabt, aber das ist so verschachtelt, das ich die Finger weg gelassen habe.
    Da du ja noch weiter programmieren willst, ist es besser wenn du das jetzt so fertig machst mit D&D.
    Um es um zu schreiben, müsste man von ganz vorne anfangen. Und da nicht weis wie weit du im GML bist, habe ich es so gelassen. Habe nur zwei Sachen geändert.
    So nun verrate ich dir was ich geändert habe.
    Ich habe ein neuer Sprite gemacht mit den Namen "spr_mask_zool_fuss"
    und dieser Sprite habe ich dann in obj_player_land ein gesetzt. Ja und das war es dann auch schon.
    Das ging deswegen bei dir so einfach, weil bei dir im Programm die Sprites gedrawt werden.
    Das war dein Glück. Das habe ich aber erst festgestellt als ich mir deinen Code genauer angeschaut habe.

    So jetzt wünsche ich dir noch viel Spass mit deinen Spiel. Bin gespannt wie es ist wenn es fertig ist. Da ich die Figur Zool kenne, entweder aus einen PC-Spiel oder einer Konsole. Weis es leider nicht mehr, zu lange her.

    Hier die geänderte Datei:
    Jump N Run Template - neu.zip

    Wenn du noch Probleme bekommen sollst, gib Bescheid.
    Kannst du mir dann noch mitteilen ob so für dich in Ordnung ist

    Gruss Drachen
    Vielen Dank Drachen!

    Ja das funktioniert. Aber hätte ich nicht genauso gut die Collision Mask des Players ändern können? Oder gibt es da einen Unterschied?




    Ich habe noch eine ander Möglichkeit ausprobiert. Und zwar hab ich mich mal in GML versucht. Das ganze steht im Collision Event mit der Plattform obj_rund_plattform:

    GML-Quellcode

    1. {if collision_rectangle(x-5,y+18,x+5,y+28,obj_rund_plattform,true,false){y=-speed;move_contact_all(270,-1)}}



    Ich zeichne also ein Rechteck unter dem Player (der Nullpunkt liegt in der Mitte des Players, daher beginnt das Rechteck bei y+18 ). y=-speed soll also nur gelten, wenn die Plattform mit diesem Rechteck in Berührung kommt. Dadurch sollte er die Plattform über ihm doch eigentlich ignorieren.

    Das funktioniert aber leider nicht! Er bewegt sich immernoch in Richtung obere Plattform! Kann mir einer sagen woran das liegt? Hab ich was falsch geschrieben? Und wie schreibe ich es so, das move to contact nur für obj_rund_plattform gilt?

    Wäre echt super wenn mir das einer erklären kann, sind wie gesagt meine ersten Gehversuche in GML...

    Vielen Dank im Voraus!

    Gruß,
    Pascal

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

  • Hi Pascal2851981

    Zur Collision-Mask.
    Wenn man jetzt die Collisions-Mask verändert, bekommst du Probleme mit den anderen Gegenstände die du berühren willst die über den Boden sind. Die würden dann nicht wahrgenommen.
    Deswegen ein extra Objekt die das dann separat übernimmt mit der Berührung des Bodens.

    Also mit der collision_rectangle habe ich nur selten gearbeitet, deswegen kann darüber nichts sagen.
    Aber ich habe hier Tutorial eines Sonic-Spiel. Da geht es hauptsächlich über die Abfrage des Untergrundes. Der Programmierer hat hier einige Script geschrieben über die Collision des Untergrundes.
    Schau es dir einfach mal an. Vielleicht willst du dann dein Spiel im diesen Sinne umprogrammieren. Ist aber viel Arbeit, weil du wieder von ganz vorne anfangen musst.

    Im diesen Sinne alles Gute.
    Freue mich wenn du dein Spiel hier veröffentlichst.

    Hier die Datei
    GM Sonic Test.gm81.zip

    Hoffe bei dir läuft es ohne Probleme, so wie ich sehe besitzt du nur eine Lite-Version vom Game Maker.

    Gruss Drachen
  • Drachen schrieb:

    Zur Collision-Mask.
    Wenn man jetzt die Collisions-Mask verändert, bekommst du Probleme mit den anderen Gegenstände die du berühren willst die über den Boden sind. Die würden dann nicht wahrgenommen.
    Deswegen ein extra Objekt die das dann separat übernimmt mit der Berührung des Bodens.
    Aber mit diesem extra Objekt berührt er Gegenstände über dem Boden doch auch nicht. Ich glaube nicht dass es einen Unterschied macht ob ich die Collisions-Mask ändere oder ein extra Sprite dafür anlege. Hast Du das mal in dem Template ausprobiert welches Du für mich gemacht hast?

    Das Sonic Spiel werde ich mir mal anschauen, Dankeschön!
  • Ich habe collision_rectangle tatsächlich komplett außer Acht gelassen. Entsprechend haben meine Aussagen weiter oben nur bedingt Bestand.

    Du hast mit collision_rectangle zwei Möglichkeiten:
    Entweder, du behälst die größte Kollisionsmaske für den Spieler und machst mit collision_rectangle die nachträglichen Einschränkungen, oder du lagerst einen Teil ins Step- oder End-Step-Event aus. Letzteres lassen wir jetzt mal sein, auch wenn es wohlmöglich effizienter wäre.

    Die erste Möglichkeit bringt uns wieder zu dem Modell aus meinen ersten Antworten zurück (aus dem Kollisionsevent der Spielfigur mit der Wand):

    GML-Quellcode

    1. if (bbox_bottom <= other.bbox_bottom) {
    2. // Kollisionscode
    3. }

    Dies können wir korrigieren zu:

    GML-Quellcode

    1. if (collision_rectangle(bbox_left, bbox_bottom-8, bbox_right, bbox_bottom, other.object_index, true, true)) {
    2. // Kollisionscode
    3. }

    Ich habe das jetzt einfach so aus dem Kopf geschrieben, aber eigentlich sollte das funktionieren. Wichtig ist, dass das prec-Parameter auf true gesetzt ist.
  • Benutzer online 1

    1 Besucher