Rotation eines Objektes in Richtung eines anderen Objektes innerhalb eines definierten Bereiches

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

  • Rotation eines Objektes in Richtung eines anderen Objektes innerhalb eines definierten Bereiches

    Hi,

    ich hoffe bei dem Thread-Titel weiß jeder Bescheid, was gemeint ist =)

    Falls diese Frage zu einfach für komplexe Technikfragen ist, bitte ich das zu entschuldigen und den Thread den anderen Bereich zu verschieben.

    Ich habe in einem anderen Thread nach einer Lösung gefragt um ein Objekt in Richtung eines zweiten beliebigen Objektes auszurichten. Entscheidend ist dabei die Ausrichtung der direction. Dabei soll der kürzeste Weg berechnet werden und die Möglichkeit gegeben sein den Rotationsbereich des zu drehenden Objektes festzulegen. Die Schwierigkeit dabei liegt in dem eben genannten Rotationsbereich und dem Sprung zwischen 0 und 359 Grad.

    Mein erster Ansatz sah folgendermaßen aus:
    Spoiler anzeigen

    GML-Quellcode

    1. ////////////////////////////////////////////////////////////////////////////
    2. //! FLAK Rotation
    3. //!
    4. //! Created By : [esn]
    5. //! Created On : [2006-05-02]
    6. //! Modified By : [esn]
    7. //! Modified On : [2007-11-18]
    8. ////////////////////////////////////////////////////////////////////////////
    9. //! Description :
    10. //! Rotates an object to any specified target object.
    11. //!
    12. //! Arguments :
    13. //! -argument0: Target object
    14. //! -argument1: Amount of steps to rotate the flak
    15. //! -argument2: Rotation speed (functions through the alarm[0] event)
    16. //! -argument3: A switch that defines the sprite animation
    17. //! (1 = pre-pixeled; 2 = computed; default is computed)
    18. //! -argument4: If argument3 is 1 use this value to define the
    19. //! image_index formula (e.g. (direction / 22.5) if you got
    20. //! 16 images of rotaion)
    21. //! -argument5: Start of rotation ccw in degrees
    22. //! -argument6: End of rotation ccw in degrees
    23. //!
    24. //! Usage :
    25. //! Put this script in the alarm[0]-event of any FLAK-object.
    26. //!
    27. //! Notes :
    28. //! *If argument3 = 1, you have to use the proper arguments in the
    29. //! shot pattern script too!
    30. ////////////////////////////////////////////////////////////////////////////
    31. {
    32. var vNum_DirectionToPlayer;
    33. vNum_DirectionToPlayer = point_direction(x, y, argument0.x, argument0.y);
    34. if (direction > vNum_DirectionToPlayer)
    35. {
    36. if (direction - vNum_DirectionToPlayer < 180)
    37. {
    38. direction -= argument1;
    39. }
    40. else
    41. {
    42. direction += argument1;
    43. }
    44. }
    45. else
    46. {
    47. if (vNum_DirectionToPlayer - direction < 180)
    48. {
    49. direction += argument1;
    50. }
    51. else
    52. {
    53. direction -= argument1;
    54. }
    55. }
    56. // choses between pre-pixeled and computed image animation
    57. switch (argument3)
    58. {
    59. case 1: image_index = round(argument4); break;
    60. case 2: image_angle = direction; break;
    61. default: image_angle = direction;
    62. }
    63. // sets the speed(delay) of the flak rotaion
    64. alarm[0] = argument2;
    65. }
    Alles anzeigen

    Allerdings wußte ich nicht wie ich einen eingeschränkten Rotationsbereich integrieren sollte. Dann hat mir Shoba seinen Lösungsansatz gezeigt, den ich aufgrund besserer Überschaubarkeit und Kürze und sowieso prompt übernommen habe ;)

    Letztendlich habe ich mit Hilfe eines Freundes es auch geschafft einen Rotationsbereich festzulegen:
    Spoiler anzeigen

    GML-Quellcode

    1. ////////////////////////////////////////////////////////////////////////////////
    2. //! FLAK Rotation
    3. //!
    4. //! Created on : [2006-05-02] by [esn]
    5. //! Modified on : [2007-11-26] by [esn]
    6. ////////////////////////////////////////////////////////////////////////////////
    7. //! Description :
    8. //! Rotates an object to any specified target object.
    9. //!
    10. //! Arguments :
    11. //! -argument0: Target object
    12. //! -argument1: Amount of steps to rotate the FLAK
    13. //! -argument2: Rotation delay (functions through the alarm[0] event)
    14. //! -argument3: A switch that defines the sprite animation
    15. //! (1 = pre-pixeled; 2 = computed; default is computed)
    16. //! -argument4: If argument3 is 1 use this value to define the image_index
    17. //! formula (e.g. (direction / 22.5) if you got 16 images of rot.)
    18. //! -argument5: Start of rotation ccw in degrees
    19. //! -argument6: End of rotation ccw in degrees
    20. //!
    21. //! Usage :
    22. //! Put this script in the alarm[0]-event of any FLAK-object. Set argument5 to
    23. //! 0 and argument6 to 359, to get full range rotation of 360 degrees.
    24. //!
    25. //! Notes :
    26. //! *If argument3 = 1, you have to use the proper arguments in the
    27. //! shot pattern script too!
    28. ////////////////////////////////////////////////////////////////////////////////
    29. {
    30. var vNum_TargetDirection,
    31. vNum_NewDirection,
    32. vNum_AngleDifference,
    33. vNum_WayOfRotation;
    34. vNum_TargetDirection = round(point_direction(x, y, argument0.x, argument0.y));
    35. vNum_AngleDifference = abs( direction - vNum_TargetDirection );
    36. // checks whether to rotate the object at all or not
    37. if ( vNum_AngleDifference >= argument1 )
    38. {
    39. // get the shortest way cw or ccw
    40. if ( vNum_AngleDifference > 180 )
    41. {
    42. // rotate object cw
    43. vNum_WayOfRotation = -1;
    44. }
    45. else
    46. {
    47. // rotate object ccw
    48. vNum_WayOfRotation = 1;
    49. }
    50. // calculation of the objects new angle
    51. vNum_NewDirection =
    52. ( sign(vNum_TargetDirection - direction) * vNum_WayOfRotation * argument1 +
    53. 360 + direction ) mod 360;
    54. // set new direction only if it lies in the rotation area specified by
    55. // argument5 and argument6. two cases are needed because of the jump
    56. // from 0 to 359 degrees. the first case cares about rotation without
    57. // jumping between 0 and 359...
    58. if ( argument5 <= argument6 )
    59. {
    60. if ((vNum_NewDirection >= argument5) && (vNum_NewDirection <= argument6))
    61. {
    62. direction = vNum_NewDirection;
    63. }
    64. }
    65. // ...and the second one cares about that issue
    66. else
    67. {
    68. if ((vNum_NewDirection >= argument5) || (vNum_NewDirection <= argument6))
    69. {
    70. direction = vNum_NewDirection;
    71. }
    72. }
    73. // choses between pre-pixeled and computed image animation
    74. switch (argument3)
    75. {
    76. case 1: image_index = round(argument4); break;
    77. case 2: image_angle = direction; break;
    78. default: image_angle = direction;
    79. }
    80. }
    81. // sets the delay of the flak rotaion
    82. alarm[0] = argument2;
    83. }
    Alles anzeigen

    Der Code dürfte für Jedermanns Verständnis genug auskommentiert sein. Falls doch nicht, könnt Ihr gerne nachfragen. Das Skript setzt den zu berechnenden Winkel als direction fest und geht davon aus, daß man den image_angle oder den image_index zur visuellen Darstellung benutzt. Das ist es, was im Switch-Statement abgehandelt wird. Genaueres steht im Header.

    Da eine Lösung ja bereits vorliegt, werde ich den Thread auch gleich als gelöst markieren. Falls Jemandem eine noch bessere oder einfach nur andere Alternative einfällt, kann diese hier gerne gepostet werden. Auch Optimierungsvorschläge des letzten Skriptes sind gerne gesehen, Hinweise auf Schreib- oder Ausdrucksfehler sowieso.

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