Small Useful Functions

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
User avatar
I~=Spam
Party member
Posts: 206
Joined: Fri Dec 14, 2012 11:59 pm

Re: Small Useful Functions

Post by I~=Spam » Mon Jun 08, 2015 5:47 pm

I don't think this is usable because of the license because it is strait out of garry's mod client...
My Tox ID: 0F1FB9170B94694A90FBCF6C4DDBDB9F58A9E4CDD0B4267E50BF9CDD62A0F947E376C5482610

User avatar
Inny
Party member
Posts: 652
Joined: Fri Jan 30, 2009 3:41 am
Location: New York

Re: Small Useful Functions

Post by Inny » Fri Jun 26, 2015 1:18 am

I like coroutine.wrap, but it has the one deficiency that it eats errors and makes debugging coroutines hard. So this is my better version:

Code: Select all

local function error_wrap(co, err, ...)
  if err == false then
    io.stderr:write(debug.traceback(co))
    error(...)
  else
    return ...
  end
end

function COWRAP(start)
  local co = coroutine.create(start)
  return function(...)
    return error_wrap(co, coroutine.resume(co, ...))
  end
end

User avatar
HugoBDesigner
Party member
Posts: 403
Joined: Mon Feb 24, 2014 6:54 pm
Location: Somewhere in Brazil
Contact:

Re: Small Useful Functions

Post by HugoBDesigner » Mon Jul 06, 2015 8:10 pm

I ran on a few problems with my translation functions I previously posted here:
viewtopic.php?p=185159#p185159 (last page of this very thread)

It turns out that, the way I had it set up, would make multiple translations in the same push/pop stop working. It wouldn't crash the game, but rather glitch out things like scissors and other translations further ahead. Here's the fi:xed version, though. Same functionalities, nothing changed:

Code: Select all

_translate = love.graphics.translate
_translateX, _translateY = {0}, {0}
_translateCounter = {0}
_pop = love.graphics.pop
_push = love.graphics.push
_origin = love.graphics.origin
_scissor = love.graphics.setScissor

function love.graphics.pop()
	for i = 1, _translateCounter[#_translateCounter] do
		table.remove(_translateX)
		table.remove(_translateY)
	end
	table.remove(_translateCounter)
	_pop()
end

function love.graphics.push()
	table.insert(_translateCounter, 0)
	_push()
end

function love.graphics.translate(x, y)
	table.insert(_translateX, x)
	table.insert(_translateY, y)
	_translateCounter[#_translateCounter] = _translateCounter[#_translateCounter] + 1
	_translate(x, y)
end

function love.graphics.getTranslation()
	return love.graphics.getTranslationX(), love.graphics.getTranslationY()
end

function love.graphics.getTranslationX()
	local x = 0
	for i, v in ipairs(_translateX) do
		x = x + v
	end
	return x
end

function love.graphics.getTranslationY()
	local y = 0
	for i, v in ipairs(_translateY) do
		y = y + v
	end
	return y
end

function love.graphics.origin()
	for i = 1, _translateCounter[#_translateCounter] do
		_translateX[#_translateX - (i-1)] = 0
		_translateY[#_translateY - (i-1)] = 0
	end
	_origin()
end

function love.graphics.setScissor(x, y, w, h)
	if x and type(x) == "number" then
		x = x + love.graphics.getTranslationX()
	end
	if y and type(y) == "number" then
		y = y + love.graphics.getTranslationY()
	end
	_scissor(x, y, w, h)
end
HugoBDesigner - my Twitter
HugoBDesigner - my Blog

User avatar
ejmr
Party member
Posts: 302
Joined: Fri Jun 01, 2012 7:45 am
Location: South Carolina, U.S.A.
Contact:

Re: Small Useful Functions

Post by ejmr » Wed Jul 08, 2015 1:34 am

A utility to map a function to all values in a table, which also supports partial application.

Code: Select all

function table.map(f, t)
    local function apply(values)
        local results = {}
        for index,value in pairs(values) do
            results[index] = f(value)
        end
        return results
    end

    if t then
        return apply(t)
    else
        return apply
    end
end
A detailed explanation of the code and its uses.
ejmr :: Programming and Game-Dev Blog, GitHub
南無妙法蓮華經

User avatar
Ref
Party member
Posts: 676
Joined: Wed May 02, 2012 11:05 pm

Re: Small Useful Functions

Post by Ref » Mon Jul 13, 2015 2:01 am

Was playing around with the Box2D tut and found that it is difficult to read the text which was being printed to the screen. The text string is erased when a fixed number of characters are in the string.

My first attempt was to remove the first line of text when a fixed number of characters was reached. Worked but since the number of characters per line varies, the number of lines on the screen varied.

The following code compares the number of lines in the string (as defined by '\n') and deletes the appropriate number of lines from the top to insure only a fixed number of lines will be shown. Works but someone probably has a better function. For debugging, efficiency not too important.

Code: Select all

function scrollText( text, limit )	-- retain only most recent lines (limit determines number)
	local limit, numlines, location = limit or 20, 0, {}
	location[0]	= 0
	while true do
		location[ numlines+1 ]		= string.find( text, "\n", location[numlines] + 1 )
		if location[ numlines+1 ]	== nil then
			break
			else
			numlines = numlines + 1
			end
		end
	if numlines > limit then
		text = string.sub( text, location[ numlines - limit ], #text )
		end
	return text
	end
test

Code: Select all

text = ' line 7\n line 6\n line 5\n line 4\n line 3\n line 2\n line 1\n'
text = scrollText( text, 5 )
print( text )

 line 5
 line 4
 line 3
 line 2
 line 1

User avatar
s-ol
Party member
Posts: 1076
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: Small Useful Functions

Post by s-ol » Mon Jul 13, 2015 11:20 am

Ref wrote:Was playing around with the Box2D tut and found that it is difficult to read the text which was being printed to the screen. The text string is erased when a fixed number of characters are in the string.
-snip-
[/code]
You can use font:getWrap() to find how mans lines text will take up when drawn and wrapped at a certain width (using love.graphics.printf).

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end

User avatar
Ref
Party member
Posts: 676
Joined: Wed May 02, 2012 11:05 pm

Re: Small Useful Functions

Post by Ref » Mon Jul 13, 2015 6:35 pm

Hi Soillos!
Thanks for response.
I'm doing something much less sophisticated.
Not wrapping text, just breaking up a string containing data lines separated by '\n' and only displaying the last # lines.
That way the last entry is always at the same spot on the screen with the last # data lines above it.
(Inefficient process creating multiple new string every time new data added.)
Makes it easy to see who is colliding with what and when it is released.

Obviously other ways to do this (like putting the data into a table) but just trying to patch a existing Box2D tut to help learn love.physics.

User avatar
bakpakin
Party member
Posts: 114
Joined: Sun Mar 15, 2015 9:29 am
Location: Boston

Re: Small Useful Functions

Post by bakpakin » Mon Jul 13, 2015 6:59 pm

First post in this thread.

Here's some code I wrote for getting the intersection of two lines (not line segments).
The lines run from (x1, y1) to (x2, y2) and (x3, y3) to (x4, y4).
Returns false if there is no intersection (i.e. they're parallel), otherwise returns the coordinate of intersection.

Code: Select all

function intersect(x1, y1, x2, y2, x3, y3, x4, y4)
    local x21, x43 = x2 - x1, x4 - x3
    local y21, y43 = y2 - y1, y4 - y3
    local d = x21 * y43 - y21 * x43
    if d == 0 then return false end
    local xy34 = x3 * y4 - y3 * x4
    local xy12 = x1 * y2 - y1 * x2
    local a = xy34 * x21 - xy12 * x43
    local b = xy34 * y21 - xy12 * y43
    return a / d, b / d
end
I'm pretty sure this can be modified to do segment to segment intersection.
((_((_CRAYOLA_((_((_> GitHub <_((_((_CRAYOLA_((_(()

davisdude
Party member
Posts: 1154
Joined: Sun Apr 28, 2013 3:29 am
Location: North Carolina

Re: Small Useful Functions

Post by davisdude » Mon Jul 13, 2015 7:06 pm

*Shameless self-promotion*
I didn't do it that way, but if you want to you can take a look at how I got segment intersections here.
Most of the library will soon undergo a rewrite as I wrote most of the functions a couple of years ago and they may not be extremely efficient as I wasn't too advanced in math, so if you have a suggestion, feel free to suggest/make a pull request.
GitHub | MLib - Math and shape intersections library | Walt - Animation library | Brady - Camera library with parallax scrolling | Vim-love-docs - Help files and syntax coloring for Vim

User avatar
Nixola
Inner party member
Posts: 1940
Joined: Tue Dec 06, 2011 7:11 pm
Location: Italy

Re: Small Useful Functions

Post by Nixola » Mon Jul 13, 2015 7:18 pm

Code: Select all

function isBetween(n, min, max)
    if min > max then
        min, max = max, min
    end
    return (n >= min) and (n <= max)
end

function intersect(x1, y1, x2, y2, x3, y3, x4, y4)
    local x21, x43 = x2 - x1, x4 - x3
    local y21, y43 = y2 - y1, y4 - y3
    local d = x21 * y43 - y21 * x43
    if d == 0 then return false end
    local xy34 = x3 * y4 - y3 * x4
    local xy12 = x1 * y2 - y1 * x2
    local a = xy34 * x21 - xy12 * x43
    local b = xy34 * y21 - xy12 * y43
    return a / d, b / d
end

function intersectL(x1, y1, x2, y2, x3, y3, x4, y4)
    local xi, yi = intersect(x1, y1, x2, y2, x3, y3, x4, y4)
    if isBetween(xi, x1, x2) and isBetween(yi, y1, y2) and isBetween(xi, x3, x4) and isBetween(yi, y3, y4) then
        return xi, yi
    end
    return false
end
lf = love.filesystem
ls = love.sound
la = love.audio
lp = love.physics
lt = love.thread
li = love.image
lg = love.graphics

Post Reply

Who is online

Users browsing this forum: Exabot [Bot] and 69 guests