I wrote this snippet as a proof of concept for a score/time keeper in a game I'm currently working on.
The createTicker() function takes two parameters: a number, and the number of digits you want the display to be. It then generates a 'card' for each digit, based on the width and height of the number font + padding.
The increment() function will increase the value of the number, and you can set a timer to increment the value every second to act as a game timer display. A decrement() function would behave pretty much the same way but in reverse, and a jumpToNumber() function would act similar as well.
You can change fontsize, paddingwidth, paddingheight, and space to almost anything and it'll render properly. I didn't include any real error checking in this code snippet, so if you have a 2 digit display increment past 99, it's going to break. It's very easy to check for that sort of stuff if you wish to include this in your project, though.
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 | --CUT HERE getmetatable('').__index = function(str,i) return string.sub(str,i,i) end local createTicker = function(number,digits) local localGroup = display.newGroup() --format the number with leading zeroes equivilent to the 'digits' parameter --i.e. displaying the number 123 on a 6 digit display results in: 000123 str = string.format("%0"..digits.."d", number) --get the width of a digit then remove it from display/memory local fontsize = 78 local temp = display.newText(str[1],10, 10, native.systemFont, fontsize) numwidth = temp.contentWidth numheight = temp.contentHeight temp:removeSelf() --padding on digits paddingwidth=8 paddingheight=8 --space between cards space=8 --height of digit card width=numwidth+(paddingwidth*2) height=numheight+(paddingheight*2) --loop through and create a card for each digit for i=1,digits do local numgrp = display.newGroup() numgrp:setReferencePoint(display.TopLeftReferencePoint) --create the background local bg = display.newRect(0,0,width,height) bg:setFillColor(255,255,255) bg.x = (width*i)+(space*i) bg.y = 0 numgrp:insert(bg) --create the digit and center it on the bg local num = display.newText(str[i],(width*i)+(space*i)-numwidth/2, -(height/2)+paddingheight, native.systemFont, fontsize) --set the color of the digit num:setTextColor(255,0,0) numgrp:insert(num) --insert the card into the localGroup localGroup:insert(numgrp) end --set the position of the ticker localGroup.y = 200 localGroup.increment = function() --increment number local newnum = tonumber(str) + 1 --print("Incrementing to: " .. newnum) --create a string from the new number local newstr = string.format("%0"..digits.."d",newnum) for index=1,#str do --only flip cards that are changing number if str[index] ~= newstr[index] then --set the new card to slide into the position of the current card destination = localGroup[index].y local numgrp = display.newGroup() numgrp:setReferencePoint(display.TopLeftReferencePoint) local bg = display.newRect(0,0,width,height) bg:setFillColor(255,255,255) bg.x = (width*index)+(space*index) bg.y = 0 numgrp:insert(bg) --create the new digit local num = display.newText(newstr[index],(width*index)+(space*index)-numwidth/2, -(height/2)+paddingheight, native.systemFont, fontsize) --set number to a random color. useful to see what's going on --num:setTextColor(math.random(1,255),math.random(1,255),math.random(1,255)) --set it to black num:setTextColor(0,0,0) numgrp:insert(num) --set the new card above the current number numgrp.y = localGroup[index].y - localGroup[index].contentHeight --start the card out invisible numgrp.alpha = 0 localGroup:insert(numgrp) --when the transition is complete, remove the old number from the localGroup and insert the new number into it --then update the number string local transitionHandler = function() localGroup:remove(index) localGroup:insert(index,numgrp) str = newstr end --speed of the transition should be lower than the timer interval local speed = 500 --transition the two cards local from = transition.to(localGroup[index],{y=localGroup[index].y+localGroup[index].contentHeight,alpha=0,time=speed, onComplete=transitionHandler}) local to = transition.to(numgrp,{y=destination,alpha=1,time=speed}) end end end --return the localGroup so you can call methods on it return localGroup end --create a new ticker --parameters: number to start from, number of digits --it doesn't do any error checking, so number must fit into the digits specified local ticker = createTicker(10,4) --increment the ticker one time --ticker.increment() --start incrementing indefinitely --there's no error checking, so once it runs out of digits to change it will break timer.performWithDelay(1000,ticker.increment,0) --END CUT HERE |
Nice one.
You could change line 124 to something like this:
To have the digit moving down bend a bit. Looks funny though :-)
Best J.