How to shoot in a particular direction on my 2d shooter platformer?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Juanchoh

Hey, so I’ve been scorching my brains here with this problem - I’ve got to say I’m quite new to this whole programing thing -, so I ask the community for their valious help. Ok, so I’m trying to replicate a Super Metroid type of shooting (press a button to aim in high diagonal, press another button for low diagonal, press both for aiming up), and I’ve been using vectors to try to solve this out but to no avail. Here is my code by parts:

Here are the states:

var is_pointing_high := Input.is_action_pressed("pointhigh")
var is_pointing_low := Input.is_action_pressed("pointlow")
var is_pointing_up := Input.is_action_pressed("pointhigh") and Input.is_action_pressed("pointlow")
var no_more_pointing := Input.is_action_just_released("pointhigh") or Input.is_action_just_released("pointlow")

Here are the conditions:

if is_pointing_high:
	var diagup : Rect2 = Rect2(_palma.global_position, Vector2(1,-1))
	var angup := Vector2(diagup.size.x, diagup.size.y) - global_position
	rot = _palma.get_angle_to(angup)

if is_pointing_low:
	var diagdown : Rect2 = Rect2(_palma.global_position, Vector2(1,1))
	var angdown := Vector2(diagdown.size.x, diagdown.size.y) - global_position
	rot = _palma.get_angle_to(angdown)

if is_pointing_up:
	rot = -PI / 2

if no_more_pointing:
	rot = 0.0

if is_shooting:
	shoot()

The function for shooting:

func shoot() -> void:
var _bala := bala.instance()
_bala.start(_palma.global_position, sign(_pivot.scale.x), rot)
get_parent().add_child(_bala)

Aaaand the code in the bullet:

func start(pos: Vector2, dir, angle) -> void:
position = pos
_velocity = Vector2(speed * dir, 0).rotated(angle)

“rot” is my float variable for the angle, and “_palma” is a Position2D node on the palm of the hand of the player character.

Now, with this iteration of code, what ends up happening is the bullet presumably ends up hitting the character (thus destroying itself) while facing right and shooting in a low diagonal while facing left while pressing either button. If you press both buttons, the player will shoot down if facing right and will shoot up if facing left (the only thing I get right).

I appreciate your input on this matter. I will continue to work out this and tell you if I solve it on my own. Thanks!!

:bust_in_silhouette: Reply From: Inces

This is a chaos on a few levels :slight_smile:

First : your boolean conditions do not exclude each other. When player is aiming up it is aiming low and high at the same time, so all conditions are fulfilled. Instead of multiple booleans You should introduce states. One variable status that can have one value of following : aimhigh, aimlow, aimup. On input event those states will be set - if both buttons are pressed - state is aimup, if only one - check which one and set aimhigh or aimlow accordingly.

Second: no more pointing condition is incorrect. It will trigger when one button is still pressed after letting go of another button. It would be generally better to set those statuses in process() using input informations, it will be natural to stop aiming when no input is coming. You could use setget to optimize controls.

Third : implementation of this math seems overcomplicating problem :). If I understand correctly You only need 3 stable directions of bullets trajectory - UP, LEFT and RIGHT, and 5 pivots - UP, LOW ( LEFT, RIGHT), HIGH ( LEFT,RIGHT). I would introduce constant bulletvector var as Vector(1,0) and var facing as integer
1.on character direction change ( place you flip the sprite ) set facing to 1 or -1 accordingly
2.When one button is pressed :
pivot.position.x set to to your choice * facing
bulletvector = vector2(1,0) * facing
on status aimhigh : pivot.y set to some high position
on status aimlow : pivot.y set to some lowposition
3. When both buttons pressed - on status aimhigh :
pivot. position x and y set to your chosen upward position, independent from facing
bulletvector = (0,1)
4. On shoot :
bullet position = pivot position
bullet direction = bulletvector

Many thanks, friend! I’ll give it a look and try it out! :o)

Juanchoh | 2021-10-29 15:52