MewX schrieb:
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):
Dies können wir korrigieren zu:
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.
Auf der unteren Plattform weiterlaufen
- GM 8
Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen
-
-
Ich weiß nicht, ob collision_rectangle auch Instanzen akzeptiert... probier also mal statt other.object_index nur other.
-
MewX schrieb:
Ich weiß nicht, ob collision_rectangle auch Instanzen akzeptiert... probier also mal statt other.object_index nur other.
In der Game Maker Hilfe steht das collision_rectangle die instance id wiedergibt wenn die collision zustande kommt und einen negativen Wert wenn sie nicht zustande kommt.
Muss ich dann nicht abfragen ob collision_rectangle(...)>0 ist?
Und woran liegts eigentlich dass er sich nach oben bewegt?
an
y=-speed
oder an
move_to_contact? -
Aaah, okay. Jetzt weiß ich auch wieder, warum ich die Funktion nicht so gerne mag.
Die einfache Methode: if (collision_rec..(...) == other).
Falls das nicht reicht, müsste man dies in eine Schleife packen. Ist die wiedergegebene Instanz nicht "other", wird diese deaktiviert und in einer Liste gespeichert. Nachdem die andere Instanz dann gefunden wurde oder keine Kollision mehr zustande kommt, werden wieder alle deaktivierten aus der Liste aktiviert. -
MewX schrieb:
Die einfache Methode: if (collision_rec..(...) == other).MewX schrieb:
Falls das nicht reicht, müsste man dies in eine Schleife packen. Ist die wiedergegebene Instanz nicht "other", wird diese deaktiviert und in einer Liste gespeichert. Nachdem die andere Instanz dann gefunden wurde oder keine Kollision mehr zustande kommt, werden wieder alle deaktivierten aus der Liste aktiviert.
Kann ich nicht statt "other.object_instanz" den Namen der Plattform angeben und ">0" abfragen? -
Letzteres wird nicht funktionieren, sofern meine Vermutung stimmt. Meine Vermutung ist, dass sich die Spielfigur im Step-Event bereits in den Boden "reingräbt" (das ist nicht unbedingt schlimm, das ist nur eine nüchterne Feststellung). Wenn nun aber zuerst das Kollisionsevent der oberen Plattform ausgeführt wird, dann gibt die Abfrage unter Umständen die Instanz des Bodens zurück => Deine Unterscheidung funktioniert wieder nicht.
Ich muss leider gleich weg, aber jemand anders sollte in der Lage sein, die Schleife mit meiner Anleitung oben zu schreiben. -
Ja das wär echt super wenn mir jemand so eine Schleife bauen könnte!
-
Hi Pascal
Ich schau auch noch einmal nach.
Gruss Drachen -
MewX schrieb:
Wenn nun aber zuerst das Kollisionsevent der oberen Plattform ausgeführt wird, dann gibt die Abfrage unter Umständen die Instanz des Bodens zurück => Deine Unterscheidung funktioniert wieder nicht.
Ich verstehe einfach nicht warum der Player immernoch eine Collision mit der oberen Plattform berücksichtigt, obwohl ich dies mit einer collision_rectangle Abfrage unter den Füßen des Players eigentlich ausgeschlossen habe?!
Das steht im collision event des Players mit der Plattform:
{
if (collision_rectangle(x-5,y+18,x+5,y+22,obj_rund_plattform,true,true)>0)
{
y+=-speed;
script_execute(move_to_contact_with,270,-1,obj_rund_plattform)
}
}
Warum führt er y+=-speed immernoch aus wenn er die obere Plattform berührt, obwohl das Rechteck (collision_rectangle) die obere Plattform garnicht berührt?!
Hier ist nochmal die Datei, vielleicht kann sich das ja nochmal jemand ansehen?
Jump N Run Template - platform problem.gm81.zipDieser Beitrag wurde bereits 7 mal editiert, zuletzt von Pascal2851981 ()
-
Hi Pascal
Das liegt einfach daran, weil der Game Maker immer noch die Mask vom Sprite als erstes abfragt und dann die collision_rectangle - Funktion.
Also wenn du jetzt deine Mask auf left = 14, right = 30, top = 29, botton = 42, bei den Laufsprites einstellst , hast du dein Problem gelöst.
Pascal wenn du keine registrierte Version vom Gamer Maker besitzt, konnte die Befehlsfolge von MewX nichts bewirken, weil das nur bei der registrierte Version geht.
if (collision_rectangle(bbox_left, bbox_bottom-8, bbox_right, bbox_bottom, other.object_index, true, true)>0) {// Kollisionscode
}
Gruss Drachen -
Hallo Drachen, danke für Deine Antwort!
Drachen schrieb:
Das liegt einfach daran, weil der Game Maker immer noch die Mask vom Sprite als erstes abfragt und dann die collision_rectangle - Funktion.
{
if (collision_rectangle(x-5,y+18,x+5,y+22,obj_rund_plattform,true,true)>0)
{
y+=-speed;
script_execute(move_to_contact_with,270,-1,obj_rund_plattform)
}
}
Drachen schrieb:
Also wenn du jetzt deine Mask auf left = 14, right = 30, top = 29, botton = 42, bei den Laufsprites einstellst , hast du dein Problem gelöst.
Drachen schrieb:
Pascal wenn du keine registrierte Version vom Gamer Maker besitzt, konnte die Befehlsfolge von MewX nichts bewirken, weil das nur bei der registrierte Version geht.
Zitat
if (collision_rectangle(bbox_left, bbox_bottom-8, bbox_right, bbox_bottom, other.object_index, true, true)>0) {// Kollisionscode
}
Und wenn du doch eine registrierte Version besitzen sollst, dann mach es erkenntlich. Weil in dein Profil Game Maker light steht, und das deutet darauf hin das du keine registrierte Version hast.
Funktionieren tut es trotzdem nicht! -
So, ich habe mir dein Spiel jetzt mal etwas ausführlicher angeschaut. Deine Engine ist eine Katastrophe. Ohne da ordentlich aufzuräumen, wirst du dieses Problem nie lösen, ohne nicht an anderer Stelle sofort ein neues zu erzeugen. Ich rate dir daher dringend, dich nochmal im stillen Kämmerlein einzuschließen und das von Grundauf neu hochzuziehen. Zwischenzeitlich solltest du natürlich immer gucken, ob du dich auf dem richtigem Weg befindest und nachfragen.
Ich handle das mal stichpunktartig ab:
- Deine Engine braucht eine Logik, die den Rahmen von D&D sprengt. Steig auf GML um.
- Benutze der Übersicht wegen nur noch "Execute a script" und weder D&D noch "Execute a piece of code". Nenne diese Scripts dann z.B. "obj_player_end_step" oder so. Ohne einen schnellen Zugriff verliert man schnell die Übersicht.
- Du benutzt oft speed, wenn du eigentlich hspeed oder vspeed meinst. Mach dir bitte klar, wo dort die Unterschiede liegen.
- Du hast eine Funktion, die das "am Boden haften bleiben" regelt. Die rufst du allerdings mal hier, mal da auf (Kollisionsevents, End-Step-Event...). Mach dir Gedanken, wie man diese Bodenhaftung zentral an einer Stelle lösen kann.
- Du hast willkürlich zwischen "Air" und "Land" getrennt, handelst aber viele andere Sachen intern mit Zustandsvariablen ab. Vereinige die beiden Spielerobjekte am besten zu einem. Das erspart Ärger durch Parents und doppelte Events.
- Mach dir bewusst, was die Trennungen zwischen Begin-, Normal- und End-Step-Event im Detail bedeuten (siehe "Order of Events" in der Hilfe).
- Schreibe dir Code, der optional die Maske der Spielifgur am Ende des Draw-Events zeichnet (als Rechteck). Sowas hilft ungemein.
- Trenne Masken von Sprites. Der Game Maker bietet dir zwar dieses tolle Maskenfeature an, aber bei vielen Sprites passieren schnell Fehler und Korrekturen dauern lange. Mach einfach einen Sprite, der nur einen schwarzen Kasten beinhaltet und verwende ihn als Maske. Dann kannst du auch einfach den zeichnen lassen anstelle des Rechtecks, das ich oben vorgeschlagen habe.
- Es spricht zwar von der Spiellogik her nicht soviel dagegen, den ganzen Level in einen Sprite zu packen, allerdings wird dein Spiel dadurch sehr groß werden. Überleg dir lieber, ob sich das nicht sinnvoll trennen lässt.
Die zentralen Fragen bei so einer Engine sind erstmal "Wie bleibe ich auf dem Boden?", "Wann fange ich an zu fallen?" und "Wie verhalte ich mich bei Kollisionen?". Die Antwort von einer Frage beeinflusst schon die der anderen. Du kannst z.B. sagen, dass man immer fällt - und dafür halt in jedem Step auch wieder aus der Plattform rausgedrückt wird. Spiele verschiedene Szenarien durch, bis du glaubst, alles so einfach, zentral und funktional wie nur möglich zu haben.
Was ich von dir hier fordere ist nicht wenig, aber Jump'n'Runs gehören zu den schwersten Einsteigerprojekten überhaupt. Mach dir keinen Kopf, dass es auf Anhieb nicht geklappt hat. Es gibt hier genug Leute, die dir an vielen Stellen wieder weiterhelfen können. Jetzt ist es aber meiner Meinung nach Zeit, dass du nochmal ein bisschen zurückruderst. Denn selbst wenn du dieses Problem jetzt IRGENDWIE lösen solltest, wird das nächste Problem noch schlimmer. - Deine Engine braucht eine Logik, die den Rahmen von D&D sprengt. Steig auf GML um.
-
Hi MewX,
erstmal vielen Dank dass Du Dir die Mühe gemacht hast mein Spiel durchzuschauen und auch noch so ausführlich zu kommentieren!
MewX schrieb:
Deine Engine braucht eine Logik, die den Rahmen von D&D sprengt. Steig auf GML um.
MewX schrieb:
Mach dir bewusst, was die Trennungen zwischen Begin-, Normal- und End-Step-Event im Detail bedeuten (siehe "Order of Events" in der Hilfe).
MewX schrieb:
Schreibe dir Code, der optional die Maske der Spielifgur am Ende des Draw-Events zeichnet (als Rechteck). Sowas hilft ungemein.MewX schrieb:
Trenne Masken von Sprites. Der Game Maker bietet dir zwar dieses tolle Maskenfeature an, aber bei vielen Sprites passieren schnell Fehler und Korrekturen dauern lange. Mach einfach einen Sprite, der nur einen schwarzen Kasten beinhaltet und verwende ihn als Maske. Dann kannst du auch einfach den zeichnen lassen anstelle des Rechtecks, das ich oben vorgeschlagen habe.MewX schrieb:
Es spricht zwar von der Spiellogik her nicht soviel dagegen, den ganzen Level in einen Sprite zu packen, allerdings wird dein Spiel dadurch sehr groß werden. Überleg dir lieber, ob sich das nicht sinnvoll trennen lässt.MewX schrieb:
Du benutzt oft speed, wenn du eigentlich hspeed oder vspeed meinst. Mach dir bitte klar, wo dort die Unterschiede liegen.
Du hast eine Funktion, die das "am Boden haften bleiben" regelt. Die rufst du allerdings mal hier, mal da auf (Kollisionsevents, End-Step-Event...). Mach dir Gedanken, wie man diese Bodenhaftung zentral an einer Stelle lösen kann.
Du hast willkürlich zwischen "Air" und "Land" getrennt, handelst aber viele andere Sachen intern mit Zustandsvariablen ab. Vereinige die beiden Spielerobjekte am besten zu einem. Das erspart Ärger durch Parents und doppelte Events.
MewX schrieb:
Benutze der Übersicht wegen nur noch "Execute a script" und weder D&D noch "Execute a piece of code". Nenne diese Scripts dann z.B. "obj_player_end_step" oder so. Ohne einen schnellen Zugriff verliert man schnell die Übersicht.
Ok, dann mach ich mich mal ans Werk *Ärmelhochkrempel*
Hoffe das Problem wird dann dadurch gelöst.
nochmals vielen Dank für Deine Hilfe!
Gruß,
PascalDieser Beitrag wurde bereits 1 mal editiert, zuletzt von Pascal2851981 ()
-
Pascal2851981 schrieb:
Ok, werde ich tun! Gibt es irgendwo eine Liste wo alle GML Funktionen und Variablen drin sind? Das würd mir glaub ich helfen.
Pascal2851981 schrieb:
Was genau bringt [es, die Maske zu zeichnen]?
Pascal2851981 schrieb:
Ich sehe derzeit keine Alternative dazu. Das hängt mit der Art und Weise zusammen wie ich später die Levels erstelle. Das "obj_rund_plattform" dient nur dazu einen Boden zu erzeugen, es ist später unsichtbar. Darunter kommt dann noch die Spielgrafik (ebenfalls in einem Sprite...)
Pascal2851981 schrieb:
Das habe ich alles aus dem Tutorial "Zool" aus dem Buch "Game Maker´s Companion". Dort gab es sogar 6 oder 7 verschiedene Spielerobjekte. Daher wundert es mich jetzt ein wenig dass das falsch ist. Aber ich glaub dir mal und werd es ändern ;)
Ansonsten gilt für so eine doch sehr zustandsorientierte Programmierung aus Amateursicht (der Profi würde das im Vorfeld genau durchplanen): Halte deine Hierarchien halbwegs flach. Lagere doppelten Code, der sich trotz Hierarchie nicht vermeiden lässt, in Scripts aus. Vermeide unter allen Umständen Code, der bereits ausgeführten Code wieder rückgängig macht. Ordne in letzterem Fall lieber die Hierarchie neu.
Es braucht viel Übung und Erfahrung, bis du für so eine Hierarchie das richtige Gefühl hast.
Pascal2851981 schrieb:
Ich denke für mich persönlich ist es mit "Execute a code" übersichtlicher. Das ist aber nur Geschmackssache, oder wo genau liegen die Unterschiede?