• Announcement: Lua.org now officially recommends this forum as a meeting place for the Lua community

Share your code! (1 Viewer)

Hello and welcome!

If you made or found any functions or any other useful things that can be used in Love2D please share right here. All you have found or made should not be licensed under any circumstances or should be protected by an open source licence so please do not try to sell anything here.

I would really like to see more people hanging around here. I hope that the Administrator will successfully promote this site.

Thanks.
 

younyokel

Newcomer
Joined
Jan 8, 2020
Messages
16
Reaction score
19
Age
19
Location
Kazakhstan
Website
stackoverflow.com
Here's the function that allows you to draw a nineslice. So, the nineslice is a sprite that will be cropped into nine smaller images and drawn in any given sizes. Just use this function in love.draw, that's it.

To use it, you need to insert an image or user data in a place of first argument. This image need to square and its size should be still integer after dividing it to 3. Other 4 arguments (x1, y1, x2, y2) are positions where you need it to be drawn.

Created and tested on LOVE 11.3.0 - Mysterious Mysteries.
Lua:
function DrawNineslice(image, x1, y1, x2, y2)
    local NinesliceImage = type(image) == 'userdata' and image or type(image) == 'string' and love.graphics.newImage(image)
    
    local SpriteWidth, SpriteHeight = NinesliceImage:getWidth(), NinesliceImage:getHeight()
    local NinesliceWidth, NinesliceHeight = SpriteWidth / 3, SpriteHeight / 3
    
    local Width, Height = x2 - x1 < SpriteWidth and SpriteWidth or x2 - x1, y2 - y1 < SpriteHeight and SpriteHeight or y2 - y1

    local NinesliceQuad = {
        -- Top
        [1] = love.graphics.newQuad(0, 0, NinesliceWidth, NinesliceHeight, NinesliceImage:getDimensions()),
        [2] = love.graphics.newQuad(NinesliceWidth, 0, NinesliceWidth, NinesliceHeight, NinesliceImage:getDimensions()),
        [3] = love.graphics.newQuad(NinesliceWidth * 2, 0, NinesliceWidth, NinesliceHeight, NinesliceImage:getDimensions()),
        
        -- Middle
        [4] = love.graphics.newQuad(0, NinesliceHeight, NinesliceWidth, NinesliceHeight, NinesliceImage:getDimensions()),
        [5] = love.graphics.newQuad(NinesliceWidth, NinesliceHeight, NinesliceWidth, NinesliceHeight, NinesliceImage:getDimensions()),
        [6] = love.graphics.newQuad(NinesliceWidth * 2, NinesliceHeight, NinesliceWidth, NinesliceHeight, NinesliceImage:getDimensions()),
        
        -- Bottom
        [7] = love.graphics.newQuad(0, NinesliceHeight * 2, NinesliceWidth, NinesliceHeight, NinesliceImage:getDimensions()),
        [8] = love.graphics.newQuad(NinesliceWidth, NinesliceHeight * 2, NinesliceWidth, NinesliceHeight, NinesliceImage:getDimensions()),
        [9] = love.graphics.newQuad(NinesliceWidth * 2, NinesliceHeight * 2, NinesliceWidth, NinesliceHeight, NinesliceImage:getDimensions())
    }

    -- Top
    love.graphics.draw(NinesliceImage, NinesliceQuad[1], x1, y1)
    love.graphics.draw(NinesliceImage, NinesliceQuad[2], x1 + NinesliceWidth, y1, 0, (Width - NinesliceWidth * 2) / NinesliceWidth, 1)
    love.graphics.draw(NinesliceImage, NinesliceQuad[3], x1 + (Width - NinesliceWidth), y1)

    -- Middle
    love.graphics.draw(NinesliceImage, NinesliceQuad[4], x1, y1 + NinesliceHeight, 0, 1, (Height - NinesliceHeight * 2) / NinesliceHeight)
    love.graphics.draw(NinesliceImage, NinesliceQuad[5], x1 + NinesliceWidth, y1 + NinesliceHeight, 0, (Width - NinesliceWidth * 2) / NinesliceWidth, (Height - NinesliceHeight * 2) / NinesliceHeight)
    love.graphics.draw(NinesliceImage, NinesliceQuad[6], x1 + (Width - NinesliceWidth), y1 + NinesliceHeight, 0, 1, (Height - NinesliceHeight * 2) / NinesliceHeight)

    -- Bottom
    love.graphics.draw(NinesliceImage, NinesliceQuad[7], x1, y1 + (Height - NinesliceHeight))
    love.graphics.draw(NinesliceImage, NinesliceQuad[8], x1 + NinesliceWidth, y1 + (Height - NinesliceHeight), 0, (Width - NinesliceWidth * 2) / NinesliceWidth, 1)
    love.graphics.draw(NinesliceImage, NinesliceQuad[9], x1 + (Width - NinesliceWidth), y1 + (Height - NinesliceHeight))
end

Thanks.
 

younyokel

Newcomer
Joined
Jan 8, 2020
Messages
16
Reaction score
19
Age
19
Location
Kazakhstan
Website
stackoverflow.com
Here's some useful mathematics functions. I wasn't able to found some of these functions built in when I was just starting to learn Lua. They actually can be used not only in Love2D but in just Lua too.

Created and tested on LOVE 11.3.0 - Mysterious Mysteries.
Code:
function sign(number)
    return number > 0 and 1 or number == 0 and 0 or -1
end
This function returns a number you inserted as an argument and clamps it if it is negative it will be -1, if zero it will be 0, and if positive it will be 1.

Code:
function clamp(number, minimum, maximum)
    return number < minimum and minimum or number > maximum and maximum or number
end
The function above clamps the number between minimum and maximum.

Code:
function bool(argument)
    return argument and 1 or 0
end
In some programming languages boolean variables can be read by a program as if they were numbers. Like this: 1 is true, 0 is false.

Code:
function round(number)
    return number >= 0 and math.floor(number + 0.5) or math.ceil(number - 0.5)
end

function round_fraction(number, fraction)
    return round(number * fraction) / fraction
end
The function called round() obviously rounds the number you have inserted as argument. These two functions work almost the same, except that the second function will round the number to the fraction you need.

Thanks.
 

younyokel

Newcomer
Joined
Jan 8, 2020
Messages
16
Reaction score
19
Age
19
Location
Kazakhstan
Website
stackoverflow.com
Here, some simple string function I made recently. You can use them if you're making a text-based game.

Created and tested on LOVE 11.3.0 - Mysterious Mysteries.
Lua:
function insertString(string, insert, position)
    return string.sub(string, 1, position) .. insert .. string.sub(string, position + 1)
end
This function inserts a given string into another one, Don't mix up the string and insert arguments. The second argument is a string you want to insert inside the first one.

Lua:
function deleteString(string, from, to)
    return string.sub(string, 1, from - 1) .. (j ~= nil and string.sub(string, from + to) or string.sub(string, from + 1))
end
This one deletes a string from position from till position to. Also, if you're going to skip the to argument, it will remove only one character from the given string.

Lua:
function countString(string, toCount)
    local i, j = 0, 0

    while j < string.len(string) do
        if string.sub(string, j, j + string.len(toCount) - 1) == toCount then
            i = i + 1
        end
        j = j + 1
    end

    return i
end
This is a useful function which counts a given string toCount in a given string. Yes, you could use a string.find instead of this, but I noticed that it returns only 2 outputs maximum.

Thanks.
 

younyokel

Newcomer
Joined
Jan 8, 2020
Messages
16
Reaction score
19
Age
19
Location
Kazakhstan
Website
stackoverflow.com
Here you go: a simple string whitespace trimming function:

Created and tested on LOVE 11.3.0 - Mysterious Mysteries.
Lua:
function trimString(s)
    return (s:gsub('%s+', ' '):gsub('^%s*(.-)%s*$', '%1'):gsub('%s*\\n%s*', '\n'))
end
This function returns a string you've entered as a single argument with multiple spaces deleted from it, one-line space at the start and at the end of the string, including the space around the linebreak sign which is marked as \n. This function uses patterns.
 
Last edited:

GavinW

Newcomer
Creator of RiscLua
Joined
Oct 21, 2020
Messages
41
Reaction score
17
Age
82
Location
UK
Website
www.wra1th.plus.com
Here is another kind of duality. One uses patterns to extract data from strings (the functions string.match, string.gmatch etc), and format-strings (with the function string.format) to pack the data back into a string. If you find your program bloated with instances of the word "format" you can get rid of them by inserting the line (getmetatable "").__call = string.format somewhere at the start of your program. This effectively turns format strings into functions, so you can remove all the subsequent instances of :format.
 

dinsdale247

Moderator
Staff member
Community Patron
Creator of WinLua
Joined
Nov 17, 2020
Messages
93
Reaction score
32
Location
Victoria BC
Website
winlua.net
Here is another kind of duality. One uses patterns to extract data from strings (the functions string.match, string.gmatch etc), and format-strings (with the function string.format) to pack the data back into a string. If you find your program bloated with instances of the word "format" you can get rid of them by inserting the line (getmetatable "").__call = string.format somewhere at the start of your program. This effectively turns format strings into functions, so you can remove all the subsequent instances of :format.
My brain exploded. Can you give us an example in 5.3/5.4?
 

GavinW

Newcomer
Creator of RiscLua
Joined
Oct 21, 2020
Messages
41
Reaction score
17
Age
82
Location
UK
Website
www.wra1th.plus.com
Lua:
-- Two ways to insert into strings
do -- awesome hack
  local SM = getmetatable ""
  SM.__mod = function (s, t) return s:gsub ("%$([%w_]+)", t) end
  SM.__call = string.format
end -------------------------------
local print = print
-- Pythonesque
local x = "$head and $tail."
print (x % { head = "this"; tail = "that"; }) --> this and that.
-- fonctionesque
local y = "%s and %s."
print (y ("this", "that"))                     --> this and that.
 

dinsdale247

Moderator
Staff member
Community Patron
Creator of WinLua
Joined
Nov 17, 2020
Messages
93
Reaction score
32
Location
Victoria BC
Website
winlua.net
Lua:
-- Two ways to insert into strings
do -- awesome hack
  local SM = getmetatable ""
  SM.__mod = function (s, t) return s:gsub ("%$([%w_]+)", t) end
  SM.__call = string.format
end -------------------------------
local print = print
-- Pythonesque
local x = "$head and $tail."
print (x % { head = "this"; tail = "that"; }) --> this and that.
-- fonctionesque
local y = "%s and %s."
print (y ("this", "that"))                     --> this and that.
I was looking for a templating library for creating dynamic web forms (asp.net razor if you will). This example makes me think I might pull that project out again.

One could even do substitutions and then generate scripts with further substitutions. meta....
 

Loggy

Newcomer
Joined
Dec 16, 2020
Messages
11
Reaction score
2
A simple library to call.

Call the chunk by:

Lua:
local split,kpairs,dump,tSize,variables,tcopy,round,koncat,grep,file_exists,create_userdata = dofile "library.lua" -- or wherever it is stored
 

Attachments

  • forumLibrary.lua
    10.2 KB · Views: 2

dinsdale247

Moderator
Staff member
Community Patron
Creator of WinLua
Joined
Nov 17, 2020
Messages
93
Reaction score
32
Location
Victoria BC
Website
winlua.net
A simple library to call.

Call the chunk by:

Lua:
local split,kpairs,dump,tSize,variables,tcopy,round,koncat,grep,file_exists,create_userdata = dofile "library.lua" -- or wherever it is stored
1608182621316.png
Short nose 45 Caliber handgun. BIG boom.

tSize is great. I couldn't make variables work in the interactive interpreter?
 

Loggy

Newcomer
Joined
Dec 16, 2020
Messages
11
Reaction score
2
Which Lua? I usually use luajit (2.1.0-beta3) or my Ubuntu 18.04 LTS platform default is lua 5.2. I've never tried it on Windoze.

I only use interactive Lua to check little ideas so I've never thought to use variables() that way. :)

I use it in code where there is a puzzling error to check I haven't been inadvertently accessing an upvalue. It can be useful when using lualanes as well to check that I am not assuming globals/upvalues which either may not exist or may have the wrong values.

My current work used to use torch threads rather than Lanes, which was very good and would bundle upvalues into the thread, but it was easy to accidentally carry junk around I didn't need. The good thing about threads was that it pre-loaded the thread so all processes were alive - Lanes loads a process for each invocation and you have to synchronise the process yourself but that way I award virtual threads > hardware threads (32 on my system) and let the scheduler cope. Works better IMHO.

When using threading I always have a threads=0 ie unthreaded case to use in development.
 
Top