Best approach for a typewriter effect?

Hi guys,

I was just doing some refactoring and came across my typewriter implementation I made a while ago. Wondering now what would be the best approach. I came up with 3 methods, which all achieve the same functionality. But I would like to know which would perform best. Would love to hear your opinions. The code is beneath.

local text1 = display.newText({ text = "", y = 80, font = native.systemFont, fontSize = 15 }) text1.anchorX = 0 local text2 = display.newText({ text = "", y = 160, font = native.systemFont, fontSize = 15 }) text2.anchorX = 0 local text3 = display.newText({ text = "", y = 240, font = native.systemFont, fontSize = 15 }) text3.anchorX = 0 local text = "abcdefghijklm nopqrstuvw xyz abcdefghijklm nopqrstuvw xyz" ------------------------------------------------------- -- Method 1 ------------------------------------------------------- for i=1, #text, 1 do timer.performWithDelay(i \* 100, function() text1.text = string.sub(text, 1, i) end) end ------------------------------------------------------- -- Method 2 ------------------------------------------------------- local lastTime = system.getTimer() local lastIndex = 0 Runtime:addEventListener("enterFrame", function(event) if event.time \>= (lastTime + 100) then lastTime = event.time lastIndex = lastIndex + 1 text2.text = string.sub(text, 1, lastIndex) end end) ------------------------------------------------------- -- Method 3 ------------------------------------------------------- local lastIndex2 = 0 timer.performWithDelay(100, function() lastIndex2 = lastIndex2 + 1 text3.text = string.sub(text, 1, lastIndex2) end, 0)

Hey,

I think methode 2 or 3 work better as method 1, as method 1 creates many many timers that run simultaniously, which kills performance.

But I think a better approach for this specific situation would be the following:

local textObject = display.newText({ text = "", font = native.systemFont, fontSize = 15, }) local textString = "abcdefgh ijklmn opqr stuvwxyz" local typewriterFunction = function(event) textObject.text = string.sub(textString, 1, event.count) end local typewriterTimer = timer.performWithDelay(100, typewriterFunction, string.len(textString))

Like this you don’t need an extra index and the timer does not run forever like in method 3.

Additionally you get the timer handle to pause or cancel it.

Greetings

Torben

I agree on method 1 looks like it’s would be in-efficient. (Although I don’t know how timers work under the hood).

I like the elegant method 3, but it would somewhat limit me in customisability, as there is a static 100 ms, and no (elegant) way to change that dynamically. For example I would like to add custom “wait” functions in my text, for example: “abc, #wait250 defghijklmn…”. This would wait 250ms after text is "abc, " and then continues again.

I’ll try to find my way with method 2 as base, as this both performs and allows customisability.

You can archive that with third method as well. Just assign a variable to the 100ms and inside the function where you change the letter check next char, if its # get the value after it till find a space change the variable of the timer with that value. Done.

Hey,

I think methode 2 or 3 work better as method 1, as method 1 creates many many timers that run simultaniously, which kills performance.

But I think a better approach for this specific situation would be the following:

local textObject = display.newText({ text = "", font = native.systemFont, fontSize = 15, }) local textString = "abcdefgh ijklmn opqr stuvwxyz" local typewriterFunction = function(event) textObject.text = string.sub(textString, 1, event.count) end local typewriterTimer = timer.performWithDelay(100, typewriterFunction, string.len(textString))

Like this you don’t need an extra index and the timer does not run forever like in method 3.

Additionally you get the timer handle to pause or cancel it.

Greetings

Torben

I agree on method 1 looks like it’s would be in-efficient. (Although I don’t know how timers work under the hood).

I like the elegant method 3, but it would somewhat limit me in customisability, as there is a static 100 ms, and no (elegant) way to change that dynamically. For example I would like to add custom “wait” functions in my text, for example: “abc, #wait250 defghijklmn…”. This would wait 250ms after text is "abc, " and then continues again.

I’ll try to find my way with method 2 as base, as this both performs and allows customisability.

You can archive that with third method as well. Just assign a variable to the 100ms and inside the function where you change the letter check next char, if its # get the value after it till find a space change the variable of the timer with that value. Done.