Use light to trigger events

A

AquaticChaos

Guest
I am looking for a way to draw dynamic shadows/lights that can affect other objects, such as keeping enemies away or activating switches. I've tried looking for tutorials on such things for GMS, and at one point I found one for Unity. However, I feel much more confident in using GMS, as I've used it plenty more than Unity.

Anyway, let's say that there's an enemy that must stay away from a light level over 50% in order to reach the player. It'll have to pathfind its way around the darkness to reach the player.

For another example, several switches must be hit with light at the same time in order to open a door. These switches, like before, must have a light level over 50% to activate.
 

lolslayer

Member
What you're trying to do is extremely complicated and I hope you know what you're getting into.

You need to use the information on the light surface for this. But you need a way to get the data of a pixel on the surface, gamemaker built-in function for that is really slow so I would recommend giving this Marketplace item by Misu a look:
https://marketplace.yoyogames.com/assets/5344/buffer_getpixel

Now you can use surface data. So for the switches question, for every switch, you check at what pixel on the light surface the center of the switch is found. On that pixel you check the data and if the light level is over 50% it will be activated.

Pathfinding will be much harder, you could use the shaders to create a version of the light surface where everything with a light level above 50% has an alpha value of 1, and everything below one with 0. Then you will go on to use a mp_grid for pathfinding. When setting up the mp_grid, you first assign the surface to a sprite that you assign to an object. Than you assign the object to the grid using this function: mp_grid_add_instances() (Make sure that prec is set on true!). Now you'll have a pthfinding grid where only the grid cells that are completely in >50% light level will be used.

You could also make your own waypoint or navmesh pathfinding system and check on every waypoint/navpoint's pixel on the light surface if it's in a light level above 50% or not.

I hope that I could explain it to you well enough, PM me for any further questions if you want.
 
A

AquaticChaos

Guest
Wow, talk about crazy coding! I'll try it for now, but can I ask if the link is for GMS 1.4 or 2? I sadly don't have 2.

EDIT: Yeah, unfortunately it's for GMS 2. That's a shame.
 
A

AquaticChaos

Guest
Thanks, I really do appreciate it! For now I'll work on the other parts of my game.
 
A

AquaticChaos

Guest
Wait seriously? That's handy! I'll take a look

ANOTHER EDIT: What would be a good asset, or what should I search?
 
Last edited by a moderator:

Yal

🐧 *penguin noises*
GMC Elder
@Dark made a "sampler" resource a while ago that could be useful, it's a faster way to get color data from a surface than surface_getpixel. Check out her postings and select 'topics only' and it should hopefully be easy to find (now when I think about it I don't remember if she moved it over to the new GMC when we changed forum software last year). I use it myself in a bunch of projects, so I can vouch for its usefulness~
 
A

AquaticChaos

Guest
Yeah, unless I'm being a complete derp I don't see it in the postings list. Sorry if I'm making it difficult, this is probably one of my first topics in the forums. Plus I don't come here much.
 
A

AquaticChaos

Guest
Alrighty, so I downloaded the scripts Yal linked, now to just use them
 
A

AquaticChaos

Guest
After much thought, I decided to use the system found here (
) for the lighting. Hopefully this will work!
For now, I'm gathering ideas on puzzle gimicks in my game. I only need two or three more, since the first gimmick is this.
 
A

AquaticChaos

Guest
Funny you say that, last night I bought that exact source. Though, I am having trouble with a global._light variable, as it says it doesn't exist. At the moment though I'm away from my computer which I'm coding on. I'll post the error when I have a chance.
 

muki

Member
there are multiple systems and questions you need to address. do you have a design document?

first there's the lighting. you need to ask yourself what art direction you're going for. cartoonish or semi-realistic. are you content with a linear/square mathematical falloff or do you want to do it with sprites and additive blending modes? then you have to ask yourself whether you want shadows. if so, what kind, tile-based (like many exampels out there)? or cast off of complex sprites? again dependent on your art direction.

then there's the enemy AI which would be a completely different system. if your lights are simple points or sprites, then an AI routine that checks for proximity isn't too hard. but if your lights are casting shadows, things get way more complicated.

this is why it's good to have a design document before you start.
 

lolslayer

Member
there are multiple systems and questions you need to address. do you have a design document?

first there's the lighting. you need to ask yourself what art direction you're going for. cartoonish or semi-realistic. are you content with a linear/square mathematical falloff or do you want to do it with sprites and additive blending modes? then you have to ask yourself whether you want shadows. if so, what kind, tile-based (like many exampels out there)? or cast off of complex sprites? again dependent on your art direction.

then there's the enemy AI which would be a completely different system. if your lights are simple points or sprites, then an AI routine that checks for proximity isn't too hard. but if your lights are casting shadows, things get way more complicated.

this is why it's good to have a design document before you start.
Tbh, you're making it overcomplicated for a small thing like this. First he should just try to get the systems working before worrying about art-styles.

He'll know if there will or won't be shadows.
 
W

Wraithious

Guest
There is a nice and easy lighting system tutorial video someone posted on this thread , and once you implement it you can just use the size variable you set in the create event of the object emitting the light and the distance the enemy is to the light emitting object. If the enemy is within this range you can have him stop or retreat.

And for the other thing you wanted to do with the 50% light value statement can be calculated by adding up the 3 values that you are feeding to your make_color_rgb function's variable that's getting passed to the draw_set_color(my_color) statement in the lighting controller object's step event, then divide that result by 3 and compare that result with the number 128 (because 255/2 = 127.5)
so to picture this say you have 3 variables named red, green, and blue. and say value red is 100, green is 100, and blue is 100. so then you make your color like my_color=make_color_rgb(red,green,blue) ;

so now take those red, green and blue variables and add them together and then divide the result by 3, and in this case the final result is 100. 100 is less than 128 so you know that your light level is under 50%.
hope this helps!

EDIT: Oh and in that tutorial video he forgot one VERY VERY important thing, in the draw event of the light controller make sure you check if the surface exists or your game will crash! (such as if you switch from full screen to windowed mode in game, or load a saved game, in these cases you have to re-create the surface)
Code:
if(surface_exists(light))
{draw_set_blend_mode(bm_subtract);
draw_surface(light,view_xview,view_yview);
draw_set_blend_mode(bm_normal);
}
 
Last edited by a moderator:
A

AquaticChaos

Guest
Alrighty, I'll take a look at this when I get home. Sounds pretty easy to implement actually!
 
A

AquaticChaos

Guest
So I've been on and off with my game, and I was wondering how to make the light over the light sources only activate if the obj_lighting instance exists. I'll see if I can try it myself, while I'm at it.
 

Yal

🐧 *penguin noises*
GMC Elder
So I've been on and off with my game, and I was wondering how to make the light over the light sources only activate if the obj_lighting instance exists. I'll see if I can try it myself, while I'm at it.
Interpreting your question at face value:
Code:
if(instance_exists(obj_lighting)){
  //existing code here
}
Then again, wasn't obj_lighting the instance that drew everything in the first place? It not being there should just result in nothing happening anyway...
 
Top