|
|
|
 |
Reply From: |
njamster |
While i know how to detect if its pointed up, down, right, or left […] i’m not sure how to find the other directions
The other directions are just combinations of the four basic ones (I called those actions stick_right
, stick_left
, stick_down
and stick_up
here):
var direction = Vector2()
direction.x = int(Input.is_action_pressed("stick_right")) - int(Input.is_action_pressed("stick_left"))
direction.y = int(Input.is_action_pressed("stick_down")) - int(Input.is_action_pressed("stick_up"))
Note that the diagonal directions will be longer than the basic ones. While that does not matter, when you’re only interested in the direction, it does matter when you use the Vector2 as a means to express speed. In that case, use direction.normalized()
!
what exactly does the int()
function do, I’ve never seen it before. I assume that it’s returning an integer form of the Input?
Millard | 2020-09-28 16:45
also, would this code require the player to move the joystick in exactly the right direction, or would it allow leeway like it’s supposed to?
Millard | 2020-09-28 16:54
ok, i have written this code for detecting the aiming.
var aim_left = Input.is_action_pressed("aim_left")
var aim_left_up = int(Input.is_action_pressed("aim_left")) - int(Input.is_action_pressed("aim_up") )
var aim_left_down = int(Input.is_action_pressed("aim_left")) - int(Input.is_action_pressed("aim_down") )
var aim_right = Input.is_action_pressed("aim_right")
var aim_right_up = int(Input.is_action_pressed("aim_right")) - int(Input.is_action_pressed("aim_up") )
var aim_right_down = int(Input.is_action_pressed("aim_right")) - int(Input.is_action_pressed("aim_down") )
var aim_up = Input.is_action_pressed("aim_up")
var aim_down = Input.is_action_pressed("aim_down")
and this for testing it.
if aim_left:
print("aiming left")
if aim_left_up:
print("aiming left up")
if aim_left_down:
print("aiming left down")
if aim_right:
print("aiming right")
if aim_right_up:
print("aiming right up")
if aim_right_down:
print("aiming right down")
if aim_down:
print("aiming down")
if aim_up:
print("aiming up")
this almost sort of works, but it’s obviously not quite right. (and I didn’t think it would be).
so, if you could look at it and see what i’m doing wrong, or what I should do that would be great. 
thanks for your answer!
Millard | 2020-09-28 17:21
what exactly does the int() function do, I’ve never seen it before. I assume that it’s returning an integer form of the Input?
Correct. It converts the return value of Input.is_action_pressed()
which happens to be a boolean (i.e. either true and false) into an integer (where true
becomes 1
and false
becomes 0
). In more general terms this is called a “type-cast”. Because variables in GDscript have no fixed type by default, you won’t encounter it often, but if you program in a strongly-typed-language like e.g. C# you’ll use it all the time. 
also, would this code require the player to move the joystick in exactly the right direction, or would it allow leeway like it’s supposed to?
That’s where the so-called “dead-zone” comes into play. You can set it individually for each input action and it defaults to 0.5, which means an axis input will be recognized once you push it over 50% of the maximum value, but not below that. So you don’t have to hit an exactly specified spot, but instead need to apply enough force to pass over the dead-zone of both input actions to make the player walk diagonally.
If you prefer that, you can also work with the exact axis values instead:
const DEVICE_ID = 0
const DEADZONE = 0.5
const FACTOR = 1
func _physics_process(delta):
var input_direction = Vector2()
input_direction.x = Input.get_joy_axis(DEVICE_ID, JOY_ANALOG_LX)
input_direction.y = Input.get_joy_axis(DEVICE_ID, JOY_ANALOG_LY)
if input_direction.length() > DEADZONE:
var input_angle_in_degrees = rad2deg(input_direction.angle())
# rounds the input angle to the next multiple of 45
var dir = int(round(input_angle_in_degrees/45.0)*45)
var move_direction
match dir:
0:
move_direction = Vector2( 1, 0)
-45:
move_direction= Vector2( 1, -1).normalized()
-90:
move_direction= Vector2( 0, -1)
-135:
move_direction= Vector2(-1, -1).normalized()
-180, 180:
move_direction= Vector2(-1, 0)
135:
move_direction= Vector2(-1, 1).normalized()
90:
move_direction= Vector2( 0, 1)
45:
move_direction= Vector2( 1, 1).normalized()
njamster | 2020-09-28 17:44
Regarding the code that you’ve written, e.g.:
var aim_left_up = int(Input.is_action_pressed("aim_left")) - int(Input.is_action_pressed("aim_up") )
if aim_left_up:
print("aiming left up")
This will be either…
- 1, if
aim_left
is pressed (i.e. true/1
) but aim_down
isn’t (i.e. false/0
)
- -1, if
aim_down
is pressed (i.e. true/1
) but aim_left
isn’t (i.e. false/0
)
- 0 if both
aim_down
and aim_left
are pressed (i.e. true/1
)
However, that’s clearly not what you want! If you want to do it this way, you’d do:
var aim_left_up = Input.is_action_pressed("aim_left") and Input.is_action_pressed("aim_up")
if aim_left_up:
print("aiming left up")
The solution that I initially provided you with already gives you the direction, though it’s in Vector2-form. So you could also do something like this:
var direction = Vector2()
direction.x = int(Input.is_action_pressed("stick_right")) - int(Input.is_action_pressed("stick_left"))
direction.y = int(Input.is_action_pressed("stick_down")) - int(Input.is_action_pressed("stick_up"))
if direction == Vector2(-1, 1):
print("aiming left up")
njamster | 2020-09-28 17:59
Ok, I implemented the code you last added:
var direction = Vector2()
direction.x = int(Input.is_action_pressed("stick_right")) - int(Input.is_action_pressed("stick_left"))
direction.y = int(Input.is_action_pressed("stick_down")) - int(Input.is_action_pressed("stick_up"))
if direction == Vector2(-1, 1):
print("aiming left up")
(I also added the code checking all the other directions, not just left up)
And it works fine, except it doesn’t have deadzone.
So I am next going to use the deadzone code you implemented earlier, however first i need to understand a few things more. 
input_direction.x = Input.get_joy_axis(DEVICE_ID, JOY_ANALOG_LX) input_direction.y = Input.get_joy_axis(DEVICE_ID, JOY_ANALOG_LY)
Is this unnecessary with the code i have? I’m pretty sure my code is already doing this just differently.
var dir = int(round(input_angle_in_degrees/45.0)*45)
not quite sure what this is doing, could you explain?
and finally:
match dir:
pretty sure i’ve learned this somwhere before, but I haven’t done a lot of coding so I’m not sure what kind of statement this is.
Thanks so much for your help, and I totally get it if you don’t want to answer all this. 
Millard | 2020-09-28 19:13
I’m pretty sure my code is already doing this just differently.
Well, get_joy_axis
will return a float-value between 0.0 and 1.0 depending on how hard you’re pushing the stick into the given direction. Whereas is_action_pressed
will be either true
(i.e. 1) or false
(i.e. 0), but never something in between! What’s more appropriate to use depends on what exactly you’re trying to achieve. But yes, both share the common goal of finding out if the stick is pushed here.
not quite sure what this is doing, could you explain?
As the comment above that line already states, it “rounds the input angle to the next multiple of 45”. In order to do so, it first takes the value of input_angle_in_degrees
and divides it by 45, the result of which will be a float that tells you how often you can fit 45 into input_angle_in_degrees
e.g. 49.5/45 would be 1.1 and 85.5/45 would be 1.9. It then rounds these floats to the nearest whole number - so to stay with our examples round(1.1) == 1.0
and round(1.9) == 2.0
. Now all that’s left to do for us is to multiply it again by 45 and we’ll end up with 45 and 90 - both multiples of 45! Casting it into an integer isn’t actually necessary here, but without it you need to use floats inside the match-statement as well - so I chose the lazy route. 
Btw, the halfway case is always rounded up: round(1.5) == 2.0
.
what kind of statement this is
The match-statement (check out the documentation!) is a way of re-writing a set of if-statements for which you know in advance that it’s not possible to meet more than one condition at the same time anyway! So instead of writing the following:
if counter == 1:
print("It's a 1!")
elif counter == 2:
print("It's a 2!")
elif counter == 3:
print("It's a 3!")
you can also write it like that:
match counter:
1:
print("It's a 1!")
2:
print("It's a 2!")
3:
print("It's a 3!")
njamster | 2020-09-29 20:22
ok, I implemented it and it appears to be working! I’m using the is_action_pressed
because it’s being used for directional aiming and a boolean makes more sense.
It might just be an illusion, but it seems like it’s a lot less forgiving when aiming down-left than when its aiming down-right. It’s likely just the difference in motion of my thumb, but have you experienced this before?
Thanks so much, for the help, I know it must have taken a lot of time!

Millard | 2020-09-29 23:22