60FPS on CORONA code!!!

3 replies [Last post]
fpassa's picture
fpassa
User offline. Last seen 20 hours 36 sec ago. Offline
Joined: 17 Sep 2009

Hi all,

Here's a little trick to obtain 60FPS or even more in your animation made in CORONA.

You can verify it by using existing sample code provided in CORONA SDK Sample Code folder. For instance I picked Polyline or MovieClip sample code, to show you how to obtain faster animation beyond 30 limited FPS of CORONA engine. Of course this response can vary depending on different factors, but I tested them in my device iPhone 3G 16Gb and is fantastic!

What you have to do is to duplicate Runtime:addEventListener("enterFrame", xxx) sentence, for example in Polyline sample code do as follow:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
-- Example of shape drawing function
local function newStar()
 
        local star = display.newLine( 0,-110, 27,-35 )
 
        star:append( 105,-35, 43,16, 65,90, 0,45, -65,90, -43,15, -105,-35, -27,-35, 0,-110 )
 
        -- default color and width (can be modified later)
        star:setColor( 255, 255, 255, 255 )
        star.width = 3
 
        return star
end
 
 
-- Create stars with random color and position
local stars = {}
 
for i = 1, 20 do
 
        local myStar = newStar()
        
        myStar:setColor( math.random(255), math.random(255), math.random(255), math.random(200) + 55 )
        myStar.width = math.random(10)
        
        myStar.x = math.random( display.contentWidth )
        myStar.y = math.random( display.contentHeight )
        myStar.rotation = math.random(360)
        
        myStar.xScale = math.random(150)/100 + 0.5
        myStar.yScale = myStar.xScale
        
        myStar:setReferencePoint( display.CenterReferencePoint )
 
        local dr = math.random( 1, 4 )
        myStar.dr = dr
        if ( math.random() < 0.5 ) then
                myStar.dr = -dr
        end
 
        table.insert( stars, myStar )
end
 
 
 
 
function stars:enterFrame( event )
 
        for i,v in ipairs( self ) do
                v.rotation = v.rotation + v.dr
        end
end
 
Runtime:addEventListener( "enterFrame", stars )
Runtime:addEventListener( "enterFrame", stars ) -- Here I added this sentence

You can also see this impact of this trick on the MovieClip Sample Code. I've modified a little bit to show you another alternative to activate faster animation in this way:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
-- load external libraries (should be in the same folder as main.lua)
local ui = require("ui")
local movieclip = require("movieclip")
 
 
function main()
 
        display.setStatusBar( display.HiddenStatusBar )
 
        -- Create groups to hold assets
        background = display.newGroup()
        foreground = display.newGroup()
 
        -- Load background image
        local stars = display.newImage("space.png")
        background:insert( stars, true ); stars.x = 160; stars.y = 240
        
 
        ---------------------------------------------
        -- Create animated sprites (aka "movieclips")
 
        -- Initialize first cube anim   
        myAnim = movieclip.newAnim{"cube01.png", "cube02.png", "cube03.png", "cube04.png", "cube05.png", "cube06.png"}
        foreground:insert( myAnim )
 
        -- Add some frame labels (optional)
        myAnim:setLabels{foo=1, bar=3}
 
        myAnim.x = 150
        myAnim.y = 250
 
 
        -- Initialize a second cube anim (these could be different images, if desired)
        myAnim2 = movieclip.newAnim{"cube01.png", "cube02.png", "cube03.png", "cube04.png", "cube05.png", "cube06.png"}
        foreground:insert( myAnim2 )
 
        myAnim2.x = 160
        myAnim2.y = 300
        
        
        -- Start the animations, one forward and one in reverse
        myAnim:play()
        
        
        
        -------------------------------------------------------------------------
        -- FOR DEMO: 
        
        -- Function to bounce first cube around screen with simple Newtonian motion
        local dx = 4
        local dy = -8
        local grav = 0.2
        
        local function moveSprite()
                myAnim.x = myAnim.x + dx
                myAnim.y = myAnim.y + dy
                
                if ((myAnim.x < 20) or (myAnim.x > 300)) then
                        dx = -dx
                end
                
                if ((myAnim.y < 20) or (myAnim.y > 460)) then
                        dy = - dy - grav
                end
                
                dy = dy + grav          
        end
        
------------------------------------------------------------------------------------------------------------------
--
--               Add these lines to original code in main.lua of MovieClip sample code provided with CORONA SDK
--
-------- This where I added this new event on object myAnim2, which I will use as a button to increase animation FPS of myAnim object. --------
-------- Every time you tap the cube at the middle of the screen (i.e. myAnim2), the next one (myAnim) increase its FPS. 
-------- You will see that myAnim2 still at 30FPS, due its normal animation in MovieClip.lua file
 
        function myAnim2:tap (event)
                myAnim2:reverse()
                Runtime:addEventListener("enterFrame",moveSprite)
        end
        
        myAnim2:addEventListener("tap",myAnim2)
 
------------------------------------------------------------------------------------------------------------------      
        -- Start first cube bouncing
        Runtime:addEventListener( "enterFrame", moveSprite )
                
 
        -- Store all button actions in lookup table, for convenience
        local actions = 
        {
                ["button1"] = function() myAnim:play() end,
                ["button2"] = function() myAnim:reverse() end,
                ["button3"] = function() myAnim:stopAtFrame(4) end,
                ["button4"] = function() myAnim:stopAtFrame("foo") end
        }
        
        -- General function for all buttons (uses lookup table above)
        local buttonHandler = function( event )
                if ( "press" == event.phase ) then
                        actions[ event.id ]()
                end
        end
        
        
        -- Create buttons
        local button1 = ui.newButton{
                default = "shortButton.png",
                over = "shortButtonOver.png",
                onEvent = buttonHandler,
                id = "button1",
                text = "play()",
                size = 18,
                emboss = true,
                x = 80, 
                y = 80
        }
        background:insert( button1 );
        
        local button2 = ui.newButton{
                default = "shortButton.png",
                over = "shortButtonOver.png",
                onEvent = buttonHandler,
                id = "button2",
                text = "reverse()",
                size = 18,
                emboss = true,
                x = 240, 
                y = 80
        }
        background:insert( button2 );
        
        local button3 = ui.newButton{
                default = "shortButton.png",
                over = "shortButtonOver.png",
                onEvent = buttonHandler,
                id = "button3",
                text = "stopAtFrame(4)",
                size = 14,
                emboss = true,
                x = 80, 
                y = 130
        }
        background:insert( button3 );
        
        local button4 = ui.newButton{
                default = "shortButton.png",
                over = "shortButtonOver.png",
                onEvent = buttonHandler,
                id = "button4",
                text = "stopAtFrame(\"foo\")",
                size = 14,
                emboss = true,
                x = 240, 
                y = 130
        }
        background:insert( button4 );
 
end
 
-- Start program!
main()

Enjoy it.

Flavio
fpassa@gmail.com

Replies

MikeHart
User offline. Last seen 1 week 2 days ago. Offline
Joined: 22 Mar 2010

Flavio,

you still only get 30 FPS max, because corona flips the screen at this speed. What you do here is just update the framecounter twice a frame.

Michael

fpassa's picture
fpassa
User offline. Last seen 20 hours 36 sec ago. Offline
Joined: 17 Sep 2009

Mike,

Of course, but you get faster speed for animations that you couldn't take anyway. The frame refresh every 30, but animations increase their cycle, producing a simulation of improved FPS.

Flavio.

MikeHart
User offline. Last seen 1 week 2 days ago. Offline
Joined: 22 Mar 2010

:-) I thought you wanted to say that someone will actually have a refresh rate of 60 FPS and more.

Anway, I am sure someone will have a use for your method too. That's the great thing about developing stuff. You can reach a goal in several different ways. I foudn a different way of speeding or slowing the animation of a sprite/movieclip.

Viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.