Top down shooter player-wand-probleme

  • GM 8

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

  • Top down shooter player-wand-probleme

    Moin!
    Ich bin grad dabei einen topdownshooter zu machen.Ich habe eine WSAD Steuerung gemacht. Wenn man 'D' drückt und gegen die Wand läuftbleibt der Spieler ganz normal stehen. Wenn man dann 'D' loslässt und 'W' drückt geht der Spieler ganz normal nach oben.

    Wenn ich aber 'D' und 'W' gleichzeitig drücke und gegen die Wand rechts vom player laufe, bleibt der Player auch stehen. Er sollte sich aber mit einem speed von 3.16 (√5+5) nach oben bewegen.
    Dies liegt sicher dadran, dass ich den speed bei einer Collision mit der Wand null setzte.

    Was kann ich machen, damit der Player sich bei einer collision mit der Wand und 2 gedrückten Tasten mit einem speed von 3.16 an der Wand lang bewegt?

    Dies ist der Code, den ich fürs gehen bemnutze:
    (ich weiß ist etwas kompliziert, aber würde ich gerne so lassen, da der player auf den Diagonalen nicht schneller ist und ich später den Speed für jede Richtung individuell noch verändern kann)

    :event_step:

    GML-Quellcode

    1. //Steuerung
    2. //Prüfung, welche Tasten gedrückt werden --> Variablenwerte werden gestzt
    3. {
    4. if (keyboard_check(ord('A'))) global.key_a= 1;
    5. if (keyboard_check(ord('D'))) global.key_d= 1;
    6. if (keyboard_check(ord('W'))) global.key_w= 1;
    7. if (keyboard_check(ord('S'))) global.key_s= 1;
    8. if (keyboard_check_released(ord('A'))) global.key_a= 0;
    9. if (keyboard_check_released(ord('D'))) global.key_d= 0;
    10. if (keyboard_check_released(ord('S'))) global.key_s= 0;
    11. if (keyboard_check_released(ord('W'))) global.key_w= 0;
    12. //wenn 1 Taste gedrückt wird, wird der playerspeed gesetzt
    13. if global.key_a=1 && global.key_d=0 && global.key_s=0 && global.key_w=0 x+=-5
    14. if global.key_a=0 && global.key_d=1 && global.key_s=0 && global.key_w=0 x+=5
    15. if global.key_a=0 && global.key_d=0 && global.key_s=1 && global.key_w=0 y+=5
    16. if global.key_a=0 && global.key_d=0 && global.key_s=0 && global.key_w=1 y+=-5
    17. //wenn 2 Tasten gedrückt werden, wird der playerspeed gesetzt
    18. if global.key_a=1 && global.key_d=0 && global.key_s=0 && global.key_w=1 {x+=-3.16 y+=-3.16}
    19. if global.key_a=0 && global.key_d=1 && global.key_s=0 && global.key_w=1 {x+=3.16 y+=-3.16}
    20. if global.key_a=0 && global.key_d=1 && global.key_s=1 && global.key_w=0 {x+=3.16 y+=3.16}
    21. if global.key_a=1 && global.key_d=0 && global.key_s=1 && global.key_w=0 {x+=-3.16 y+=3.16}
    22. //3 Tasten (speed=0)
    23. if global.key_a=1 && global.key_d=1 && global.key_s=1 && global.key_w=0 y+=0
    24. if global.key_a=0 && global.key_d=1 && global.key_s=1 && global.key_w=1 y+=0
    25. if global.key_a=1 && global.key_d=0 && global.key_s=1 && global.key_w=1 y+=0
    26. if global.key_a=1 && global.key_d=1 && global.key_s=0 && global.key_w=1 y+=0
    27. //4 Tasten (speed=0)
    28. if global.key_a=0 && global.key_d=0 && global.key_s=0 && global.key_w=0 y+=0
    29. }
    Alles anzeigen


    obj_player :event_collision: obj_wall

    GML-Quellcode

    1. speed=0


    Achja die Suche hatte ich auch schon benutzt und hab auch viel gefunden, aber hat mir alles nicht weiter geholfen...

    Und wers nochmal als .gmk haben will:
    Dateien
    • player-wall.zip

      (10,35 kB, 137 mal heruntergeladen, zuletzt: )
    :action_drawsprite: :event_collision: :action_killposition: = :action_health:

    :action_drawsprite: + :action_drawsprite: + :action_drawlivesimage: = :action_drawsprite: :action_drawsprite: :action_drawsprite:

    :action_drawsprite: + :action_color: = :action_spritecolor:

    :action_drawsprite: + :action_wrap: = :action_exit:
  • Oh, bitte lass diese ganzen unnötigen Abfragen und nimm mal lieber die Kollisionsfunktionen des Game Makers zur Hand.
    speed = 0; im Collision-Event setzt, bewirkt erstmal gar nichts, weil du den speed deines Objektes gar nicht änderst und das hier:

    GML-Quellcode

    1. //3 Tasten (speed=0)
    2. if global.key_a=1 && global.key_d=1 && global.key_s=1 && global.key_w=0 y+=0
    3. if global.key_a=0 && global.key_d=1 && global.key_s=1 && global.key_w=1 y+=0
    4. if global.key_a=1 && global.key_d=0 && global.key_s=1 && global.key_w=1 y+=0
    5. if global.key_a=1 && global.key_d=1 && global.key_s=0 && global.key_w=1 y+=0


    macht auch keinen Sinn. Wenn du eine 0 zum y addieren willst, dann lass es doch einfach weg.

    Also Folgendes kommt in das Step-Event deines obj_player:
    Spoiler anzeigen

    GML-Quellcode

    1. image_angle = point_direction(x,y,mouse_x,mouse_y)-90
    2. //Steuerung
    3. //Prüfung, welche Tasten gedrückt werden --> Variablenwerte werden gestzt
    4. if (keyboard_check(ord('A')) && !collision_rectangle(x-sprite_width/2-5,y-sprite_height/2,x,y+sprite_height/2,obj_wall,1,1)) x -= 3.16;
    5. if (keyboard_check(ord('D')) && !collision_rectangle(x+sprite_width/2+5,y-sprite_height/2,x,y+sprite_height/2,obj_wall,1,1)) x += 3.16;
    6. if (keyboard_check(ord('W')) && !collision_rectangle(x-sprite_width/2,y-sprite_height/2-5,x+sprite_width/2,y+sprite_height/2,obj_wall,1,1)) y -= 3.16;
    7. if (keyboard_check(ord('S'))&& !collision_rectangle(x-sprite_width/2,y-sprite_height/2,x+sprite_width/2,y+sprite_height/2+5,obj_wall,1,1)) y += 3.16;


    Den Code erklär ich jetzt nicht, denn dafür ist die Hilfe da.
    MfG

    Albert Einstein schrieb:

    Probleme kann man niemals mit derselben Denkweise lösen, durch die sie entstanden sind.
  • Danke :)
    hat mir erstmal sehr geholfen.

    Aber ich hätte gerne eine runde collisionmask wenns geht. hab schon geguckt, ob ichs irgentwie mit collision_circle(xc,yc,radius,obj,prec,notme) hinbekomme, aber ich schaffe es irgentwie nicht... :S :(

    Und ich bekomme es mit diesem code auch nicht hin, dass der player diagonal genau so schnell läuft, wie horizontal/vertikal...

    Kann jemand mir da bitte noch mal helfen? :rolleyes:
    :action_drawsprite: :event_collision: :action_killposition: = :action_health:

    :action_drawsprite: + :action_drawsprite: + :action_drawlivesimage: = :action_drawsprite: :action_drawsprite: :action_drawsprite:

    :action_drawsprite: + :action_color: = :action_spritecolor:

    :action_drawsprite: + :action_wrap: = :action_exit:
  • hmm
    ja kann ich machen, aber bringt auch nichts... aber mein player objekt ist ja eigentlich auch schon rund...
    Mit dem Code von Trixt0r wird glaub ich immer ne rechteckige collisions abfrage gemacht... Gibt es denn irgetwie einen code, der das gleiche in rund macht?
    :action_drawsprite: :event_collision: :action_killposition: = :action_health:

    :action_drawsprite: + :action_drawsprite: + :action_drawlivesimage: = :action_drawsprite: :action_drawsprite: :action_drawsprite:

    :action_drawsprite: + :action_color: = :action_spritecolor:

    :action_drawsprite: + :action_wrap: = :action_exit:
  • Wieso sieht das denn besser aus, wenn die Kollisionsabfrage rund ist?
    Wenn du mit collision_circle abfragst musst du auch 4 Abfragen erstellen und das wirkt sich auf die Performance nicht wirklich positiver aus.

    KATZE schrieb:

    Es sieht dann besser aus, wenn die kollisionsabfrage rund ist...

    Was sieht denn da dann besser aus?
    Ich sehe keine Grund den Code zu verändern.

    MfG

    Albert Einstein schrieb:

    Probleme kann man niemals mit derselben Denkweise lösen, durch die sie entstanden sind.
  • Trixt0r schrieb:

    Wenn du mit collision_circle abfragst musst du auch 4 Abfragen erstellen und das wirkt sich auf die Performance nicht wirklich positiver aus.


    Naja, bedingt. Wenn man mit collision_circle abfragt, kann man sich die Vier verschiedenen Kollisionsabfragen sparen und müsste nur noch die jeweiligen Tasten überprüfen. Das Problem wäre halt, dass der Spieler sich schon bei der winzigsten Wand festfahren würde. Und damit mein ich wirklich komplett. Auch wenn die Wand über ihm wäre, könnte er nicht mehr nach unten, links oder rechts laufen.

    Von daher würde ich da als Lösung entweder die Variante von Kev empfehlen, oder auf den Kollisionskäse komplett verzichten und über place_free bzw. place_meeting gehen. In etwa so:

    :event_step: Step-Event

    GML-Quellcode

    1. if !place_meeting(x+3.16,y,obj_wall) x+=keyboard_check(global.key_d)*3.16; // keyboard_check gibt entweder true (1) oder false (0) zurück. Das nimmst du mit 3.16 mal und sparst dir so eine zusätzliche if-Abfrage.
    2. if !place_meeting(x-3.16,y,obj_wall) x-=keyboard_check(global.key_a)*3.16; // Das gleiche, nur diesmal nach links....
    3. if !place_meeting(x,y+3.16,obj_wall) y+=keyboard_check(global.key_s)*3.16; // ...unten...
    4. if !place_meeting(x,y-3.16,obj_wall) y-=keyboard_check(global.key_w)*3.16; // ...und oben.


    Und schon hast du die Bewegungsengine fertig. Keine ellenlangen if-Abfragen für jede mögliche Tastenkombination, keine Ressourcenfresser aka Kollisionsabfragen und trotzdem eine recht passable Steuerung in 8 Richtungen.