Composer Overlay Transitioning Too Quickly

Hi,

My game uses several overlay scenes, some simple, some more complex. All of them worked fine with Storyboard and Graphics 1.0. After switching to Composer/Graphics 2.0, using the latest public build, some of these overlay scenes appear to ‘pop’ on-screen with no transition. Code for showing the overlay:

[lua]composer.showOverlay(“props.manual”, {effect=“crossFade”, time=300, isModal=true})[/lua]

If I increase the ‘time’ parameter to something very high, say 5000, I can clearly see that the scene is transitioning on. However, it appears to ‘rush’ through the early part of the transition, and then slow down to a more stable rate. Is there a way to control the easing of overlay transitions?

Also, if I put print statements in the “create” and “show” functions of my overlay scene file, they aren’t printed to the console until after the overlay is on-screen (if I use my target transition time of 300). If the transition time is higher, they are printed at more appropriate times.

Once the scene is on-screen, it functions as expected, and the transition in hideOverlay works properly. Also, as I said, this was not an issue with Storyboard/Graphics 1.0, and it is not affecting all of my overlay scenes, only some of them.

Thanks in advance!

  • David

I’ve spent the better part of the morning optimizing the overlay modules that are ‘popping’ on-screen (removing around 50 lines of code!), and while they now works properly in the simulator, they still just ‘pop’ on-screen on my iPad Air and iPhone 4S (both 1x and 2x assets). What continues to be frustrating and perplexing is that other overlay modules display just fine.

Here’s the “create” function of one of the problem modules:

[lua]

function scene:create (e)local group = self.view propGift = display.newGroup() blackBG = display.newRect(propGift, 512, 384, 1024, 768) blackBG:setFillColor(0,0,0, overlayAlpha) giftBox = display.newImageRect(propGift, "images/overlays/gift\_box/ExtPT\_GiftOpen.png", 1024, 768) buttonInactive = display.newRect(propGift, 0, 0, 520, 520) buttonActive = display.newImageRect(propGift, "images/overlays/gift\_box/ExtPT\_GiftActive.png", 512, 512) boxTop = display.newImageRect(propGift, "images/overlays/gift\_box/ExtPT\_GiftClosed.png", 1024, 768) buttonInactive.isVisible = false; buttonInactive.isHitTestable = true buttonActive.isVisible = false local screenMidpointX = \_W \* .5 local screenMidpointY = \_H \* .5 for i=2, propGift.numChildren do propGift[i].x = screenMidpointX; propGift[i].y = screenMidpointY end exitButton = display.newImageRect(propGift, "images/UI/Close\_White.png", 40, 40) exitButton.x = \_W - 50; exitButton.y = 50 + deviceInfo.verticalOffset exitButton\_Touch = display.newCircle(propGift, exitButton.x, exitButton.y, 45) exitButton\_Touch.isVisible = false; exitButton\_Touch.isHitTestable = true boxTop:scale(deviceInfo.reductionFactor, deviceInfo.reductionFactor) giftBox:scale(deviceInfo.reductionFactor, deviceInfo.reductionFactor) buttonInactive:scale(deviceInfo.reductionFactor, deviceInfo.reductionFactor) buttonActive:scale(deviceInfo.reductionFactor, deviceInfo.reductionFactor) group:insert(propGift) end

[/lua]

And here’s the “create” function of a working module:

[lua]function scene:create (e)

local group = self.view

blackBG = display.newRect(group, 512, 384, 1024, 768)

blackBG:setFillColor(0,0,0, overlayAlpha)

if (gameState.currRoom == “rooms.int_1902_cavern”) then

pageFileExt = “_B&W.png”

end

propUninvite = display.newGroup()

propUninvite.isFlipping = false

propUninvite.hasFlipped = false

propUninvite_Back = display.newImageRect(propUninvite, “images/overlays/uninvite/UnInvite_Back” … pageFileExt, 800, 600)

propUninvite_Front = display.newImageRect(propUninvite, “images/overlays/uninvite/UnInvite_Front” … pageFileExt, 800, 600)

exitButton = display.newImageRect(propUninvite, “images/UI/Close_White.png”, 40, 40)

exitButton.x = _W - 50; exitButton.y = 50 + deviceInfo.verticalOffset

exitButton_Touch = display.newCircle(propUninvite, exitButton.x, exitButton.y, 45)

exitButton_Touch.isVisible = false; exitButton_Touch.isHitTestable = true

propUninvite_Front.x = _W / 2; propUninvite_Front.y = _H / 2

propUninvite_Back.x = _W / 2; propUninvite_Back.y = _H / 2

propUninvite_Back.xScale = .1

propUninvite_Back.isVisible = false

group:insert(propUninvite)

end[/lua]

It seems like the scene isn’t created in time before the transition actually begins. Is this possible? Why would this be the case? And why would Composer/Graphics 2.0 have a harder time creating the scene than Storyboard/Graphics 1.0, which was fine with these modules?

Thanks!
 

  • David

One other note on this: if I put print statements in each of the main scene functions (create, show, hide) they all show up in the console after the entire process is complete. For example, I’ll get three print statements at once (one for create, two for show), and they will all appear after the scene has visually finished transitioning onscreen. Shouldn’t the ‘create’ print statement fire, then I should see the transition, followed by the two ‘show’ print statements?

I did a lot more testing, and have reduced the problem module to this simple piece of code:

[lua]-- Load composer and create the scene

local composer = require(“composer”)

local scene = composer.newScene()

– Local variables

local blackBG = nil

local boxTop = nil

function scene:create (e)

local group = self.view

blackBG = display.newRect(group, 512, 384, 1024, 768)

blackBG:setFillColor(0,0,0, overlayAlpha)

boxTop = display.newImageRect(group, “images/Default-Landscape.png”, 1024, 768)

boxTop.x = _W * .5; boxTop.y = _H * .5

end

function scene:show (e)

end

function scene:hide (e)

end

scene:addEventListener(“create”, scene)

scene:addEventListener(“show”, scene)

scene:addEventListener(“hide”, scene)

return scene[/lua]

Even with this simple scene, the transition fails to work properly. However, if I convert the PNG to a JPG file, it works much better. That may be the reason why the ‘good’ module in one of my earlier posts works: it uses JPG images, rather than PNGs.

What’s going on here??

  • David

Hi David,

It could be that you’re loading a very large image. What is the file size of the largest version of “Default-Landscape” you’re loading? What device are you testing on which shows this behavior?

Brent

Thanks for the reply, Brent! The 2x PNG version of Default-Landscape is 1.2 MB, and the problem is apparent on both an iPad Air and an iPhone 4S, both with iOS 8. I also tested on an iPad Mini with iOS 7, and it had the same effect. This was not a problem with the old Storyboard and Graphics 1.0 framework, so I’m not sure why it would be an issue now.

Right now the only workaround I can see is to increase the transition time, but I’d prefer a better solution.

Thanks again!
 

  • David

Hi David,

So what is the pixel dimensions on that largest version? 2048 x 1536? Or otherwise?

Sorry Brent, should have included that info.

Default-Landscape.png [1024x768, 384KB]

Default-Landscape@2x.png [2048x1536, 1.2MB]

The JPG versions are 344KB and 962KB, respectively

The images that worked well, above:

UnInvite_Front.jpg [800x600, 281KB]

UnInvite_Front@2x.jpg [1600x1200, 1.2MB]

UnInvite_Back.jpg [800x600, 313KB]

UnInvite_Back@2x.jpg [1600x1200, 1.3MB]

Let me know if you’d like any more info. Thanks!
 

  • David

Hi David,

I don’t know the internal technical explanation for this. It’s a large image, which might be hurting the overall performance. Is there any way you can pre-load this image into the cache and keep it hidden, so when the scene shows, it’s already in memory?

Brent

Hi Brent, I just tried pre-loading the scene with composer.loadScene(), and it had no effect. I don’t really understand why a large image would matter, as it shouldn’t start transitioning until create() was finished. If the image was taking a long time to load, I would expect a pause before the transition starts, not a truncation of the transition. Also puzzling is that this is fine in the simulator, but not on any of my iOS devices.

Thanks again,

  • David

First of all… your print statements… Corona SDK has buffering turned on for the output for performance reasons.  You might find adding:

io.output():setvbuf(‘no’)

to the top of your main.lua.

As for why PNG’s could be slower to load than JPEG’s, well it’s about file size.  A 300K JPEG will load faster than a 1.3MB PNG just due to the file size.  However if you are trying to call composer.loadScene() in advance, this is very likely not the issue.

Does this happen in the Simulator or just on Device?

Can you zip up a sample to look at?  It would need to be complete with build.settings, config.lua and any images that display the issuel

Rob

Hi Rob,

Thanks for weighing in! The issue only happens on device (tested on iPad Air, iPhone 4S, iPad Mini 1G). I tried including [lua]io.output():setvbuf(‘no’)[/lua], but the output in my console is the same: all three print statements appear simultaneously, after the overlay is done transitioning (in both Xcode and the Corona Simulator console).

As to filesize, I would agree, but then these images should be giving me trouble, even though they’re not (overlay code posted above):

UnInvite_Front.jpg [800x600, 281KB]

UnInvite_Front@2x.jpg [1600x1200, 1.2MB]

UnInvite_Back.jpg [800x600, 313KB]

UnInvite_Back@2x.jpg [1600x1200, 1.3MB]

 

Also, I still don’t understand why the transition would start before the scene is finished being created, no matter how long it takes to load.

 

I’ll zip something up and post it here soon. Thanks!

 

  • David

Hi Rob,

 
Here is a ZIP file containing a small project that demonstrates this issue. I tested it on both my iPad Air and iPhone 4S, and both exhibited the problem. The app will load, and after two seconds, display the overlay. None of the overlay’s functionality will work, but you will see that it ‘pops’ on, with no visible transition.
 
Thanks for checking into it!
 

  • David

Before I dig to far into this, you are generating an error when click on the gift box:

    /Users/rmiracle/Downloads/OverlayTest/props/gift.lua:170: attempt to index field ‘ext_party_tree’ (a nil value)
    stack traceback:
        /Users/rmiracle/Downloads/OverlayTest/props/gift.lua:170: in function </Users/rmiracle/Downloads/OverlayTest/props/gift.lua:168>
        (tail call): ?
        ?: in function <?:498>
        ?: in function <?:221>

Next, you are trying to call showOverlay()  but you don’t have a parent scene to overlay.  Your main.lua should be calling composer.gotoScene() to go to your first scene.  Once there you can have an overlay.

Rob

Hi Rob,

No worries on the error; the entire overlay will be functionally broken. I just wanted to give you the most ‘real-world’ example I could without sending the entire game. In the actual game, once the overlay is on screen, everything works perfectly. The problem lies solely with the transition.

As for calling showOverlay without a parent scene, that was done just to make the example simpler, and it seems to work regardless: the overlay shows properly in the simulator, and shows (but without a transition) on device. I can fashion an updated example with a parent scene if you need it, just let me know.

Thanks!
 

  • David

We can’t support 3rd party libraries which you appear to be using with the Luna library.  Please put together a demo that shows this issue without using Luna and I’ll take another look.   If you find that you can’t produce this issue without Luna, then you should contact it’s author to see if they can isolate the issue in their code.

Hi Rob,

Haha, the Luna library is actually my own set of adventure game engine functions. It’s not really necessary in this case, though. I’ll simplify the example overall and resend.

  • David

Hi Rob,

Here’s the updated example. Should be much simpler now.

Thanks!
 

  • David

The sample you sent shows a black screen for 2 seconds, then fades in the overlay over 300ms.  That’s what I see in the simulator and that’s what I see on my iPhone 6.  Just to make sure the fade was happening, I changed it to 3000ms and after 2 seconds, it faded in over 3 seconds as expected.  I see no issues here.  If the issue is that 2 second blackness, well you have a timer.performWithDelay(2000,…) in your code that calls your overlay.

Rob

Hi Rob,

Thanks for taking the time to check it out. It’s interesting that the overlay faded as expected on your iPhone 6. On my iPad Air, iPad Mini 1G, and iPhone 4S, there is a 300 ms delay, followed by the overlay instantaneously appearing on screen. This is happening in both the sample app I sent you and the full Doggins app, which I am trying to convert from Storyboard/Graphics 1.0 to Composer/Graphics 2.0 to release an update on the App Store. All of this code was totally functional in the ‘old’ way of doing things.

I put the timer in the code to ensure that the test application was fully up and running before beginning the transition. It’s not the issue.

I too have made the effect time long, and it does work, but when it finally starts, the effect is partially complete. Meaning, it’s further along than it should be, then appears to slow down and continue normally for the remaining duration of the effect.

I’m going to try to capture my iPad screen as a QuickTime video so you can see exactly what I’m talking about.

Thanks again,

  • David