As requested, I’d like to do a quick entry about simple lighting systems in Game Maker Studio. The following does not use any extensions or complex code. All you will need is a controller object and some basic knowledge of how surfaces work in Game Maker.
Instead of going to far in depth about this, I’ll just show you what I’m doing and I’ll let you do some further research if you’d like to accomplish more with your lighting system.
To begin, you will need an object that will handle your lighting. In my project, I call it ‘objDarkRoom’ because it actually makes the room dark as well as handling the light sources.
CREATE EVENT
// Create a surface the size of the current room
// You could also create a surface the size of the current view, but I won't get into that
surf = surface_create(room_width, room_height);
// The following two lines clear the surface
// There is no guarantee that the surface doesn't contain garbage info post-creation
surface_set_target(surf);
draw_clear_alpha(c_black, 0);
// Reset to application surface
surface_reset_target();
STEP EVENT
// Surfaces are volatile
// Always check that they haven't been destroyed
if (surface_exists(surf)) {
surface_set_target(surf);
// The following three lines set the 'dark' overlay
draw_set_color(c_black);
draw_set_alpha(0.8);
draw_rectangle(0, 0, room_width, room_height, 0);
// Setting the blend mode to 'subtract' is what allows us to "cut holes" out of the overlay
draw_set_blend_mode(bm_subtract);
draw_set_color(c_white);
// Draw circles in the overlay with your different light sources
// Note that I add randomization to the position and radius to mimic a flicker effect
with (oLantern)
draw_circle(x + random_range(-1, 1), y + random_range(-1, 1), 30 + random_range(-1, 1), false);
with (oParticleLantern)
if (image_xscale > 0.25)
draw_circle(x + random_range(-1, 1), y + random_range(-1, 1), 2 + random_range(-1, 1), false);
// Reset all of your draw stuff
draw_set_blend_mode(bm_normal);
draw_set_alpha(1);
surface_reset_target();
} else {
// Again, surfaces can be a pain
// Create a new one if there were issues
surf = surface_create(room_width, room_height);
surface_set_target(surf);
draw_clear_alpha(c_black, 0);
surface_reset_target();
}
// Apparently I moved my fog layer with 'objDarkRoom', haha
background_x[1] -= 0.5;
ROOM END EVENT
// Clean up the surface memory manually
if (surface_exists(surf))
surface_free(surf);
DRAW END EVENT
NOTE: I am using the DRAW END EVENT rather than the DRAW EVENT. I'm not sure if there is any drawback to this. I use it because I can guarantee that 'objDarkRoom' will run its draw code LAST. If you use the typical draw event, be sure that this object is on the highest layer (lowest number), otherwise objects/tiles could draw on top of the overlay.
// Draw the surface or create a new one
// Be sure to use views, even if it isn't necessary for your game
// This trick bypasses an issue with resizing the game window
// DX requires that surfaces be destroyed when resizing
if (!surface_exists(surf)) {
surf = surface_create(room_width, room_height);
} else {
if (view_current == 0) {
draw_surface(surf, 0, 0);
}
}
Questions, comments, concerns? Shoot me an email at zbell91[AT]comcast[DOT]net.
-Z
hmm…. When i change to full screen mode, everything just messes up…. why?
LikeLike
DirectX requires that all surfaces be destroyed when resizing a window. There is currently no way around that. I believe there is an event pertaining to window resizing. You could create a new, resized one.
LikeLike