How to fade image_alpha as you walk further from object

Discussion in 'Programming' started by Pkirkby, Jun 5, 2019.

  1. Pkirkby

    Pkirkby Member

    Joined:
    Mar 25, 2019
    Posts:
    103
    Hi everyone, as you can see from my image I have a simple light source. It's effective in drawing my shadow based on the placement of the light object. However, given my code I can't figure out how to properly fade the image_alpha out as I walk further from the light source. Here's the code I use:

    var sx = oLighting.x - x;
    var sy = oLighting.y - y;
    //var light_xy = sx + sy;


    //Draw Shadow

    gpu_set_fog(true,c_black,0,1);
    draw_sprite_pos(sprite_index,image_index,
    x-(sprite_width/2)-sx,
    y-sy,
    x+(sprite_width/2)-sx,
    y-sy,
    x+(sprite_width/2),
    y,
    x-(sprite_width/2),
    y,
    image_alpha);

    I've come close with some equations that update the alpha based on the x/y coordinates of the light source, but I'm too noobish in GML to figure this one out. Also, I've looked into the "clamp" function, this was on YoYo's website:

    image_alpha = clamp(image_alpha - 0.01, 0, 1);

    The above code will slowly reduce the image_alpha until it reaches 0.

    Surely there must be a way to do this with clamp?

    EDIT: Now I've got it working, HOWEVER I'm trying to make it so everywhere I place this "oLighting" object, I'd like it to cast a separate "shadow" and I can't seem to accomplish this.
     

    Attached Files:

    Last edited: Jun 11, 2019
  2. obscene

    obscene Member

    Joined:
    Jun 21, 2016
    Posts:
    2,399
    Use point_distance() to find the distance between two points
    Set the variable max_distance to distance at which alpha should be 0.

    image_alpha=1-(actual_distance/max_distance);
     
    Nocturne and Bentley like this.
  3. Pkirkby

    Pkirkby Member

    Joined:
    Mar 25, 2019
    Posts:
    103
    Ok, so let's say my light source is called (oLight) How would I go about implementing that into my current code? Thanks for a fast response!
     
  4. MikeeyBikeey

    MikeeyBikeey Member

    Joined:
    Aug 24, 2017
    Posts:
    5
    I got this to work in Gamemaker Studio 1.4.9999:
    Code:
    // if `distance` is below `min_distance` then the instance is fully visible
    var min_distance = 32;
    var max_distance = 256;
    var distance = point_distance(oLighting.x, oLighting.y, x, y);
    image_alpha = 1 - clamp((distance - min_distance) / (max_distance - min_distance), 0, 1);
    
    var sx = oLighting.x - x;
    var sy = oLighting.y - y;
    
    //Draw Shadow
    
    // gpu_set_fog(true,c_black,0,1);
    draw_sprite_pos(
        sprite_index,
        image_index,
        x - sprite_width / 2 - sx,
        y-sy,
        x + sprite_width / 2 - sx,
        y-sy,
        x + sprite_width / 2,
        y,
        x - sprite_width / 2,
        y,
        image_alpha);
    
     
  5. Pkirkby

    Pkirkby Member

    Joined:
    Mar 25, 2019
    Posts:
    103
    You're the best, I'm gonna try that tonight and see if I can make it work, thanks a lot!
     
  6. Pkirkby

    Pkirkby Member

    Joined:
    Mar 25, 2019
    Posts:
    103
    Damn, I'm not sure what I'm doing wrong, is that exactly as you did it to get it work?
     
  7. Pkirkby

    Pkirkby Member

    Joined:
    Mar 25, 2019
    Posts:
    103
    Nev
    Nevermind, I got it!!! Dude, you've solved an issue I've been struggling with for weeks lol. Thanks again!
     
  8. Pkirkby

    Pkirkby Member

    Joined:
    Mar 25, 2019
    Posts:
    103
    Here's another question for you, when I make this an object, it only affects things in one instance, if I put multiple of these objects, they dont make individual shadows on the objects. Would you know a way around that?
     
  9. obscene

    obscene Member

    Joined:
    Jun 21, 2016
    Posts:
    2,399
    Sounds like you have one object to run the effect, right?

    Best way to run code for multiple instances is something like this...

    with (obj_name) { do stuff }

    This will cause every obj_name to run the following code all at once.

    So with multiple lights and multiple shadowcasters you might end up with something like this...

    Code:
    with (obj_light)
       {
       // save the lights position to temporary variables
       var xx=x;
       var yy=y;
       
       with (obj_shadowcaster)
              {
              // get distance from x,y to xx,yy and draw the shadows at x,y
              }
       }
    
     
    Yal likes this.
  10. Pkirkby

    Pkirkby Member

    Joined:
    Mar 25, 2019
    Posts:
    103
    Actually I already have it affecting any objects in my associated with my oParent, my problem is that I want this code to affect all "lamps" for example. So I want to place a bunch of "lamps" and have a shadow draw for each lamp's light source. But as of right now, it only seems to draw one. Thanks again for your reply.
     
  11. obscene

    obscene Member

    Joined:
    Jun 21, 2016
    Posts:
    2,399
    That's where "with" comes in. If you write with(obj_lamp) every lamp runs the code. Not sure if your code is in your shadowcaster objects or in a controller object, but in either case that's the way to approach it.

    In your code in your first post, you are just saying...

    var sx = oLighting.x - x;
    var sy = oLighting.y - y;

    But that will only get one light.

    This will get them all...

    Code:
    with (oLighting)
       {
       var sx=x; // this code is running from the perspective of each light instance, so simply get x and y.
       var sy=y;
       with (oParent)
          {
          // draw your shadow here for each object as you did before.
          }
       }
    
     
  12. Pkirkby

    Pkirkby Member

    Joined:
    Mar 25, 2019
    Posts:
    103
    Yeah, I didn't post my with statement, it currently has a "with (oParent)" to affect all objects controlled by my parent object. But Im going to try that tonight, it's kind of what I was thinking but it's nice to see it from someone more experienced. Thanks a lot for your help!
     
  13. Pkirkby

    Pkirkby Member

    Joined:
    Mar 25, 2019
    Posts:
    103
    So I tried that, but it seems that if I remove the "sx = oLighting.x - x;" it won't update the shadow based on the position of the object, it just fixes it. I can't seem to have each light source affect each object.

    While we're here, I'm trying to apply an if statement of similar effect, where as my zsp (my jumping height) increases, the shadow size decreases. I should be able to use a similar statement, but how would you go about it?
     
  14. Pkirkby

    Pkirkby Member

    Joined:
    Mar 25, 2019
    Posts:
    103
  15. obscene

    obscene Member

    Joined:
    Jun 21, 2016
    Posts:
    2,399
  16. Pkirkby

    Pkirkby Member

    Joined:
    Mar 25, 2019
    Posts:
    103
    This is a Top-down style game, as of right now I have "oLighting" working and affecting all objects, I just cant place more than one "oLighting" and have multiple shadows cast from each source. Here's my current code:

    with(oParent)
    {
    //variables for shadows
    var min_distance = 2;
    var max_distance = 150;
    var distance = point_distance(oLamp.x, oLamp.y+z, x, y+z);
    var shadow_alpha = 1 - clamp((distance - min_distance) / (max_distance - min_distance), 0, 1);
    var shadow_distance = 1 - clamp((distance - min_distance) / (max_distance - min_distance), 0, 1);

    var sx = oLamp.x - x;
    var sy = oLamp.y - y;

    //Draw Shadow


    gpu_set_fog(true,c_black,0,1);
    draw_sprite_pos(
    sprite_index,
    image_index,
    x - sprite_width / 2 - sx,
    y-sy,
    x + sprite_width / 2 - sx,
    y-sy,
    x + sprite_width / 2,
    y,
    x - sprite_width / 2,
    y,
    shadow_alpha);


    //draw_sprite_ext(sprite_index,image_index,x-5,y-5,image_xscale,image_yscale,0,c_black,0.5);

    //This sets fog to disable,white is default.
    gpu_set_fog(false,c_white,0,0);


    }
     
  17. MikeeyBikeey

    MikeeyBikeey Member

    Joined:
    Aug 24, 2017
    Posts:
    5
    I got this to work:
    Code:
    // gpu_set_fog(true,c_black,0,1);
    
    with(oLighting) // assuming all `oLighting` instances cast light
    {
        // jumping (z)
        var cast_dir = point_direction(x, y, other.x, other.y);
        var xcast = lengthdir_x(other.z, cast_dir) + other.x;
        var ycast = lengthdir_y(other.z, cast_dir) + other.y;
    
        // variables for shadows
        var min_distance = 2;
        var max_distance = 150;
        var distance = point_distance(x, y, xcast, ycast);
        var shadow_alpha = 1 - clamp((distance - min_distance) / (max_distance - min_distance), 0, 1);
        var shadow_distance = 1 - clamp((distance - min_distance) / (max_distance - min_distance), 0, 1);
       
        var sx = x - xcast;
        var sy = y - ycast;
       
        // draw shadow
        draw_sprite_pos(
            other.sprite_index,
            other.image_index,
            xcast - other.sprite_width / 2 - sx,
            ycast - sy,
            xcast + other.sprite_width / 2 - sx,
            ycast - sy,
            xcast + other.sprite_width / 2,
            ycast,
            xcast - other.sprite_width / 2,
            ycast,
            shadow_alpha);
    }
    
    // This sets fog to disable, white is default.
    // gpu_set_fog(false,c_white,0,0);
    
    As your `z` increases the shadow should appear farther away.
     
  18. Pkirkby

    Pkirkby Member

    Joined:
    Mar 25, 2019
    Posts:
    103
    Awesome, I'm going to try tomorrow. Appreciate the response!
     
  19. Pkirkby

    Pkirkby Member

    Joined:
    Mar 25, 2019
    Posts:
    103
    Ok, so I fooled around with it, I am trying to make sense of it. What's the "other" object and how is it controlled? Seems I get an issue with the "object.z" right off the bat.
     
  20. obscene

    obscene Member

    Joined:
    Jun 21, 2016
    Posts:
    2,399
  21. Pkirkby

    Pkirkby Member

    Joined:
    Mar 25, 2019
    Posts:
    103
    Anyone have any more suggestions? I've read up on With but I still can't seem to have all objects "oLamp" draw shadow, only the most recent "oLamp" will affect other objects. I have my "oLighting" affecting my "oParent" which essentially affects everything that should cast a shadow, and I made oLamp the reference point in which the light is cast. As you can see from the screenshot, light is casting from the right lightsource but wont from the left. Here's my code, any help would be amazing, thanks!



    with(oParent)
    {
    //variables for shadows
    var min_distance = 2;
    var max_distance = 150;
    var distance = point_distance(oLamp.x, oLamp.y, x, y);
    var shadow_alpha = 0.8 - clamp((distance - min_distance) / (max_distance - min_distance), 0, 0.8);

    var sx = oLamp.x - x;
    var sy = oLamp.y - y;

    //Draw Shadow


    gpu_set_fog(true,c_black,0,1);
    draw_sprite_pos(
    sprite_index,
    image_index,
    x - sprite_width / 2 - sx,
    y-sy,
    x + sprite_width / 2 - sx,
    y-sy,
    x + sprite_width / 2,
    y,
    x - sprite_width / 2,
    y,
    shadow_alpha);



    //draw_sprite_ext(sprite_index,image_index,x-5,y-5,image_xscale,image_yscale,0,c_black,0.5);

    //This sets fog to disable,white is default.
    gpu_set_fog(false,c_white,0,0);

    }
     

    Attached Files:

    • ss.jpg
      ss.jpg
      File size:
      53.5 KB
      Views:
      2

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