• 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!

Using "clamp" with Image_angle

S

SupaTroopaAlpha

Guest
Hi everyone,

Im having trouble restricting my players gun angle. whether he is facing left or right he can aim the gun behind him even though he isn't facing that direction. I would like to restrict oGun to only aiming between 150 and 210 while he is facing left and 30 and 330 while facing right. When he faces left it works perfectly fine. But if he is facing right then object gun aims everywhere but in between angles 30 and 330. I tried switching the order, making negatives, median and means, but nothing works. I am extremely new to programing and using gamemnaker. Any insight will be much appreciated. Thanks!

in oGun's step event :

//This part is working perfectly

if(oPlayer.image_xscale == -1)
{
image_angle = clamp(image_angle,150,210)
}


//This part has the angle of the gun aim everywhere but in between 330 and 30.

if(oPlayer.image_xscale == 1)
{
image_angle = clamp(image_angle,330,30)
}
 
the cause of this is the transition from 360 to 0 degrees.

what you can do is find the difference between the angle your character is facing and to the direction the gun is facing. Then clamp that difference. Then add that difference back to the angle your character is facing. Example:

Code:
var _mouse_angle = point_direction( x, y, mouse_x, mouse_y );
var _difference_angle = clamp(angle_difference( _mouse_angle, character_angle ), -constraint, constraint );
gun_angle = character_angle + _difference_angle;
 

Ubu

Member
Or since Game Maker understands degrees larger than 360 you can use:
image_angle = clamp(image_angle,330,390)
 
S

SupaTroopaAlpha

Guest
I tried
Code:
image_angle = clamp(image_angle,330,390)
it would work between 330 and 0 then if I aimed above 0 degrees it would snap back down to 330.


Then I also tried this but it didn't work. I doubt this is correct, kinda confused about the character angle and gun angle and finding the difference.
Code:
var character_angle = oPlayer.image_xscale
var mouse_angle = point_direction(x,y,mouse_x,mouse_y);
var difference_angle = clamp(angle_difference(mouse_angle,character_angle), -330, 30 );
image_angle = character_angle + difference_angle;
Maybe I shouldn't attempt doing this if its too challenging for my "coding" level lol. I always wanna try and do more than I can handle.
 

CMAllen

Member
You need to convert oPlayer.image_xscale into an angle. Fortunately, since the player can only 'face' two directions, the angle is either 0 (right) or 180 (left), so precomputing that value is fine.
Code:
var character_angle = 0
if (oPlayer.image_xscale == 1) { character_angle=180 };
var mouse_angle = point_direction(x,y,mouse_x,mouse_y);
var difference_angle = clamp(angle_difference(mouse_angle,character_angle), -30, 30 );
image_angle = character_angle + difference_angle;
Note: If you ever intend to allow your character to 'shrink' and be less than 1.0 in scale, you'll have to check the sign() value of image_xscale for this code block to work properly.

(I did a programming no-no. Never use a single '=' for a comparison test)
 
Last edited:

Ubu

Member
Hmm, sorry about that, was convinced that would work...

Well, if you're using mouse aiming for the gun you could just make your own "clamp":

Code:
var mouse_angle = point_direction(x, y, mouse_x, mouse_y);
if (mouse_angle > 330 || mouse_angle < 30)
   image_angle = mouse_angle;
 

Yal

🐧 *penguin noises*
GMC Elder
Hmm, sorry about that, was convinced that would work...
It normally would work, but image_angle (and direction) is clamped between 0 and 360. Also, an angle of 390 is not equal to an angle of -30, and an angle of 390 + 360 isn't equal either. They just happen to represent the same direction, but the values won't compare equal.

I'd recommend something like this to clamp an angle instead:
Code:
if(abs(angle_difference(0,image_angle)) > 30){
  image_angle = 0 + 30*sign(angle_difference(0,image_angle));
}
(in this case 0 is the center angle you want to snap around)
 
V

Vintage GameArtist

Guest
Did anyone come up with the right answer? I want the gun angle to be limited and to point in same the direction the oPlayer is walking. So instead of this: image_angle = point_direction (x,y,mouse_x,mouse_y);
I want something that will stop the players arm from rotating unnaturally and flip it to the direction the player is facing.
 
Last edited by a moderator:

Bearman_18

Fruit Stand Deadbeat
Code:
if mouse_check_button_pressed(mb_left) {
     if image_xscale = 1 {
     bullet = instance_create(x,y,obj_Bullet);
     bullet.direction = point_direction(bullet.x,bullet.y,mouse_x,mouse_y);
          if (bullet.direction > 90) && (bullet.direction < 180) {
          bullet.direction = 90;
          }
          if (bullet.direction >= 180) && (bullet.direction < 270) {
          bullet.direction = 270;
          }
     }
     if image_xscale = -1 {
     bullet = instance_create(x - 1,y,obj_Bullet);
     bullet.direction = point_direction(bullet.x,bullet.y,mouse_x,mouse_y);
     bullet.direction = clamp(bullet.direction,90,270);
     }
}
So, this code runs in the gun object. Everything is based on whether the image _xscale is 1 (facing right) or -1 (facing left). The xscale is based on the player's xscale. THis code makes sure that the bullet created is restricted to straight up and down, everything in between, but not behind the player. You could also apply this to the gun's image_angle, but every frame, not just when you have pressed mb_left. As you can see, I used two if statements when facing right, and a clamp when facing left. There is probably a better way to do this. The code should make it easy to restrict the possible directions further. Hope this helps!
 
Code:
// Left Aim Angle Restrictions

if (oPlayer.image_xscale = -1)
{
image_angle = clamp(image_angle,150,210)
}

// Right Aim Angle Restrictions

if (oPlayer.image_xscale = 1) and (image_angle > 0) and (image_angle < 90)
{
image_angle = clamp(image_angle,0,30)
}

if (oPlayer.image_xscale = 1) and (image_angle > 270) and (image_angle < 360)
{
image_angle = clamp(image_angle,330,360)
}
This may be irrelevant now, yet there was a simple solution the whole time.
Since setting a min thats higher than the max glitches out the aiming, you need to set two "if" statements, one dealing with > 0 and one dealing with < 360.
 
Last edited:

Yal

🐧 *penguin noises*
GMC Elder
angle_difference could also be useful, since it takes equivalent angles into account (e.g. 365 and 5 degrees will have angle difference of zero).

For instance, restricting aim to straight up or down would be done like this:
GML:
if(  abs(angle_difference(0,image_angle)) > 90){
  image_angle = 90*sign(angle_difference(0,image_angle))
}
 
Top