drawingtrigonometrygame-maker-studio-2

Drawing a sprite on the circumference of a circle based on the position of other objects


I'm making a sniper shooter arcade style game in Gamemaker Studio 2 and I want the position of targets outside of the viewport to be pointed to by chevrons that move along the circumference of the scope when it moves. I am using trig techniques to determine the coordinates but the chevron is jumping around and doesn't seem to be pointing to the target. I have the code broken into two: the code to determine the coordinates in the step event of the enemies class (the objects that will be pointed to) and a draw event in the same class. Additionally, when I try to rotate the chevron so it also points to the enemy, it doesn't draw at all.

Here's the coordinate algorithm and the code to draw the chevrons, respectively

//determine the angle the target makes with the player
delta_x = abs(ObjectPlayer.x - x);  //x axis displacement
delta_y = abs(ObjectPlayer.y - y);  //y axis displacement
angle = arctan2(delta_y,delta_x);   //angle in radians
angle *= 180/pi                     //angle in radians

//Determine the direction based on the larger dimension and 
largest_distance = max(x,y);
plusOrMinus = (largest_distance == x)?
sign(ObjectPlayer.x-x) : sign(ObjectPlayer.y-y);

//define the chevron coordinates
chevron_x = ObjectPlayer.x + plusOrMinus*(cos(angle) + 20);
chevron_y = ObjectPlayer.y + plusOrMinus*(sign(angle) + 20);

The drawing code

if(object_exists(ObjectEnemy)){
    draw_text(ObjectPlayer.x, ObjectPlayer.y-10,string(angle));
    draw_sprite(Spr_Chevron,-1,chevron_x,chevron_y);
    //sSpr_Chevron.image_angle = angle;
}

Solution

  • Your current code is slightly more complex that it needs to be for this, if you want to draw chevrons pointing towards all enemies, you might as well do that on spot in Draw. And use degree-based functions if you're going to need degrees for drawing anyway

    var px = ObjectPlayer.x;
    var py = ObjectPlayer.y;
    with (ObjectEnemy) {
        var angle = point_direction(px, py, x, y);
        var chevron_x = px + lengthdir_x(20, angle);
        var chevron_y = py + lengthdir_y(20, angle);
        draw_sprite_ext(Spr_Chevron, -1, chevron_x, chevron_y, 1, 1, angle, c_white, 1);
    }
    

    (also see: an almost-decade old blog post of mine about doing this while clamping to screen edges instead)

    Specific problems with your existing code are: