Rotate arrow in player.

Sahaj GuptaSahaj Gupta
3 min read

Now that we have our player working, let's add the arrow (trajectory) to player, and add Strech sound. We'll add arrow as sprite2d node in player node.

Note: Make sure to add offset in arrow so that pivot of arrow remains in center of player but the png is at right of player.

Rules on when to play sound.

  • Only if player has moved from last position.

  • Only when sound is not playing.

we'll add two functions scale_arrow and play_strech_sound in scale arrow we'll rotate and scale (later in blog) arrow and in play strech sound well we'll just play sound

func scale_arrow():
    arrow.rotation = (_start_position - position).angle()


func play_strech_sound():
    if not (_last_dragged_position - position) == Vector2.ZERO:
        if not strech_sound.playing:
            strech_sound.play()

in scale arrow function we are subtracting the start position from current position and taking out the angle of deference and that is our rotation value.

in play strech sound first we are checking if player has moved then is sound is not playing then only we are playing sound you can set _last_dragged_position just before we update the position of player in update_drag function

func update_drag():
    if detect_release(): return
    var gmp = get_global_mouse_position()
    play_strech_sound()
    _last_dragged_position = position
    position = get_update_drag_position(gmp)
    scale_arrow()
    play_strech_sound()

Now that we are rotating arrow as per player drag, lets work on player throw and arrow scale.

Player throw.

To launch our player we need to apply impulse. and for use its easy because we already have our dragged vector we'll just multiply it with -1 to apply impulse in reverse direction also we'll need a multiplayer because the dragged vector is too small and apply this when player is released. here is the code for that.

const IMPUL_MULTI: int = 20
func get_impulse() -> Vector2:
    return dragged_vector * -1 * IMPUL_MULTI

func set_new_state(new_state: PLAYER_STATE):
    state = new_state
    if state == PLAYER_STATE.RELEASE:
        freeze = false
        arrow.hide()
        apply_central_impulse(get_impulse())

Lets add throw sound as well. add this line in the end and use AudioStreamPlayer2D for this. throw_sound.play()

Scale arrow

We already have get_impulse function so its easy for us to get the percentage of applied impulse for this too we'll need a constant to calculate percentage. we'll also store the initial value of arrow scale so that we dont scale down from initial value. formula to get impulse percentage is length of impulse vector / Max impulse length. and to scale arrow (initial arrow size * percentage) + initial arrow size here is the code for that.

var arrow_scale_x: float
const IMPUL_MAX: int = 1200
func _ready():
    arrow_scale_x = arrow.scale.x
func scale_arrow():
    arrow.rotation = (_start_position - position).angle()
    var impl = get_impulse().length()
    var perc = impl / IMPUL_MAX
    arrow.scale.x = (arrow_scale_x * perc) + arrow_scale_x

And that's it now you can run the game to test everything
What we did in this blog.

What we have learned in this blog

  • Adding arrow and rotating it as per dragged vector

  • Throwing player by applying impulse

  • Calculate impulse to scale the arrow.

Contact me

0
Subscribe to my newsletter

Read articles from Sahaj Gupta directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Sahaj Gupta
Sahaj Gupta