• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GameMaker [Solved] Trouble Aiming Projectiles with Gamepad

Papa Doge

Member
I'm working on some code that should create a projectile object on a dedicated Projectiles layer originating at the current location of the player. Then in the projectile's creation event, it should move in direction of the right analog stick's current angle.

Here's my code for creating the projectile which resides in the player's step event...

Code:
// if the player has not already thrown a projectile and they have released a projectile...
if (key_release_weapon) && (thrown == false) {
    // create a projectile and run it's create event...
    thrown = true;
    instance_create_layer(x,y,"Projectiles",obj_projectile);
}
Here's my code for aiming the projectile which resides in the projectile's create event...

Code:
direction = point_direction(x,y,gamepad_axis_value(0,gp_axisrh),gamepad_axis_value(0,gp_axisrv));
image_angle = direction;

// set the speed of the projectile in frames...
projectileSpeed = 16;
I was able to make this code work with mouse controls using mouse_x and mouse_y but it doesn't seem to be working properly with the gamepad and I'm not sure how to troubleshoot. I am printing the haxis and vaxis values of the right analog stick to the screen and I can see that the values are indeed changing as I rotate the stick but every time I fire, the projectile always moves diagonally up and left.
 

obscene

Member
If you set the direction relative to 0,0 it would be correct, but since you said point_direction(x,y,...); it's aiming from the current projectile position to some coordinate such as 0,0 0,1 -1,0 etc.
 
obscene is right and the fix is simple:
Code:
// if the player has not already thrown a projectile and they have released a projectile...
if (key_release_weapon) && (thrown == false) {
   // create a projectile and run it's create event...
   thrown = true;
   var proj = instance_create_layer(x,y,"Projectiles",obj_projectile);
   proj.direction = point_direction(x,y,gamepad_axis_value(0,gp_axisrh),gamepad_axis_value(0,gp_axisrv));
}
Just set the dir from the player instance, not the projectile instance.
 

obscene

Member
obscene is right and the fix is simple:
Code:
// if the player has not already thrown a projectile and they have released a projectile...
if (key_release_weapon) && (thrown == false) {
   // create a projectile and run it's create event...
   thrown = true;
   var proj = instance_create_layer(x,y,"Projectiles",obj_projectile);
   proj.direction = point_direction(x,y,gamepad_axis_value(0,gp_axisrh),gamepad_axis_value(0,gp_axisrv));
}
Just set the dir from the player instance, not the projectile instance.
No no your code is doing the same thing....

oint_direction(x,y,gamepad_axis_value(0,gp_axisrh),gamepad_axis_value(0,gp_axisrv));

That's going from x,y to something ranging from -1,-1 to 1,1. The resulting direction will always be up-left. You have to aim from 0,0 which is the value of the sticks at rest.

Example:

You push right and down. The stick reads 1,1. Getting the direction from 0,0 to 1,1 will return 315 (down-right).
 
Last edited:

Papa Doge

Member
If you set the direction relative to 0,0 it would be correct, but since you said point_direction(x,y,...); it's aiming from the current projectile position to some coordinate such as 0,0 0,1 -1,0 etc.
Awesome! That definitely works now.

However, I still don't fully understand what's happening, which doesn't sit right. I'll explain what I thought I was doing and you can help me understand where my thinking is wrong.

Looking at the documentation for point_direction() I understand that the first two arguments (x1,y1) create the origin point which is one of two points needed to draw a line. The second two arguments (x2,y2) create the destination point. When I was using the mouse, that was easy to understand because the location of the mouse was where I was aiming the projectile.

The Player (players_x_position,players_y_position) --------------------------------------> The Mouse (mouses_x_position,mouse_y_position)


----

Now with the controller if I was aiming straight to the right the haxis is 1 and the vaxis is 0.

The Player (0,0) ----------------------------------------> The Stick Angle (haxis,vaxis)

^ That makes no sense to me as it relates to the mouse controls because it reads "make the origin (0.0) which is the top left of the viewport" and then "make the destination (1,0) which is the space immediately to the right of (0,0)".

How does the projectile know to start from the player's current position?

How can I think about this differently?
 

obscene

Member
If you put a cursor to the right of your player and then return and angle from the player to the cursor, it will be to the right like you imagined. Because both of those are using coordinates.

Gamepad axis values have nothing to do with coordinates. An axis only has a value from -1 to 1. If your player is in the center of the screen, his coordinates might be 960,540. But if you press the stick right, it's 1. If you point from 960 to 1, it's going to be left. And if you press down, the Y axis will be 1. But if you point from 540 to 1, that's still going to be up.

You are effectively "cheating" the code by using point_direction and pretending 0,0 and axislh and axisrh are coordinates. It works the same, but it's simply calculating a tiny, 1-pixel-long line from 0,0 to 1,1.

The projectile is still starting from where you created it... x,y. You are only setting it's direction.
 
Top