How can I implement night levels?

Hi all,

I am writing a platform game and would like to implement some night levels. The character will have a flashlight that would light up the space in front of him. This in itself would be quite simple, I could use a black image with a “flashlight” shape cut out that would follow him around. However to complicate things I would also like to add;

1. more lights around the level that would be placed dynamically (not always in the same place),

2. explosions etc that would light up the immediate area when exploded

Has anyone got any pointers on how I could go about doing this?

Thanks,

Craig

I would suggest using a dark colored rect (purpe or blue) with its blendMode set to “multiply” to darken the level graphics.

Above that you have all the light sources (yellow to white) with their blendMode set to “add”.

I did so for a never release game I developed and it works great if you don’t darken the screen too much.

Thanks,

I played around with this and it works well.  Will work well for street lights and explosions etc.  I would like the flashlight to be more “transparent”. I played around with the settings and couldn’t quite get it transparent enough, the idea is that the level is so dark that you cannot see what is going on without the assistance of light, once it is this dark then the blend is not quite strong enough.

Im going to try using a mask for the flashlight and blends for everything else.   

Can you think of any other way?

Cheers

Craig

Check the sample projects included with Corona for the “Flashlight” and “xray” code.

I looked at these,  but not sure they would suit my needs.  As far as I can tell they use the mask to cut down the viewable area, not drill a hole through it.  This would work perfectly if I didn’t also want to implement additional light sources.  

What would work for me would be if I could use a mask to ‘drill’ a hole for the flashlight, then the rest of the layer would still be there so I could still apply blends etc for additional light sources.

Craig

Then you might want to take a look at the “SnapshotEraser” sample project.

Cheers,

I had a look at this.  My level has moving elements so I don’t think it would work, I think doing a snapshot:invalidate() every frame would have too much overhead.  So far Torben’s blend method is the closest,  it is just not quite transparent enough…

Thanks,

Ill keep thinking.

Hey,

Thinking about going in a slightly different direction.  I’m going to use an image with a hole cut in it for the headlight (gives perfect transparency) and then blends for the other lights (these don’t need to be as transparent).   As I said before I looked at using a mask but this has the opposite effect.

Not sure if anyone can help as this is rather specific to my needs, but…   If I want the whole level to be “night” then what is the best way to achieve this?  The camera follows the character but the user can pan around the level by dragging the screen, this means that I cannot simple black out the current ‘view’. I have a few thoughts, I was wondering if anyone had any input;

  1. Create one huge image with the headlight hole, this would need to be bigger than the current level so that it covers all the way to the left or right when the character moves.  This would take up a huge amount of texture memory??

  2. Create a small image with the headlight hole and then create newRects (set to the same colour) to the left, right, above and below. And then move these as the character moves.  

     a. Do newRects take up just as much texture memory?

     b. They would need to be perfectly aligned or else a seam would be visible.

     c. These could be put in a group, and I could move the group as opposed to everything individually

     d. Would it be better to resize these rects as the character moves?  That way they wouldn’t need to be as large.

Thanks,

Appreciate any input,

Craig

You could use normal mapping. This would add extra work to your game but it looks awesome. I read This link last week, and decided to try it out on Corona SDK, now that we have the graphics.newTexture API to use as framebuffers. After reading a lot of stuff and implementing this shader as two stages, I came up with this small example. Note! The assets are not my own, i just used the ones in the first link. I have yet to build my own normal and self-illumination maps. So this pretty much is a proof of concept only.

Hi,

Thanks basilogerman but I think this is outside my skillset.  

I actually ‘almost’ got it working, using the 2nd method I suggested above.  The only slight problem I have is that there is a very thin line where the seam is,  not sure if this is something I should be concerned about or not,  it annoys me, but I am not sure it would be overly visible to others.  It only appears when there is a blend…  Or when I am transitioning the alpha in or out…  Most of the time it would also be off screen unless the user pans around… (im trying to convince myself)…

I used the following code (found it in a forum somewhere) to minimize the issue and it helped.

[lua]local pixelHeight = 1000/display.contentScaleY

local pixelWidth = 1000/display.contentScaleX

local scaledTileHeight = math.floor(pixelHeight)*display.contentScaleY

local scaledTileWidth = math.floor(pixelWidth)*display.contentScaleX[/lua]

Any other ideas?  I’m not in love with this methods,  but can’t think of any others…  Is there any way to invert a mask??  

Cheers,

Craig

I would suggest using a dark colored rect (purpe or blue) with its blendMode set to “multiply” to darken the level graphics.

Above that you have all the light sources (yellow to white) with their blendMode set to “add”.

I did so for a never release game I developed and it works great if you don’t darken the screen too much.

Thanks,

I played around with this and it works well.  Will work well for street lights and explosions etc.  I would like the flashlight to be more “transparent”. I played around with the settings and couldn’t quite get it transparent enough, the idea is that the level is so dark that you cannot see what is going on without the assistance of light, once it is this dark then the blend is not quite strong enough.

Im going to try using a mask for the flashlight and blends for everything else.   

Can you think of any other way?

Cheers

Craig

Check the sample projects included with Corona for the “Flashlight” and “xray” code.

I looked at these,  but not sure they would suit my needs.  As far as I can tell they use the mask to cut down the viewable area, not drill a hole through it.  This would work perfectly if I didn’t also want to implement additional light sources.  

What would work for me would be if I could use a mask to ‘drill’ a hole for the flashlight, then the rest of the layer would still be there so I could still apply blends etc for additional light sources.

Craig

Then you might want to take a look at the “SnapshotEraser” sample project.

Cheers,

I had a look at this.  My level has moving elements so I don’t think it would work, I think doing a snapshot:invalidate() every frame would have too much overhead.  So far Torben’s blend method is the closest,  it is just not quite transparent enough…

Thanks,

Ill keep thinking.

Hey,

Thinking about going in a slightly different direction.  I’m going to use an image with a hole cut in it for the headlight (gives perfect transparency) and then blends for the other lights (these don’t need to be as transparent).   As I said before I looked at using a mask but this has the opposite effect.

Not sure if anyone can help as this is rather specific to my needs, but…   If I want the whole level to be “night” then what is the best way to achieve this?  The camera follows the character but the user can pan around the level by dragging the screen, this means that I cannot simple black out the current ‘view’. I have a few thoughts, I was wondering if anyone had any input;

  1. Create one huge image with the headlight hole, this would need to be bigger than the current level so that it covers all the way to the left or right when the character moves.  This would take up a huge amount of texture memory??

  2. Create a small image with the headlight hole and then create newRects (set to the same colour) to the left, right, above and below. And then move these as the character moves.  

     a. Do newRects take up just as much texture memory?

     b. They would need to be perfectly aligned or else a seam would be visible.

     c. These could be put in a group, and I could move the group as opposed to everything individually

     d. Would it be better to resize these rects as the character moves?  That way they wouldn’t need to be as large.

Thanks,

Appreciate any input,

Craig

You could use normal mapping. This would add extra work to your game but it looks awesome. I read This link last week, and decided to try it out on Corona SDK, now that we have the graphics.newTexture API to use as framebuffers. After reading a lot of stuff and implementing this shader as two stages, I came up with this small example. Note! The assets are not my own, i just used the ones in the first link. I have yet to build my own normal and self-illumination maps. So this pretty much is a proof of concept only.

Hi,

Thanks basilogerman but I think this is outside my skillset.  

I actually ‘almost’ got it working, using the 2nd method I suggested above.  The only slight problem I have is that there is a very thin line where the seam is,  not sure if this is something I should be concerned about or not,  it annoys me, but I am not sure it would be overly visible to others.  It only appears when there is a blend…  Or when I am transitioning the alpha in or out…  Most of the time it would also be off screen unless the user pans around… (im trying to convince myself)…

I used the following code (found it in a forum somewhere) to minimize the issue and it helped.

[lua]local pixelHeight = 1000/display.contentScaleY

local pixelWidth = 1000/display.contentScaleX

local scaledTileHeight = math.floor(pixelHeight)*display.contentScaleY

local scaledTileWidth = math.floor(pixelWidth)*display.contentScaleX[/lua]

Any other ideas?  I’m not in love with this methods,  but can’t think of any others…  Is there any way to invert a mask??  

Cheers,

Craig