mündungsfeuer soll dem spieler folgen

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

  • mündungsfeuer soll dem spieler folgen

    Hallo liebe gm-d Community, mein erster Post hurray.

    Ich (Anfänger) versuche mich gerade an einem 2d Shooter/Platformer und bin gerade dabei dem Spieler ein Mündungsfeuer zu implementieren und habe dafür 2 Vorstellungen zur Umsetzung, jedoch weiß ich weder für die eine noch für die andere eine Lösung.



    Ansatz1(der bessere): Die beste Lösung wäre die, dass die Animation vom Mündungsfeuer dem Spieler folgt. Aktuell erstelle ich die Animation ja genau an einem Punkt und dort läuft sie dann einmal kurz ab. Das sieht aber blöd aus, zumindest wenn man sich bewegt, wie man sich denken kann und auch auf dem Bild oben zu sehen ist.

    Ansatz2(notlösung, aber auch interessant zu wissen für mich): Pro Schuß immer nur ein zufälliges Frame der Animation kurz zu zeigen. Aber ich kann nichts finden in der Game Maker Dokumentation, wie man mit der instance_create Funktion halt nur ein bestimmtes Frame der Animation spielt.

    Mein aktuelles Skript dafür:

    Spoiler anzeigen

    Quellcode

    1. //Shooting
    2. if (canshoot) = true
    3. if keyboard_check(ord("D")) || (gamepad_button_check(0,gp_face3))
    4. {
    5. canshoot = false;
    6. alarm[1] = 12;
    7. if image_xscale = 1
    8. {
    9. with (instance_create(x+20,y-2,obj_muzzlefire_right)) {image_speed = 0.3};
    10. alarm[2] = 8;
    11. thing = instance_create(x+16,y-2,obj_lasershot_lev1_right);
    12. thing.vspeed = 8;
    13. thing.direction = 0;
    14. }
    15. else
    16. {
    17. with (instance_create(x-20,y-2,obj_muzzlefire_left)) {image_speed = 0.3};
    18. alarm[2] = 8;
    19. thing = instance_create(x-16,y-2,obj_lasershot_lev1_left);
    20. thing.vspeed = 8;
    21. thing.direction = 180;
    22. }
    23. }
    Alles anzeigen


    Wäre toll wenn ihr ein paar Lösungsansätze parat hättet.

    Vielen Dank schonmal im voraus.

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

  • Da das Mündungsfeuer "nachhinkt" gehe ich davon aus, dass es eine Animation ist und somit mehrere images hat.

    Wenn es wirklich so ist, gehen wir einfach mal davon aus, es sind 5 images in der Mündungsanimation und lösen es wie folgt:

    Wenn Spieler schießt:

    GML-Quellcode

    1. animation = 0


    Im Draw:

    GML-Quellcode

    1. if animation != -1
    2. {
    3. if side = "left"
    4. {
    5. draw_sprite_ext( spr_fireanimation, animation, x-16, y-2, 1, 1, 0, -1, 1)
    6. }
    7. if side = "right"
    8. {
    9. draw_sprite_ext( spr_fireanimation, animation, x+16, y-2, -1, 1, 0, -1, 1) // ich lasse hier einfach das Sprite mit xscale -1 gespiegelt zeichnen, dann benötigt man keine extra animation
    10. }
    11. animation += 0.5 // je nachdem wie schnell die Animation laufen soll
    12. }
    13. if animation >= 4 // Wieviele images du hast
    14. {
    15. animation = -1
    16. }
    Alles anzeigen



    Eventuell musst du mit den Werten noch etwas rumspielen, wie lange die Animation dauern soll, wo sie genau gezeichnet werden soll etc.
    Ist alles frei aus dem Kopf aber sollte mit etwas Anpassung funktionieren :)
    Husi012 hat mich nicht mehr in seiner Signatur, ich bin trotzdem noch fame.
  • Ok, wo fange ich an. Zuerst einmal es klappt so nicht, dass liegt aber sicher an meiner Implementierung und nicht am Code, denn den habe ich einbauen können ohne Fehlermeldungen zu bekommen.
    Allerdings passiert dabei nichts.
    Nach weiterer Recherche habe ich gelesen das die DRAW Funktionen nur in einem "Draw Event" funktioniert. Und da ich das ganze in mein Stepevent eingebaut habe, kann es wohl nicht funktionieren.
    Nun habe ich zum testen mal in dem Objekt muzzlefire das Draw Event eingebaut und es hat auch geklappt ohne Fehlermeldung. Allerdings sehe ich kein Sprite.

    Mir platzt grad n bisserl der Schädel, gehe pennen und werde morgen nochmal konzentriert an die Sache rangehen.
  • Am besten wäre es wenn du das Mündungsfeuer nicht als einzelnes Objekt erstellst, sondern im "Draw Event" des Spielers malst. dazu musst du draw_self() hinzufügen da sonst dein Spieler nicht mehr gemalt wird, sofern du dies noch nicht zuvor rausgefunden hast. Um die Animation zui positionieren würde ich mit den lengthdir funktionen arbeiten (lengthdir_x(),lengthdir_y()). Dann malst du an x + lenx und y + leny. hoffe das hilft als erster Anreiz
    132 little bugs in the code. 132 little bugs. Fix a few, set the compiler to stew, 172 little bugs in the code... :vogel:
  • Hallo und guten Morgen ihr zwei, mit eurer Hilfe konnte ich das Problem nun heute bewältigen.

    Ja Rhazul, das ich den Spieler nicht mehr sehen kann, als ich mit dem Draw Event rumprobiert habe, ist mir natürlich auch passiert. Auch habe ich es geschafft das der Spieler nur dann sichtbar war wenn man geschossen hat, aber gut da war das draw_self nur unlogisch plaziert.

    Aber gut, dank eurer Hilfe funktioniert es nun soweit und für andere die es auch interessiert lege ich hier den funktionierenden Code nochmal bei und möchte dann noch auf einen weiteren Fehler aufmerksam machen, der mir zwar aufgefallen ist, aber ich jetzt erst anfange mich darum zu kümmern. Und zwar ist es momentan so, dass wenn der Spieler steht oder rennt alles perfekt ist, die Animation spielt alle 4 Frames und folgt dem Spieler, wenn ich aber springe folgt die Animation dem Spieler zwar noch einwandfrei, die Animation scheint aber nur noch den ersten Frame darzustellen. Das flackert hübsch und sieht auch ok aus, ist aber noch nicht ganz so wie ich es mir vorstelle. Na mal schauen . . .


    Spoiler anzeigen

    Quellcode

    1. //Shooting
    2. if (canshoot) = true
    3. if keyboard_check(ord("D")) || (gamepad_button_check(0,gp_face3))
    4. {
    5. canshoot = false;
    6. muzzlefire = true;
    7. alarm[1] = 12;
    8. if image_xscale = 1
    9. {
    10. thing = instance_create(x+16,y-2,obj_lasershot_lev1_right);
    11. thing.vspeed = 8;
    12. thing.direction = 0;
    13. }
    14. else
    15. {
    16. thing = instance_create(x-16,y-2,obj_lasershot_lev1_left);
    17. thing.vspeed = 8;
    18. thing.direction = 180;
    19. }
    20. }
    Alles anzeigen



    Spoiler anzeigen

    Quellcode

    1. ///player_muzzlefire
    2. draw_self();
    3. if muzzlefire = true
    4. {
    5. if image_xscale = 1
    6. {
    7. draw_sprite_ext(spr_muzzlefire,2-3,x+20,y-2,1,1,0,-1,1)
    8. }
    9. if image_xscale = -1
    10. {
    11. draw_sprite_ext(spr_muzzlefire,2-3,x-20,y-2,-1,1,0,-1,1)
    12. }
    13. muzzlefire += 0.5
    14. }
    15. if muzzlefire >= 3
    16. {
    17. muzzlefire = false;
    18. }
    Alles anzeigen
  • Ich bin grad zu faul in den Code zu schauen ^^
    Um dein Wissen aufzufrischen, wie man das mit den einem Frame macht, kannst du image_index benutzen, dort gibst du an, welches Frame angezeigt werden soll. Dafür solltest du aber image_speed = 0 setzen, da sonst die Animation von da weiter spielt.
    im draw kannst du das bei draw_sprite bei dem Parameter sub_image einstellen

    @Duftner
    die Anzahl der Images/Frames ist in der Variable image_number

    Edit: @zhe73
    mache mal statt muzzle_fire == true muzzle_fire != false

    Edit: eine Zufallszahl kannst du mit irandom(x) bekommen. über randomize() kannst du das ganze dann noch etwas zufälliger machen, sonst kann man irgendwann eine Wiederholung feststellen, wobei das bei dem Feuer nicht so eine große Rolle spielen würde, da man nur 1 Frame das Sprite sieht.
    In deinem Fall kannst du dann das Subimage auf irandom(image_number-1) machen
    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

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

  • Der Fehler liegt an der Variable muzzlefire,
    ein Sprite kann mehrere Images haben, in deinem Fall sind es 4. Das heißt, das erste Image hat den wert 0, das zweite 1, das dritte 2 und das vierte 3 (wie in einem Array).
    Willst du also das erste Image zeichnen lassen, so lautet der Code so: draw_sprite(sprite, 0, x, y); , für das zweite Image so: draw_sprite(sprite, 1, x, y); usw.
    Zudem musst du angeben, welches Image du zeichnen lassen willst und das funktioniert leider nicht so, wie du es gemacht hast ( draw_sprite_ext(spr_muzzlefire,2-3,x-20,y-2,-1,1,0,-1,1) ), hierfür brauchst du eine Variable, welche du jeden Step hochzählen lässt und in unserem Fall war das eben die Variable animation oder muzzlefire.

    Hier habe ich es mal verbessert:

    Spoiler anzeigen

    GML-Quellcode

    1. //Shooting
    2. if (canshoot) = true
    3. if keyboard_check(ord("D")) || (gamepad_button_check(0,gp_face3))
    4. {
    5. canshoot = false;
    6. muzzlefire = 0;
    7. alarm[1] = 12;
    8. if image_xscale = 1
    9. {
    10. thing = instance_create(x+16,y-2,obj_lasershot_lev1_right);
    11. thing.vspeed = 8;
    12. thing.direction = 0;
    13. }
    14. else
    15. {
    16. thing = instance_create(x-16,y-2,obj_lasershot_lev1_left);
    17. thing.vspeed = 8;
    18. thing.direction = 180;
    19. }
    20. }
    Alles anzeigen




    Spoiler anzeigen

    GML-Quellcode

    1. ///player_muzzlefire
    2. draw_self();
    3. if muzzlefire != -1
    4. {
    5. if image_xscale = 1
    6. {
    7. draw_sprite_ext(spr_muzzlefire,muzzlefire ,x+20,y-2,1,1,0,-1,1)
    8. }
    9. if image_xscale = -1
    10. {
    11. draw_sprite_ext(spr_muzzlefire,muzzlefire ,x-20,y-2,-1,1,0,-1,1)
    12. }
    13. muzzlefire += 0.5
    14. }
    15. if muzzlefire > image_number // wie Husi sagte, gibt image_number die Anzahl der Images in deinem Sprite wieder
    16. {
    17. muzzlefire = -1;
    18. }
    Alles anzeigen

    Husi012 hat mich nicht mehr in seiner Signatur, ich bin trotzdem noch fame.

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

  • @Husi012

    Um dein Wissen aufzufrischen, wie man das mit den einem Frame macht, kannst du image_index benutzen, dort gibst du an, welches Frame angezeigt werden soll. Dafür solltest du aber image_speed = 0 setzen, da sonst die Animation von da weiter spielt. Im draw kannst du das bei draw_sprite bei dem Parameter sub_image einstellen


    Die Variante werde ich aufjedenfall noch ausprobieren. Denn ich denke das könnte schon besser aussehen wenn man es so macht, dass es immer ein zufälliges Frame gespielt wird, anstatt die ganze Animation immer und immer wieder abzuspielen.

    mache mal statt muzzle_fire == true muzzle_fire != false


    Da komme ich noch nicht hinter, was der Unterschied ist zwischen:

    if muzzlefire = true; // wenn muzzlefire wahr ist;
    und
    if muzzlefire != false; // wenn muzzlefire nicht gleich falsch ist; was ja letztendlich auch nichts anderes als wahr ist.

    Und das sehr seltsame ist, dass ein weiteres Problem gelöst wurde nachdem ich das mit dem = und != nun so angepasst hatte. Und zwar war ich grade schon dabei zu versuchen den Sprites eine Tiefenebene(depth) zu geben, da man das muzzlefire auf dem Background zwar gesehen hat, dort wo Tiles waren aber eigentlich nur verbuggt(schaute so aus, als wenn nur hier und da ein paar Pixel angezeigt wurden(durchscheinten)). Aber wie erwähnt wird die Animation jetzt überall wunderbar gezeichnet.


    @Dufner: Das mit den Images hatte ich eigentlich schon verstanden, war nur n bisserl verwirrt weil du bei deinem Beispiel Code ja 5 Images hattest und bei " if animation >= 4 " geschrieben hattest.
    Aber danke nochmal für die Aufklärung, dass sollte nun auch sitzen.

    Nochmal kurz dazu . . .

    ( draw_sprite_ext(spr_muzzlefire,2-3,x-20,y-2,-1,1,0,-1,1) ) ; irgendeine Funktion scheint dieses 2-3 im subimg aber schon zu haben, zumindest wird die Animation gespielt und irgendwie nicht immer vom Anfang und rein optisch fehlt auch zumindest das erste Frame der Animation. Also mir schauts so aus als ob ich damit die letzten Frames abspiele aber mit einem zufälligem Start.

    So Dufner, und das Problem aus meinem vorherigen Post

    Ich möchte dann noch auf einen weiteren Fehler aufmerksam machen, der mir zwar aufgefallen ist, aber ich jetzt erst anfange mich darum zu kümmern. Und zwar ist es momentan so, dass wenn der Spieler steht oder rennt alles perfekt ist, die Animation spielt alle 4 Frames und folgt dem Spieler, wenn ich aber springe folgt die Animation dem Spieler zwar noch einwandfrei, die Animation scheint aber nur noch den ersten Frame darzustellen. Das flackert hübsch und sieht auch ok aus, ist aber noch nicht ganz so wie ich es mir vorstelle.


    wurde dadurch gelöst, dass ich halt die 2-3 im subimg mit muzzlefire ersetzt habe. Warum das so ist, dem muss ich erstmal auf den Grund gehen. Hab schon geschaut ob das vielleicht was mit meiner jump_script oder was auch immer zu tun haben könnte. Mal schauen . . .


    Wie dem auch sei, ich bin euch sehr sehr dankbar für eure Mühe und würde für mich sagen das dieses Problem im vollem Umfang gelöst ist, und hänge für Interessierte nochmal den Code mit bei.

    Spoiler anzeigen

    Quellcode

    1. //Shooting
    2. if (canshoot) = true
    3. if keyboard_check(ord("D")) || (gamepad_button_check(0,gp_face3))
    4. {
    5. canshoot = false;
    6. muzzlefire = 0;
    7. alarm[1] = 12;
    8. if image_xscale = 1
    9. {
    10. audio_play_sound(snd_player_laser,10,false);
    11. thing = instance_create(x+16,y-2,obj_lasershot_lev1_right);
    12. thing.vspeed = 8;
    13. thing.direction = 0;
    14. }
    15. else
    16. {
    17. audio_play_sound(snd_player_laser,10,false);
    18. thing = instance_create(x-16,y-2,obj_lasershot_lev1_left);
    19. thing.vspeed = 8;
    20. thing.direction = 180;
    21. }
    22. }
    Alles anzeigen



    Spoiler anzeigen

    Quellcode

    1. ///player_muzzlefire
    2. draw_self();
    3. if muzzlefire != -1
    4. {
    5. if image_xscale = 1
    6. {
    7. draw_sprite_ext(spr_muzzlefire,muzzlefire,x+18,y-2,1,1,0,-1,1)
    8. }
    9. if image_xscale = -1
    10. {
    11. draw_sprite_ext(spr_muzzlefire,muzzlefire,x-18,y-2,-1,1,0,-1,1)
    12. }
    13. muzzlefire += 0.5
    14. }
    15. if muzzlefire >= 4
    16. {
    17. muzzlefire = -1;
    18. }
    Alles anzeigen