collision_triangle

image

! NOTE: This function will eventually be replaced with a version that works more like the built-in collision_*() functions of Game Maker. It will return an instance id rather than the true or false value it returns now.

Downloadcollision_triangle(x1,y1,x2,y2,x3,y3,object)   Returns true if there is a collision between the given triangle and the given object or instance.
/*
**  Usage:
**      collision_triangle(x1,y1,x2,y2,x3,y3,object)
**
**  Arguments:
**      x1,y1     first point of triangle
**      x2,y2     second point of triangle
**      x3,y3     third point of triangle
**      object    an object or instance to check for collision
**
**  Returns:
**      (true) if there is a collision between the given
**      triangle and the given object, (false) otherwise
**
**  Notes:
**      Must be initialized with collision_triangle_init() before use.
**
**  GMLscripts.com
*/

{
    var x1,y1,x2,y2,x3,y3,object,xmin,xmax,ymin,ymax,d12,d13,d23,d14,d24,t,dx,dy,x4,y4;
    x1 = argument0;
    y1 = argument1;
    x2 = argument2;
    y2 = argument3;
    x3 = argument4;
    y3 = argument5;
    object = argument6;

    // Bounding box check
    xmin = min(x1,x2,x3);
    xmax = max(x1,x2,x3);
    ymin = min(y1,y2,y3);
    ymax = max(y1,y2,y3);
    if (not collision_rectangle(xmin,ymin,xmax,ymax,object,false,false)) return false;

    // Triangle perimeter check
    if (collision_line(x1,y1,x2,y2,object,true,false)) return true;
    if (collision_line(x1,y1,x3,y3,object,true,false)) return true;
    if (collision_line(x2,y2,x3,y3,object,true,false)) return true;

    // Find long side, make it (x1,y2) to (x2,y2)
    d12 = point_distance(x1,y1,x2,y2);
    d13 = point_distance(x1,y1,x3,y3);
    d23 = point_distance(x2,y2,x3,y3);
    switch (max(d12,d13,d23)) {
        case d13:
        t = x2; x2 = x3; x3 = t;
        t = y2; y2 = y3; y3 = t;
        d12 = d13;
        break;
        case d23:
        t = x1; x1 = x3; x3 = t;
        t = y1; y1 = y3; y3 = t;
        d12 = d23;
        break;
    }

    // From (x3,y3), find nearest point on long side (x4,y4).
    dx = x2 - x1;
    dy = y2 - y1;
    if ((dx == 0) && (dy == 0)) {
        x4 = x1;
        y4 = y1;
    }else{
        t = ((x3 - x1) * dx + (y3 - y1) * dy) / (d12 * d12);
        x4 = x1 + t * dx;
        y4 = y1 + t * dy;
    }

    // A line constructed from (x3,y3) to (x4,y4) divides
    // the original triangle into two right triangles.
    // Fit the collision mask into these triangles.
    d14 = point_distance(x1,y1,x4,y4);
    d24 = d12 - d14;
    with (global.objCollisionTriangle) {
        image_angle  = point_direction(x1,y1,x4,y4);
        image_xscale = d14 / size;
        image_yscale = point_distance(x3,y3,x4,y4) / size;
        if ((x1 > x4) xor (y3 < y4)) image_yscale *= -1;
        if (place_meeting(x4,y4,object)) return true;
        image_xscale = -d24 / size;
        if (place_meeting(x4,y4,object)) return true;
    }
    return false;
}
collision_triangle_init(size)   Must be called once before collision_triangle() can be used. It creates a collision mask of the given size. The larger the size, the more accurate collision_triangle() will be.
/*
**  Usage:
**      collision_triangle_init(size)
**
**  Arguments:
**      size      size of the test triangle in pixels
**                increase size to increase accuracy
**
**  Returns:
**      nothing
**
**  Notes:
**      Creates an object, a sprite, and a global variable called objCollisionTriangle
**
**  GMLscripts.com
*/

{
    if (not variable_global_exists("objCollisionTriangle")) {
        var color,object,size;
        size = argument0;
        object = object_add();
        object_set_persistent(object,true);
        object_event_add(object,ev_create,0,"size = "+string(size));
        global.objCollisionTriangle = instance_create(0,0,object);
        draw_clear_alpha(c_black,1);
        color = draw_get_color();
        draw_set_color(c_white);
        draw_triangle(size,size,size,0,0,0,false);
        draw_set_color(color);
        global.objCollisionTriangle.sprite_index =
        sprite_create_from_screen(0,0,size,size,true,true,false,true,size,0);
        global.objCollisionTriangle.visible = false;
    }
}

Comments? Click to Comment

Click if you've used this script[Please Login]
Projects: 5

 Contributors: Big J, xot

 History:
Mar 17, 2007 - xot submits the original script
Jul 27, 2009 - Big J spots a typo