Any glaringly stupid errors in this code?

This is my very first Corona anything. Trying to do the best I can, but I’m sure I’m doing many things inefficiently, if not outright wrong. So far this appears to mostly work in the simulator. It’s an app that loads one of a set of 3 (will eventually be 20) randomly generated screens with custom messages when the device is shaken. 

It seems to mostly work…but the simulator starts to slow down and get laggy after you shake it 10-20 times. Not sure why that is. 

Also, I’d like to play a second audio file for each of the background images, timed for when the shakeAgain image appears (using a transition.to), and I want it to start 1000 milliseconds after the respective background appears. How do I delay the second audio file so that it starts playing a second AFTER each new background image appears? 

I appreciate any feedback or advice.

-- housekeeping stuff display.setStatusBar(display.HiddenStatusBar) local centerX = display.contentCenterX local centerY = display.contentCenterY -- preload audio local soundTable = { harpSound = audio.loadSound("sounds/harp.wav"), negativeMeow = audio.loadSound("sounds/sad-meow-1.ogg"), purringSound = audio.loadSound("sounds/tabby-purring-3sec.wav") } -- audio.play( soundTable ["harpSound"] ) -- create intro screen local function showNav() navBar = display.newImageRect("interface-elements/top-aqua-nav-bar.png",1242,400) navBar.x = centerX navBar.y = 70 navBar.alpha = 0 transition.to(navBar, { time=500, alpha=1 }) end local function createIntroScreen() introScreen = display.newImageRect("interface-elements/main-intro-screen.jpg",1242,2208) introScreen.x = centerX introScreen.y = centerY introScreen.alpha = 0 introCircle = display.newImageRect("interface-elements/intro-coral-circle.png",596,596) introCircle.x = centerX - 150 introCircle.y = display.viewableContentHeight / 2 + 300 introCircle.alpha = 0 audio.play( soundTable ["harpSound"] ) audio.play( soundTable ["negativeMeow"] ) transition.to(introCircle, {time=500, delay=1000, alpha=1}) transition.to(introScreen, { time=1000, alpha=1, onComplete=showNav }) end -- app functions local function appBackground1() backgroundScreen = display.newImageRect("backgrounds/background-yes-1.jpg",1242,2208) backgroundScreen.x = centerX backgroundScreen.y = centerY backgroundScreen.alpha = 0 audio.play( soundTable ["negativeMeow"] ) transition.to(backgroundScreen, { time=1000, alpha=1 }) navBar = display.newImageRect("interface-elements/top-aqua-nav-bar.png",1242,400) navBar.x = centerX navBar.y = 70 answerRectangle = display.newImageRect("answer-rectangles/answer-yes-1.png",1242,400) answerRectangle.x = centerX answerRectangle.y = 300 answerRectangle.alpha = 0 transition.to(answerRectangle, { time=1000, delay=1000, alpha=1 }) shakeAgain = display.newImageRect("interface-elements/shake-again-cloud.png",1642,900) shakeAgain:scale(0, 0) shakeAgain.x = centerX shakeAgain.y = display.viewableContentHeight - 200 shakeAgain.alpha = 0 transition.to(shakeAgain, { time=1000, delay=2000, alpha=1, xScale=1, yScale=1 }) end local function appBackground2() backgroundScreen = display.newImageRect("backgrounds/background-maybe-1.jpg",1242,2208) backgroundScreen.x = centerX backgroundScreen.y = centerY backgroundScreen.alpha = 0 audio.play( soundTable ["negativeMeow"] ) transition.to(backgroundScreen, { time=1000, alpha=1 }) navBar = display.newImageRect("interface-elements/top-aqua-nav-bar.png",1242,400) navBar.x = centerX navBar.y = 70 answerRectangle = display.newImageRect("answer-rectangles/answer-maybe-1.png",1242,400) answerRectangle.x = centerX answerRectangle.y = 300 answerRectangle.alpha = 0 transition.to(answerRectangle, { time=1000, delay=1000, alpha=1 }) shakeAgain = display.newImageRect("interface-elements/shake-again-cloud.png",1642,900) shakeAgain:scale(0, 0) shakeAgain.x = centerX shakeAgain.y = display.viewableContentHeight - 200 shakeAgain.alpha = 0 transition.to(shakeAgain, { time=1000, delay=2000, alpha=1, xScale=1, yScale=1 }) end local function appBackground3() backgroundScreen = display.newImageRect("backgrounds/background-no-1.jpg",1242,2208) backgroundScreen.x = centerX backgroundScreen.y = centerY backgroundScreen.alpha = 0 audio.play( soundTable ["negativeMeow"] ) transition.to(backgroundScreen, { time=1000, alpha=1 }) navBar = display.newImageRect("interface-elements/top-aqua-nav-bar.png",1242,400) navBar.x = centerX navBar.y = 70 answerRectangle = display.newImageRect("answer-rectangles/answer-no-1.png",1242,400) answerRectangle.x = centerX answerRectangle.y = 300 answerRectangle.alpha = 0 transition.to(answerRectangle, { time=1000, delay=1000, alpha=1 }) shakeAgain = display.newImageRect("interface-elements/shake-again-cloud.png",1642,900) shakeAgain:scale(0, 0) shakeAgain.x = centerX shakeAgain.y = display.viewableContentHeight - 200 shakeAgain.alpha = 0 transition.to(shakeAgain, { time=1000, delay=2000, alpha=1, xScale=1, yScale=1 }) end createIntroScreen() -- listeners local function shakeListener( event ) local theNumber = (math.random(3)) print(theNumber) if event.isShake then if (theNumber) == 1 then appBackground1() elseif (theNumber) == 2 then appBackground2() elseif (theNumber) == 3 then appBackground3() end end return true end Runtime:addEventListener( "accelerometer", shakeListener )

I don’t see you ever destroy an image.  Am I missing the display.remove() calls?

It is probably getting laggy because you keep creating images and never deleting the old ones.  The lag means memory is filling and there are too many images to render  in one frame.

Try this kind of change:

local function appBackground1() backgroundScreen = display.newImageRect("backgrounds/background-yes-1.jpg",1242,2208)

becomes this:

local function appBackground1() display.remove(backgroundScreen) backgroundScreen = display.newImageRect("backgrounds/background-yes-1.jpg",1242,2208)

repeat for all creations.

Ugh! I was wondering about that destroying thing. Yup, I haven’t been removing the previous images at all because I thought that each one could/would only occupy the same memory space no matter how many times it was called? I guess that’s not correct. 

Also, the shake listener is probably getting called way too often.  Try this and look at the log:

local lastShake = 0 local function shakeListener( event ) local curTime = system.getTimer() print("Shake at :" .. curTime .. " time since last: " .. curTime - lastShake ) lastShake = curTime end

I bet you’ll see a bunch of messages where the since time is 0 or less than 30

That went over my head. I don’t understand. When I trigger shakes in rapid succession the log shows…

2015-04-17 16:30:56.770 Corona Simulator[29208:507] Shake at :23305.565 time since last: 208.969

2015-04-17 16:30:56.888 Corona Simulator[29208:507] Shake at :23424.033 time since last: 118.468

2015-04-17 16:30:57.066 Corona Simulator[29208:507] Shake at :23601.596 time since last: 177.563

2015-04-17 16:30:57.236 Corona Simulator[29208:507] Shake at :23771.902 time since last: 170.306

But what does this mean? Is there a downside to triggering events on shake this way? 

That seems fine.  The numbers are in milliseconds

Shake at :23305.565 time since last: 208.969

  • shake event occurred 23.3305565 (23.3) seconds after app started.
  • previous shake was 208.969 ms ago or 0.2 seconds.

It looks like your shakes are happening about every 0.2 seconds.

In frame time, if you’re running at 30 FPS (1 Frame = 1000/30 ~= 33.3 ms), this means a new shake every:

200 / 33.3 ~= 6 frames

i.e 6 frames elapse then a new shake is processed.

Another way to think of this is, your shake code executes about 1 / 0.2 ==  5 times a second.

That’s me triggering the shakes manually through the simulator. The idea is that the user will shake the device to see the random image and message, but I’m imagining that they probably won’t shake it more often than once every few seconds in real life because if they did they wouldn’t even be able to read the messages.

Hey, thanks again for your help. I was worried about commenting in the forum because you never know about a new community. In some of them people aren’t very welcoming of newcomers. 

I’ve been grumpy with some folks, but these are good questions.

You need to run that same sample on a device and examine the log.  The simulator won’t give you a realistic idea of how often the listener() is firing.   I still think it will be too often.  You’ll want to write a throttle to ignore events that happen to fast.

Read through here to learn how to view the console on a device: http://docs.coronalabs.com/guide/basics/debugging/index.html#consoledebugging

I don’t see you ever destroy an image.  Am I missing the display.remove() calls?

It is probably getting laggy because you keep creating images and never deleting the old ones.  The lag means memory is filling and there are too many images to render  in one frame.

Try this kind of change:

local function appBackground1() backgroundScreen = display.newImageRect("backgrounds/background-yes-1.jpg",1242,2208)

becomes this:

local function appBackground1() display.remove(backgroundScreen) backgroundScreen = display.newImageRect("backgrounds/background-yes-1.jpg",1242,2208)

repeat for all creations.

Ugh! I was wondering about that destroying thing. Yup, I haven’t been removing the previous images at all because I thought that each one could/would only occupy the same memory space no matter how many times it was called? I guess that’s not correct. 

Also, the shake listener is probably getting called way too often.  Try this and look at the log:

local lastShake = 0 local function shakeListener( event ) local curTime = system.getTimer() print("Shake at :" .. curTime .. " time since last: " .. curTime - lastShake ) lastShake = curTime end

I bet you’ll see a bunch of messages where the since time is 0 or less than 30

That went over my head. I don’t understand. When I trigger shakes in rapid succession the log shows…

2015-04-17 16:30:56.770 Corona Simulator[29208:507] Shake at :23305.565 time since last: 208.969

2015-04-17 16:30:56.888 Corona Simulator[29208:507] Shake at :23424.033 time since last: 118.468

2015-04-17 16:30:57.066 Corona Simulator[29208:507] Shake at :23601.596 time since last: 177.563

2015-04-17 16:30:57.236 Corona Simulator[29208:507] Shake at :23771.902 time since last: 170.306

But what does this mean? Is there a downside to triggering events on shake this way? 

That seems fine.  The numbers are in milliseconds

Shake at :23305.565 time since last: 208.969

  • shake event occurred 23.3305565 (23.3) seconds after app started.
  • previous shake was 208.969 ms ago or 0.2 seconds.

It looks like your shakes are happening about every 0.2 seconds.

In frame time, if you’re running at 30 FPS (1 Frame = 1000/30 ~= 33.3 ms), this means a new shake every:

200 / 33.3 ~= 6 frames

i.e 6 frames elapse then a new shake is processed.

Another way to think of this is, your shake code executes about 1 / 0.2 ==  5 times a second.

That’s me triggering the shakes manually through the simulator. The idea is that the user will shake the device to see the random image and message, but I’m imagining that they probably won’t shake it more often than once every few seconds in real life because if they did they wouldn’t even be able to read the messages.

Hey, thanks again for your help. I was worried about commenting in the forum because you never know about a new community. In some of them people aren’t very welcoming of newcomers. 

I’ve been grumpy with some folks, but these are good questions.

You need to run that same sample on a device and examine the log.  The simulator won’t give you a realistic idea of how often the listener() is firing.   I still think it will be too often.  You’ll want to write a throttle to ignore events that happen to fast.

Read through here to learn how to view the console on a device: http://docs.coronalabs.com/guide/basics/debugging/index.html#consoledebugging