Handy Code Snippets
This is a post that lists some handy code snippets. They will generally be small examples and the list will be added to in time and also if you guys post some snippets I will add them to this list.
Print/Display a boolean value preceded by a string
Problem :
If you try to simply print a boolean value preceded by a string like so :
local myBool = true print("Value of my bool = " .. myBool)
You will get the following error :
"attempt to concatenate field 'myBool' (a boolean value)"
To get around this you instead use a comma.
--Usage local myBool = true print("Value of my bool = ", myBool)
This will output :
Value of my bool = true
Iterating through a key/pair table in order
As you know if you iterate through a key/pair table, it does not do so in the order it was defined.
Eg:
1 2 3 4 5 6 7 8 9 | local myTable = { ["key1"] = 1, ["key2"] = 2, ["key3"] = 3, } for k, v in pairs(myTable) do print(myTable[k]) end |
will print :
1, 3, 2
Sometimes that is fine, but it is not always what you want.
To iterate in order you can use the following function (taken from the lua wiki)
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 | local myTable = { ["key1"] = 1, ["key2"] = 2, ["key3"] = 3, } local function __genOrderedIndex( t ) local orderedIndex = {} for key in pairs(t) do table.insert( orderedIndex, key ) end table.sort( orderedIndex ) return orderedIndex end local function orderedNext(t, state) -- Equivalent of the next function, but returns the keys in the alphabetic -- order. We use a temporary ordered key table that is stored in the -- table being iterated. --print("orderedNext: state = "..tostring(state) ) if state == nil then -- the first time, generate the index t.__orderedIndex = __genOrderedIndex( t ) key = t.__orderedIndex[1] return key, t[key] end -- fetch the next value key = nil for i = 1,table.getn(t.__orderedIndex) do if t.__orderedIndex[i] == state then key = t.__orderedIndex[i+1] end end if key then return key, t[key] end -- no more value to return, cleanup t.__orderedIndex = nil return end --This is the function you will use to replace "pairs" local function orderedPairs(t) -- Equivalent of the pairs() function on tables. Allows to iterate -- in order return orderedNext, t, nil end for k, v in orderedPairs(myTable) do print(myTable[k]) end |
That will print:
1, 2, 3
Shuffling a table
Say you are making a card game and want to shuffle your table containing your cards. Here is one function that can do it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | local function shuffle(t) local rand = math.random assert(t, "table.shuffle() expected a table, got nil") local iterations = #t local j for i = iterations, 2, -1 do j = rand(i) t[i], t[j] = t[j], t[i] end end --Usage shuffle(myTable) |
Checking if a file exists
This speaks for itself, to check if a file exists you can use a handy function like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | local function doesFileExist(theFile, path) local thePath = path or system.DocumentsDirectory local filePath = system.pathForFile(theFile, thePath) local results = false local file = io.open(filePath, "r") --If the file exists, return true if file then io.close(file) results = true end return results end --Usage doesFileExist("levels.data") --Returns true/false --Or doesFileExist("levels.data", system.ResourceDirectory) --Returns true/false |
Get distance between two objects
This is a commonly needed function, it simply returns the distance between two objects
1 2 3 4 5 6 7 8 9 10 | local function getDistanceBetween(obj1, obj2) return math.ceil(math.sqrt( ((obj2.y - obj1.y) * (obj2.y - obj1.y)) + ((obj2.x - obj1.x) * (obj2.x - obj1.x)) )) end --Usage local plane = display.newRect(100, 100, 40, 40) local bird = display.newRect(200, 100, 40, 40) getDistanceBetween(plane, bird) --In this case it will return 100 |
Printing memory usage to the terminal
A lot of people ask how do i monitor my memory usage? Here is a handy function that will print it neatly to the terminal and format it so it is easy to understand.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | local function printMemUsage() local memUsed = (collectGarbage("count")) / 1000 local texUsed = system.getInfo( "textureMemoryUsed" ) / 1000000 print("\n---------MEMORY USAGE INFORMATION---------") print("System Memory Used:", string.format("%.03f", memUsed), "Mb") print("Texture Memory Used:", string.format("%.03f", texUsed), "Mb") print("------------------------------------------\n") return true end --Usage printMemUsage() --Best to call when you are finished changing scenes once |
Replies
How to make a Health Bar
If you are new to corona and wandered how to implement health bar to your game( for certain object or enemy), here's my little code:
1 2 3 4 5 | health_bar = display.newRect(0,0,200,10) health_bar:setReferencePoint(display.TopLeftReferencePoint) health_bar.x = 50; health_bar.y = 10 health_bar:setFillColor(0,255,0) gameGroup:insert(health_bar) |
Point is to change .xScale property of health_bar upon change of enemy's health or something like that, to achieve this we can use next function, presumable that enemy has .health = 100 property
1 2 3 4 5 6 7 8 9 10 11 12 | local function onTouch(self,event) -- this can be anything, touch, collision, enterFrame, whatever you want to make your enemy depleting health self.health = self.health - 10 -- or any amount of damage you need if self.health > 0 then health_bar.xScale = self.health *0.01 --this is simple math. equation that will help you reduce code end end enemy.touch = onTouch enemy:addEventListener("touch", enemy) |
May also be worth including the memory usage function here;
1 2 3 4 5 6 7 8 9 10 | local function monitorMem(event) collectgarbage("collect") print( "\nMemUsage: " .. (collectgarbage("count")/1000) .. " MB") print("Texture Usage " .. system.getInfo( "textureMemoryUsed" ) / 1000000) return true end Runtime:addEventListener("enterFrame", monitorMem) |
Peach :)
Everybody should know that the print function accepts comma separated values so you should never have to use the .. operator in a print function. This is much more efficient too because temporary strings don't have to be created and collected.
1 | print("Value of my bool = ", myBool) |
Wow Eric, I did not know that ever! Thanks for it!
"love the commas instead that crazy dots"
:-)
Print a LUA table, really useful during development / debug:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | print_r = function (t, name, indent) local tableList = {} function table_r (t, name, indent, full) local serial=string.len(full) == 0 and name or type(name)~="number" and '["'..tostring(name)..'"]' or '['..name..']' io.write(indent,serial,' = ') if type(t) == "table" then if tableList[t] ~= nil then io.write('{}; -- ',tableList[t],' (self reference)\n') else tableList[t]=full..serial if next(t) then -- Table not empty io.write('{\n') for key,value in pairs(t) do table_r(value,key,indent..'\t',full..serial) end io.write(indent,'};\n') else io.write('{};\n') end end else io.write(type(t)~="number" and type(t)~="boolean" and '"'..tostring(t)..'"' or tostring(t),';\n') end end table_r(t,name or '__unnamed__',indent or '','') end |
winning lottery numbers
10, 15, 32, 41, 44, 3
sorry couldn't help myself
Love this one too, I hate those crazy dot!!
This can get noisy and hard to navigate pretty soon. How about a wiki?
Added the following snippets:
Iterating through a key/pair table in order
Shuffling a table
Checking if a file exists
Get distance between two objects
Printing memory usage to the terminal
Stop 'print()' output when running on a device (improves performance) without removing the print statements in your code:
1 2 3 | if (system.getInfo("environment") == "device") then print = function() end end |
This may have been in a blog post somewhere, but I can't find it now.
using transition.to on a variable
myVal = { myCustomVal = 0 }
transition.to( myVal, { time = 1000, myCustomVal = 10000 })
Here's a great code snippet that can really help out in spotting unwanted Global variables creeping into your code (courtesy of Ntero):
1 2 3 4 5 | local function globalWatch(g, key, value) print("GlobalWatch --- ", tostring(key) .. " has been added to _G\n" .. debug.traceback()) rawset(g, key, value) end setmetatable(_G, { __index = globalWatch }) |
Originally posted by Ntero on http://developer.coronalabs.com/forum/2012/09/19/type-being-redefined#comment-124608
Naomi
Here's two that take advantage of Lua's Closures:
1 2 3 4 5 6 | local function generateCommand(funcPtr, ...) local temp = {n=select('#', ...), ...} return function() return funcPtr(unpack(temp, 1, temp.n)) end end |
This first one allows you to take a function, and a variable list of parameters (passed in as generateCommand(function, param1, param2, param3...) and creates a parameterless function that when called will call your original function with all params attached. It's very useful for creating all sorts of variables and linkages on initialization, and then just having behaviours attached to simple callbacks, without having to manage access to all the required parameters. Mostly I use this for button actions, to hookup the entire behaviour on creation but not have a dozen slightly different functions.
1 2 3 4 5 | local function wrapParam(funcPtr, param) return function(...) return funcPtr(param, ...) end end |
This one is similar to generateCommand, but it only attaches 1 parameter, and allows you to call the function with additional arguments. A good use case is if you want to have a Corona callback with a 'self' parameters, you can call onPress = wrapParam(self.myFunction, self), and now the Corona callback will be onPress(self, event), or any other parameters you need to attach, rather than just being stuck with the onPress(event) signature. this function can be chained together (pass the result of the function into another wrapParam), to attach multiple parameters.
Copies a table completely. Pass in a table, it returns a new, unique copy you can modify independently (instead of a typical reference, when assigning in lua).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | -- Creates a complete/deep copy of the data function deepCopy(object) local lookup_table = {} local function _copy(object) if type(object) ~= "table" then return object elseif lookup_table[object] then return lookup_table[object] end local new_table = {} lookup_table[object] = new_table for index, value in pairs(object) do new_table[_copy(index)] = _copy(value) end return setmetatable(new_table, getmetatable(object)) end return _copy(object) end |
Snagged this somewhere on the boards, it's fast, it's tight --- pure genius, it's a keeper. That table print up there looks pretty good too.... Hmmm...
I was banging my head against the wall trying to figure out how to use sqlite prepared statements, and I finally got it. Hopefully this small example will save someone some time.
1 2 3 4 5 6 7 8 9 | -- insert a new item into a specific set and return the id of the new item function createSetItem(theSetID,theSetItem) local stmt = db:prepare([[ INSERT INTO setItems (setID,item) VALUES (:pSetID, :pItem) ]]) stmt:bind_names({pSetID = theSetID, pItem = theSetItem}) stmt:step() local newID = db:last_insert_rowid() print("newID: ", newID) return newID end |
just in case you didn't notice, the comma adds a tab (or large space) between the first text and the following text. So, it's not the same as a concatenation .. of two strings.
Perhaps there if you used tostring(yourbool) it would concatenate your bool and string into a string.
print("Value of my bool = " .. tostring(myBool))










Here's a lua implementation of C's ternary operator:
for those who do not know, in C
can be written as
Corresponding lua implementation