Page 4 of 5

Re: Share your favourite helper functions

Posted: Wed Nov 21, 2012 4:40 am
by Nsmurf
More snippets on my blog!

This time point-object collisions. They're fairly simple, but still quite useful functions.

Re: Share your favourite helper functions

Posted: Fri Nov 23, 2012 3:33 am
by substitute541
I got (physics, and electricity) based snippets on my blog.

Re: Share your favourite helper functions

Posted: Fri Nov 23, 2012 10:18 am
by vrld
Proxy tables for lazy loading of resources:

Code: Select all

local function Proxy(f)
	return setmetatable({}, {__index = function(t,k)
		local v = f(k)
		t[k] = v
		return v
	end})
end
Doesn't look like much, but is very, very useful:

Code: Select all

State = Proxy(function(path) return require('states.' .. path) end)
Gamestate.switch(State.menu)

Image = Proxy(function(path) return love.graphics.newImage('img/'..path..'.png') end)
love.graphics.draw(Image.powerup, x,y)

-- nested proxy
Font  = Proxy(function(arg)
	if tonumber(arg) then return love.graphics.newFont(arg) end
	return Proxy(function(size) return love.graphics.newFont('font/'..arg..'.ttf', size) end)
end)
love.graphics.setFont(Font[20])
love.graphics.setFont(Font.slkscr[25])
Interrupt:

Code: Select all

function Interrupt(info)
	local old = {}
	local base = info.__base or love
	info.__base = nil
	for k,v in pairs(info) do
		old[k]  = base[k]
		base[k] = function(...)
			return v(old[k], ...)
		end
	end

	return function()
		for k,v in pairs(info) do
			base[k] = old[k]
		end
	end
end
To make a simple pause screen:

Code: Select all

local continue -- this part is a little weird though :/
continue = Interrupt{
	update = function() end,
	keypressed = function(_, key)
		if key == 'p' then continue() end
	end,
	draw = function(draw)
		draw()
		love.graphics.setColor(0,0,0,200)
		love.graphics.rectangle('fill', 0,0, SCREEN_WIDTH, SCREEN_HEIGHT)
		love.graphics.setColor(120, 255, 120)
		love.graphics.setFont(Font.slkscr[40])
		love.graphics.printf('PAUSE', 0,SCREEN_HEIGHT/2-20, SCREEN_WIDTH, 'center')
	end
}

Re: Share your favourite helper functions

Posted: Fri Nov 23, 2012 11:37 am
by Roland_Yonaba
Useful indeed. I used a similar function to the nested proxy (for font loading) in my assets loader. Which was, after all, inspired by your Proxy function.

Inspiraception ?

Re: Share your favourite helper functions

Posted: Fri Nov 23, 2012 10:06 pm
by stout
I don't know if this counts, and there is probably a better way to do this, but

Code: Select all

local total = 0 -- initialize/clear the variable
for rowIndex, row in ipairs(worldMap) do
	for columnIndex, quadID in ipairs(row) do
		if quad ~= 1 then
			total = total + 1 -- increase total for every non-ocean tile
		end
	end
end
if total > 50 then -- if there at least this many non-ocean tiles then allow next step
-- next step(s)
I'd been wanting to come up with a way of determining if a certain percentage of tiles in the tilemap were non-ocean/"blank", and this is how I did it. In this case my ocean tiles are 1, and 2, 3, etc are other things. Originally I was going to go through and add the tiles together, but then realized that higher-value tiles would throw that off. Could easily be adapted for string-based tilemaps, and the total check could be made into a variable percentage rather than a static number.

Re: Share your favourite helper functions

Posted: Sat Nov 24, 2012 1:08 pm
by Ubermann
This is something like an alarm clock.

It basically counts the time passed and "ticks" when passed XXXX seconds.

Its made of two functions: the first to count the time, the second to watch the time passed:

VARIABLES NEEDED:

Code: Select all

oneTick = 0 -- time will be added to this
tickHappened = false -- when a tick happens, set this to true
alarm = 1 -- set alarm to 1 second
COUNT THE TIME ( usually in love.update() ):

Code: Select all

function countTime()
    oneTick = oneTick + love.timer.getDelta() -- ad time passed to our counter
    watchTicks() -- this function will watch the ticks and tell you when a tick passed
end
WATCH TICKS AND ALARM ( usually in your basic app functions .lua ):

Code: Select all

function watchTicks()
    if oneTick >= alarm then -- if time passed is > or = to alarm then...
        tickHappened = true -- ring the bell
        oneTick = 0 -- restart tick time counter
    else
        tickHappened = false -- if time passed is not > or = to the alarm, then the tick didn't happen
    end
end

Pretty simple algorithm but really useful.
Also remember that the "alarm" is only active for one deltaTime, so if you need to do some events after XXXX time, but only once before the next event, this is perfect for you.

Re: Share your favourite helper functions

Posted: Sat Nov 24, 2012 3:28 pm
by Ref
Cubic spline fit of data points.
Nothing original. Just an adaption to Lua.

Code: Select all

function cubicSpline( tab, nsteps )
	-- Original Basic version by Charles O'Neill 2002
	-- 'tab' is original table of { x, y } values
	-- 'x' values don't have to be uniformly spaced
	-- 'spline' is the returned table of calculated {x,y} pairs
	local nsteps = nsteps or 10		-- number of points-1 created btw initial points
	local A, B, C, D, h, S = {}, {}, {}, {}, {}, {}
	for i = 1, #tab-1  do			-- width of each 'x' interval
		h[i] = tab[i+1][1] - tab[i][1]
		end
	for i = 1, #tab - 2 do
		A[i] = h[i+1]
		B[i] = h[i]
		C[i] = 6 * (( tab[i+2][2] - tab[i+1][2])/h[i+1] - (tab[i+1][2] - tab[i][2]) / h[i])
		D[i] = 2 * ( h[i] + h[i+1] )
		end
	ntdma = #tab - 2				-- tdma = Tre-Diagonal-Matrix-Algorithm
	for i = 2, ntdma do
		local R = B[i] / D[i-1]
		C[i] = C[i] - R * C[i-1]
		D[i] = D[i] - R * A[i-1]
		end
	C[ntdma] = C[ntdma] / D[ntdma]
	for i = ntdma - 1, 1, -1 do
		C[i] = (C[i] - A[i] * C[i+1]) / D[i]
		end
	for i = 2, #tab - 1 do			-- changes from zero based index to 1
		S[i] = C[i-1]		-- S is the second derivative
		end
	S[1], S[#tab] = 0, 0			-- set end coordinates
	for i = 1, #tab - 1 do			-- calculate cubic coordinates
		A[i] = (S[i+1] - S[i]) / (6 * h[i] )
		B[i] = S[i] / 2
		C[i] = (tab[i+1][2] - tab[i][2]) / h[i] - (2 * h[i] * S[i] + h[i] * S[i+1]) / 6
		D[i] = tab[i][2]
		end
	local spline, count = {}, 1
	for i = 1, #tab - 1 do
		for j = 1, nsteps do
			local x		= tab[i][1] + ( h[i] / nsteps ) * ( j - 1 )
			local dif		= x - tab[i][1]
			local y	        = A[i] * dif ^ 3 + B[i] * dif ^ 2 + C[i] * dif + D[i]
			spline[count]    = { floor(x), floor(y) }
			count		= count + 1
			end
		end
	spline[ #spline + 1 ] = { tab[ #tab ][ 1 ], tab[ #tab ][ 2 ] } -- adds last point to table
	return spline
	end
Edited: as per Robin's comments

Re: Share your favourite helper functions

Posted: Sat Nov 24, 2012 10:00 pm
by Robin
FYI,
Ref wrote:

Code: Select all

	local A = {} B = {} C = {} D = {} h = {} S = {}
Ref wrote:

Code: Select all

		j = i - 1 -- three times!
Ref wrote:

Code: Select all

		R = B[i] / D[i-1]
B, D, D, h, S, j and R are all globals here.

Re: Share your favourite helper functions

Posted: Sun Nov 25, 2012 10:13 pm
by Ref
Robin wrote:FYI,B, D, D, h, S, j and R are all globals here.
Thanks Robin for pointing out my error.
Question:
Are a,b,c local if you use local a,b,c = {},{},{} or do you have to specify each one local separately?

Re: Share your favourite helper functions

Posted: Mon Nov 26, 2012 1:53 am
by Inny
vrld wrote:Proxy tables for lazy loading of resources:

Code: Select all

local function Proxy(f)
	return setmetatable({}, {__index = function(t,k)
		local v = f(k)
		t[k] = v
		return v
	end})
end
Just out of curiosity, why did you use "Proxy" to name that function instead of Memoize?