1. Hello Guest! It's with a heavy heart that we must announce the removal of the Legacy GMC Archive. If you wish to save anything from it, now's the time! Please see this topic for more information.
    Dismiss Notice

GMS 2 2D Hitscan

Discussion in 'Tutorials' started by Ratsha, Jan 17, 2019.

  1. Ratsha

    Ratsha Member

    Joined:
    Jun 22, 2016
    Posts:
    59
    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: Jan 18, 2019
    trg601 and Edwin like this.
  2. maybethatsyou

    maybethatsyou Member

    Joined:
    Aug 3, 2019
    Posts:
    7
    Free Godot have RayCast and this code in Godot have 3 lines...
     
  3. YellowAfterlife

    YellowAfterlife ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ Forum Staff Moderator

    Joined:
    Apr 21, 2016
    Posts:
    2,445
    ... and it takes other workarounds to implement place_meeting/position_meeting/instance_place/instance_position there. What was the point of the comment again?
     
    Bentley likes this.
  4. Lonewolff

    Lonewolff Member

    Joined:
    Jan 8, 2018
    Posts:
    1,207
    Great. :)

    This is a GameMaker forum though. You seem to be lost.
     
    Bentley likes this.

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice