GMS Physics - Enterhaken bzw. Seilkanone

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

  • GMS Physics - Enterhaken bzw. Seilkanone

    Hallo, wer kennt sich gut mit der box2d Engine in GMS aus? Ich habe versucht ein Seil mit einem Enterhaken dran zu simulieren, bzw. eine Seilkanone. Bis jetzt klappt das noch nicht so ganz wie ich das möchte. Seht selbst:



    den Spaß mit dem GIf wollte ich mir nicht nehemn lassen. Dort könnt ihr, wenn ihr mit dem Gesicht näher an euer Display rangeht, sehen was passiert. Der Enterhaken bleibt in der Wand stecken, wie es sein soll aber das Seil "reißt" ab und verhält sich dann ganz komisch, grade zu lebendig. Zum besseren Verständnis: Ich lasse Instanzen, die Seilstücke, entlang einer Linie in mehreren Frames erstellen, was dann so aussieht als ob das Seil aus der Wumme geschoßen kommt. Es wird pro Seilstück ein distance_joint erstellt, der das neueste und das letzte Seilstück miteinander verbindet. Und ich lasse einen friction_joint erstellen pro Seilstück. So eingestellt das sich die verbundenen Instanzen nicht zu viel bewegen und rotieren können. Soweit so gut, achja und der Enterhaken erstellt wenn er auf die Wanfd trifft auch nen joint (und raucht dann einen...äh...) Aber das Seil reißt immer ab. Bzw. die Joints sind ja noch da aber sie verhalten sich nicht so wie gewollt. Denn die Anchors sind nicht da wo sie sein sollen, sieht man ja, da ist so viel Luft zwischen den Abschnitten. Oh man es spät. Wer hat sowas schon mal gemacht.

    Welche Joints sind am Besten für sowas geeignet? Was muss man beachten, dass die Joints auch wirklich zwei fixtures zusammenhalten und die nicht wild umanand fliegen. Was ist das Geheimnis der Joints?
  • Du meinst mit density. Ja das hat Einiges gebracht, danke. Meine Seilkanone schaut jetzt so aus:



    Allerdings bin ich überhaupt nicht zufrieden. Wenn die Schleuder das Seil wieder reinzeiht/aufwickelt, müsste es sich spannen. Und erst wenn es gespannt ist und die Schleuder weiter aufwickelt würde der Spieler hochgezogen werden. Bei mir folgt die Schleuder einfach dem Seil, mit allen Biegungen. Dass ist natürlich unrealistisch. Ich veröffentliche mal meinen Code. Vielleciht kann ihn jemand gebrauchen und mir jemand helfen dieses Teil zu entwickeln:

    Objekt Seilwerfer
    Create Event

    Spoiler anzeigen

    GML-Quellcode

    1. image_speed = 0;
    2. image_index = 1;
    3. phase = 1;
    4. angle = 0;
    5. maxlength = 120;
    6. length = 0;
    7. xx = 0;
    8. yy = 0;
    9. count = 0;
    10. geschw = 4;
    11. maxforce = .001;
    12. maxtorque = .001;
    13. n = 0;
    14. nn = 0;
    15. collision = 0;
    16. glied = physics_fixture_create();
    17. physics_fixture_set_box_shape(glied,1.5,1.5);
    18. physics_fixture_set_density(glied, .005);
    19. physics_fixture_set_linear_damping(glied, 1);
    20. physics_fixture_set_angular_damping(glied, 10);
    Alles anzeigen


    Step Event
    Spoiler anzeigen

    GML-Quellcode

    1. if global.seilwerfer = 0 instance_destroy();
    2. if phase = 1
    3. {
    4. if Player.image_xscale = 1
    5. {
    6. phy_position_x = Player.x+12;
    7. phy_position_y = Player.y;
    8. if angle_difference(image_angle,0) < 45 image_angle = point_direction(x,y,mouse_x,mouse_y)
    9. else phy_rotation = angle;
    10. }
    11. if Player.image_xscale = -1
    12. {
    13. phy_position_x = Player.x-12;
    14. phy_position_y = Player.y;
    15. if angle_difference(image_angle,180) < 45 image_angle = point_direction(x,y,mouse_x,mouse_y)
    16. else phy_rotation = angle;
    17. }
    18. angle = point_direction(x,y,mouse_x,mouse_y);
    19. if mouse_check_button_pressed(mb_left)
    20. {
    21. xx = x + lengthdir_x(10-4,angle);
    22. yy = y + lengthdir_y(10-4,angle);
    23. joint_fric = physics_joint_friction_create(Player, id, x,y, 0,0, false);
    24. joint = physics_joint_distance_create(Player, id, Player.x,Player.y, x,y, false);
    25. phy_rotation = -angle;
    26. phase = 2
    27. }
    28. }
    29. if phase = 2
    30. {
    31. if mouse_check_button(mb_left)
    32. {
    33. repeat (2)
    34. {
    35. if collision = 1
    36. {
    37. phase = 2;
    38. exit;
    39. }
    40. for (i = 0; i < n; i += 1)
    41. {
    42. inst[i].phy_speed_x = 0;
    43. inst[i].phy_speed_y = 0;
    44. }
    45. xx += lengthdir_x(4,angle);
    46. yy += lengthdir_y(4,angle);
    47. inst[n] = instance_create(xx,yy,Seilglied);
    48. physics_fixture_bind(glied, inst[n]);
    49. inst[n].angle = angle;
    50. if n = 0
    51. {
    52. joint_fric[n] = physics_joint_friction_create(id,inst[n], x + lengthdir_x(10,angle),y + lengthdir_y(10,angle), maxforce,maxtorque, false);
    53. joint[n] = physics_joint_distance_create(id,inst[n], x + lengthdir_x(10,angle),
    54. y + lengthdir_y(10,angle), inst[n].x + lengthdir_x(1,angle-180),inst[n].y + lengthdir_y(1,angle-180), false);
    55. }
    56. if n > 0
    57. {
    58. joint_fric[n] = physics_joint_friction_create(inst[n-1],inst[n], inst[n-1].x + lengthdir_y(1,angle),inst[n-1].y + lengthdir_y(1,angle), maxforce,maxtorque, false);
    59. joint[n] = physics_joint_distance_create(inst[n-1],inst[n], inst[n-1].x + lengthdir_y(1,angle),
    60. inst[n-1].y + lengthdir_y(1,angle), inst[n].x + lengthdir_y(1,angle-180),inst[n].y + lengthdir_y(1,angle-180), true)
    61. }
    62. n += 1;
    63. }
    64. }
    65. if mouse_check_button_released(mb_left) {phase = 3; nn = 1}
    66. }
    67. if phase = 3
    68. {
    69. if mouse_check_button(mb_left)
    70. {
    71. if nn < n-1
    72. {
    73. if point_distance(x,y,inst[nn].x,inst[nn].y) > 3
    74. {
    75. dir = point_direction(x,y,inst[nn].x,inst[nn].y);
    76. phy_position_x += lengthdir_x(1,dir);
    77. phy_position_y += lengthdir_y(1,dir);
    78. inst[nn].phy_position_x += lengthdir_x(4,dir-180);
    79. inst[nn].phy_position_y += lengthdir_y(4,dir-180);
    80. }
    81. else
    82. {
    83. physics_joint_delete(joint_fric[nn]);
    84. physics_joint_delete(joint[nn]);
    85. with (inst[nn]) instance_destroy();
    86. nn += 1;
    87. }
    88. }
    89. }
    90. }
    91. if phase > 1
    92. {
    93. if mouse_check_button_pressed(mb_right)
    94. {
    95. with (Seilglied) instance_destroy();
    96. physics_joint_delete(joint_fric);
    97. physics_joint_delete(joint);
    98. for (i = 0; i < n; i += 1)
    99. {
    100. physics_joint_delete(joint_fric[i]);
    101. physics_joint_delete(joint[i]);
    102. }
    103. with (instance_create(Player.x,Player.y,Seilwerfer)) no_deactivate = 1;
    104. instance_destroy();
    105. }
    106. }
    Alles anzeigen



    Draw Event
    Spoiler anzeigen

    GML-Quellcode

    1. draw_sprite_ext(sprite_index,clamp(phase,1,2),x,y,1,1,angle,c_white,1);
    2. if n > 0
    3. {
    4. var x1 = x+lengthdir_x(5,angle);
    5. var y1 = y+lengthdir_y(5,angle);
    6. dis = point_distance(x1,y1, inst[nn].x,inst[nn].y);
    7. ang = point_direction(x1,y1, inst[nn].x,inst[nn].y);
    8. for (i = 0; i <= dis; i += 3)
    9. {
    10. draw_sprite_ext(spr_rope,4,x1+lengthdir_x(i,ang),y1+lengthdir_y(i,ang),1,1,ang,c_white,1);
    11. }
    12. for (i = nn+1; i < n; i += 1)
    13. {
    14. dis = point_distance(inst[i-1].x,inst[i-1].y, inst[i].x,inst[i].y);
    15. ang = point_direction(inst[i-1].x,inst[i-1].y, inst[i].x,inst[i].y);
    16. for (ii = 0; ii <= dis; ii += 3)
    17. {
    18. draw_sprite_ext(spr_rope,4,inst[i-1].x+lengthdir_x(ii,ang),inst[i-1].y+lengthdir_y(ii,ang),1,1,ang,c_white,1);
    19. }
    20. }
    21. draw_sprite_ext(spr_rope,3,inst[n-1].x+lengthdir_x(3,angle),inst[n-1].y+lengthdir_y(3,angle),1,1,angle,c_white,1);
    22. }
    Alles anzeigen



    Objekt Seilglied
    Create Event

    Spoiler anzeigen

    GML-Quellcode

    1. image_speed = 0;
    2. image_index = 4;
    3. collision = 0;


    Collision Event mit Wandobjekt bzw. Parent Objekt für statische Fixtures
    Spoiler anzeigen

    GML-Quellcode

    1. if collision = 0
    2. {
    3. phy_speed_x = 0;
    4. phy_speed_y = 0;
    5. joint_fric = physics_joint_friction_create(id,other, x,y, 0,0, false);
    6. joint = physics_joint_distance_create(id,other, x,y,x+lengthdir_x(2,phy_rotation),y+lengthdir_y(2,phy_rotation), false);
    7. if instance_exists(Seilwerfer) Seilwerfer.collision = 1;
    8. var dir = Seilwerfer.angle;
    9. for (i = 0; i < 32; i += 1)
    10. {
    11. if collision_point(x+lengthdir_x(i,dir),y+lengthdir_y(i,dir),par_static,1,1)
    12. {
    13. phy_position_x = x+lengthdir_x(i,dir);
    14. phy_position_y = y+lengthdir_y(i,dir);
    15. break;
    16. }
    17. }
    18. }
    19. collision = 1;
    Alles anzeigen



    Wie gesagt bin ich überhaupt nicht zufrieden. EIgentlich wollte ich so ein Seil wie das in Worms Worldparty (oder wie im 2d Remake) machen. Das Seil bleibt dort eigentlich immer straff. Aber es biegt sich an den Stellen wo auf die Landschaft trifft. Und es verhält sich wie Gummi.



    So hätte ich das eigentlich gern. Wie mach ich das?