GMS 2 2D Hitscan

Ratsha

Member
GM Version: GMS2
Target Platform: ALL
Download: N/A
Links: N/A

Summary:
How to implement hitscan in 2D games using collision_line().

Tutorial:
Code below for the hitscan code in Left Clicked Event.
This includes a fix (gun_direction) that accounts for the gun's slightly offset in the Sprite.
Code:
var gun_x = x + lengthdir_x(gunDistance, image_angle + gunAngle);
var gun_y = y + lengthdir_y(gunDistance, image_angle + gunAngle);
var gun_direction = point_direction(gun_x, gun_y, mouse_x, mouse_y);
var aimed_x = gun_x + lengthdir_x(500, gun_direction);
var aimed_y = gun_y + lengthdir_y(500, gun_direction);
instance_create_layer(gun_x, gun_y, "Instances", oMuzzleFlash);

var target = collision_line(gun_x, gun_y, aimed_x, aimed_y, oTarget, true, true);
if (target == noone) {
    effect_create_above(ef_smoke, aimed_x, aimed_y, 0, c_white);
} else {
    var contact_x = aimed_x;
    var contact_y = aimed_y;
    var percent_start = 0;
    var percent_end = 1;
    var distance_x = aimed_x - gun_x;
    var distance_y = aimed_y - gun_y;
    var iterations = ceil(log2(point_distance(gun_x, gun_y, aimed_x, aimed_y)))
    repeat (iterations) {
        var middle_way =  (percent_end - percent_start) * 0.5 + percent_start;
        var end_x = distance_x * middle_way + gun_x;
        var end_y = distance_y * middle_way + gun_y;
        var start_x = distance_x * percent_start + gun_x;
        var start_y = distance_y * percent_start + gun_y;
        var found = collision_line(start_x, start_y, end_x, end_y, oTarget, true, true);
        if (found == noone) {
            percent_start = middle_way;
        } else {
            target = found;
            contact_x = end_x;
            contact_y = end_y;
            percent_end = middle_way;
        }
    }
    if (target.object_index == oWall) {
        effect_create_above(ef_smoke, contact_x, contact_y, 0, c_white);
    } else if (target.object_index == oEnemy) {
        // hp reduction
        effect_create_above(ef_smoke, contact_x, contact_y, 0, c_red);
    }
}
 
Last edited:
Top