2D Dynamic Shadows

A quick test shows, that adding a light with the Light class do  snot work properly for me. In fact nothing happens on the screen.

Futhermore removing a light does some optical glitches right now which I have to fix. But it does not crash like in your example.

So I guess it has something todo with your timers. Don’t know how experienced you are in Corona/LUA but removing objects in relation with timers and transitions is always a critical point which I always stumble upon.

I will add a LightRemove() and a LightOn() and LightOff() method to the shadow class. I recommend to use these. If you only want lights and no shadow throwing you can additionally use the light:SetShadowThrowing( false ) method.

What I’m doing is bypassing the shadow class and requiring the light class directly, then using the code that I listed above. I am doing it this way for testing purposes to make sure the performance doesn’t plummet. It seems like my lag comes from the vector points using the shadows which is why I am by passing them by requiring the light class and adding a light directly instead of through the shadow class. Also it only does that error when calling the Light:Remove() or adding it to the sceneGroup class and using the composer.removeScene()

So my exact code is:

local light = require("2dshadows.light") light1 = light:new( 2, {0,1,0}, 1, 4 ) light1.x = -10 light1.y = -10 light1:SetDraggable(false) sceneGroup:insert(light1)

That is literally all I am calling in my class, works perfect to. The -10 x and y is to set it in the upper corner of the screen. I can even drag it fine when I don’t set the draggable to false. I’m pretty decent with Lua, which is why I know its trying to remove a object that has a value of 0. What I am thinking is that because I am calling the light directly instead of through the shadow class, I’m not using a initializing a value which the vector 2d class requires to update the lens flare, which in turn, allows me to remove the light. Also I just tested it without lens flares and it still does the error. So what I’ll do now is require the shadow class and add a light that way, see if anything changes.

I wrote a little example with the light module only, as far as I have unferstood what you want to achieve. I also added a button which removes the light which does not throw an error. 

----------------------------------------------------------------------------------------- -- -- level8.lua -- Light only example -- ----------------------------------------------------------------------------------------- local composer = require( "composer" ) local scene = composer.newScene() local Light = require( "2dshadows.light" ) local Helper = require( "2dshadows.util.helper" ) local \_W, \_H, \_W2, \_H2 = math.floor( display.actualContentWidth + 0.5 ), math.floor( display.actualContentHeight + 0.5 ) local \_W2, \_H2 = \_W\*0.5, \_H\*0.5 function scene:create( event ) local sceneGroup = self.view local background = display.newImageRect( "img/bg2.jpg", \_W, \_H ) background.x, background.y = \_W2, \_H2 -- CREATE BLUE LIGHT local light1 = Light:new( 3, {0.5,0.5,0.7}, 0.7, 6 ) light1.x, light1.y = 0 , 0 light1:SetDraggable( true ) -- CREATE BUTTON local butRemoveLight = Helper:QuickButton("Remove") butRemoveLight.x = \_W2 butRemoveLight.y = 30 butRemoveLight:addEventListener( "tap", function() light1:Remove() end ) -- INSERT TO SCENEGROUP sceneGroup:insert( background ) sceneGroup:insert( light1 ) sceneGroup:insert( butRemoveLight ) end --------------------------------------------------------------------------------- -- Listener setup scene:addEventListener( "create", scene ) ----------------------------------------------------------------------------------------- return scene

So there must be something more you are doing?

This is the code for when my character dies:

 function collision(self, event) if event.phase == "began" then --Collision with asteroids if self.type == "player" and event.other.type == "obstacle" then local function trans() Text:removeSelf() Text = nil pause:removeSelf() pause = nil --scoreText:removeSelf() --scoreText = nil gemCounter:removeSelf() gemCounter = nil coinCounter:removeSelf() coinCounter = nil coinFont:removeSelf() coinFont = nil gem:removeSelf() gem = nil light1:Remove() transition.cancel() timer.cancel(objTimer) timer.cancel(gemTimer) --char:remove() --charDies:remove() composer.showOverlay("gameOver") end --highsaveScore() if char:currentAnimation() == "back" or char:currentAnimation() == "up" or char:currentAnimation() == "down" or char:currentAnimation() == "forward" or char:currentAnimation() == "idle" then Runtime:removeEventListener("enterFrame", move) Runtime:removeEventListener("enterFrame", move2) Runtime:removeEventListener("enterFrame", move3) Runtime:removeEventListener( "enterFrame", main ) Runtime:removeEventListener("touch", moveAnalog) char:removeEventListener("collision", char) transition.cancel("transTag") timer.pause(objTimer) timer.pause(gemTimer) --music.remove() gem:pause() charDies:newAnim("dead", mcx.sequence({name = "playerSel/characters/player/gameOverAnim/dies", extension = "png", endFrame = 24, zeros = 2}), 351, 330, {speed = 1, loops = 1}) char:stop() charDies:play({name = "dead"}) transition.to(charDies, {delay = 1000, onComplete = trans}) end

As you can see the only transitions and timers I cancel are ones that have tags in them so I can cancel specific timers. Still getting the error though, not sure why. Using the shadow class now as well. I also tried commenting out the transition.cancel to see if that was the issue. It seems the error only occurs when I switch scenes. Have you tried switching between scenes yet?

Ok, you were right. After some testing with scene changes I was able to reproduce. There were some Runtime enterframe events that still tried to access the lights after it has been removed. Please update via SourceTree to latest version and let me know if this fixes the crash.

Just tested it and it works flawlessly. You are truly an amazing programmer. You created something truly special here, and I hope more people find this post and use this. I’m going to add you to the game credits by listing your user handle and title of the plugin if thats alright with you, to market what you have here. More people should use this. Again, amazing. Thank you so much, and if you need any help testing features to flesh this out even more, just let me know and I’ll help you anytime.

Thank you rburns for you patience. I’m glad you were persistence enough so that we were able to fix this.

Maybe you should take a look if the memory consumption is consistent (memory leaks). If not, let me know. Then I will take a deeper look on that.

I’m ok with the game credits. Hope you will finish your game!

Maybe post a link here in the thread for a real life example.

There are no memory leaks, and if there were, I didn’t notice them. I always have my memory checker on and I didn’t see any leaks at all in terms of physical memory or texture memory. If I ever do notice any, I will post on here. Everything is running very consistently. I definitely will! May be a little bit because I am very OCD and I am aiming to make one of the most beautiful games made on the Corona SDK. Which is why I was very adamant on getting this to work with you. As soon as I can finalize level 1, I will gladly post what we have done on here. Just going over the art style that I want to use for the game with my artist.

Sounds promising. If you need some more eyes to beta test write me a message.

What is OCD? You don’t mean obsessive-compulsive disorder, don’t you? Just curious …

That would be great! It would really help to have an objective point of view. Yeah it does, but I meant it as a metaphor. I keep working on things until they are perfect. It’s just how I am. It’s my first game and I want to do it right.

Added a new Version 1.31 and a new video in the first post to introduce the current feature set.

This is really impressive. Well done and thank you.

This is really great! I just tried it though and I am only averaging 13 FPS and my computer is really good. Did something change in Corona or your code? In addition, will Corona be supporting its own dynamic lighting system in the future if anyone knows?

Just compiled my code and tested in simulator and on device. But on both situations I get constantly around 60 fps (I tested level6 with the Real Attenuation feature). Have you tested on a device, too? Have you pulled from BitBucket or did you try the zip file from first post?

Anybody else with these low frame rates?

AFAIK there is no plan on Coronalabs side to implement a lighting system. 

I cloned it using Soruce Tree like you had talked about in the first post. It works perfect on my Galaxy S4 running between 40 and 50 frames a second. Just runs at 14 and drops below on my Corona client. Which is really weird.

Hm strange. Which Corona version and OS you use?

Version 2570 on Windows 7 x64. I’m going to use it anyway in my game, but I may move this onto my Mac to see if it acts differently. Trying to add two light sources to my game for the levels.

So it works fine on the Mac, not entirely sure why. It could just be my laptop which is weird since it is new. But anyway, I have a question about one of your functions. When my character dies I attempt to call the light:Remove() function but it comes up with this error below. I have existing transition.cancel and timer.cancel function but they all use tags to cancel only specific timers. I’ve also tried without canceling the timers at all just in case your code cancels all active timers, but no dice. The error always occurs at 2DVector line 140. Do you know why?

I am calling the light class to just add a light. I’m not calling it through the shadow class like how you have it in your examples. Should I be calling it from the shadow class instead?

light1 = light:new( 2, {0,1,0}, 1, 4 ) light1.x = -10 light1.y = -10 light1:SetDraggable(false) sceneGroup:insert(light1)

Thanks for reading!

First let me say that this light/shadow module has not been tested in a real game environment and I do expect errors if you try to implement it in a game. But I really want it to work within a game so I’m eager to solve any problems that may occur.

It seems that Corona tries to access a vector that has been removed. Also the last Method before the Vector2D:Sub Method is the UpdateLenseFlare Method. Have you tried it without any lense flares just for testing purposes?

Let me do some tests with adding/removing light at runtime to reproduce the error.

If you’re not useing the Shadow:AddLight() Method I really do not understand how this working? Or do you insert the light object manually to the Shadow.lights table? I think this does only make sense, if you don’t want to have shadows, but only lights and lense flares. I have to test this but the Shadow object is kind of a manager of the whole system.

A quick test shows, that adding a light with the Light class do  snot work properly for me. In fact nothing happens on the screen.

Futhermore removing a light does some optical glitches right now which I have to fix. But it does not crash like in your example.

So I guess it has something todo with your timers. Don’t know how experienced you are in Corona/LUA but removing objects in relation with timers and transitions is always a critical point which I always stumble upon.

I will add a LightRemove() and a LightOn() and LightOff() method to the shadow class. I recommend to use these. If you only want lights and no shadow throwing you can additionally use the light:SetShadowThrowing( false ) method.