So, I'm working on a small game in [url=http://love2d.org/]Love2D[/url] for an assignment. I have 5 days to complete the assignment, and I'm in a bit of a pickle. I'm using Love2D's physics system - [url=http://www.box2d.org/]Box2D[/url].
Right now, I'm working on a map editor. I intend for it to have 3 buttons - 1 to create a sphere, 1 to create a rectangle/box, and 1 to create a polygon. The polygon function is giving me some beef. At the moment, I'm storing the position of the mouse every time the user clicks. The [url=http://love2d.org/wiki/love.graphics.polygon]Polygon Draw[/url] function is nice, as it accepts a table instead of each point as an individual argument. The [url=http://love2d.org/wiki/love.physics.newPolygonShape]NewPolygon[/url] function isn't quite as nice.
My problem is that I need to be able to parse an unlimited number of args to [url=http://love2d.org/wiki/love.physics.newPolygonShape]NewPolygon[/url] function, but I haven't the slightest clue how. The position data for each point of the polygon [i]has[/i] to stay in a table, and I'd like to avoid hard coding the variables in.
I know Lua has support for [url=http://lua-users.org/wiki/FunctionCallTutorial]functions with unlimited arguments[/url], if that helps.
Here's some code just in case:
[lua]
function Game.PhysicsUpdate( delta )
if( not LClick ) then return end
-- LClick makes sure that this only executes once for every click
if( Poly[1] and Poly[2] ) then
-- Poly already exists, add to the values
Poly[#Poly + 1] = love.mouse.getX()
Poly[#Poly + 2] = love.mouse.getY()
if( #Poly < 6 ) then return end
-- Make sure there are at least 6 points before we create the poly
if( Vector( Poly[1], Poly[2] ):Distance( Vector( Poly[#Poly - 1], Poly[#Poly] ) ) < 5 ) then
Physics:NewPoly( Vector( love.mouse.getPosition() ), Poly, 400 )
end
else
-- No existing poly, set the initial values
Poly[1] = love.mouse.getX()
Poly[2] = love.mouse.getY()
end
end
function Physics:NewPoly( Pos, Table, Mass, Col )
if( not World ) then return end
if( #Bodies + 1 > 2048 ) then return end
Mass = Mass or 10
Size = Size or Vector( 20, 20 )
Col = Col or Color( 255, 255, 255, 255 )
local ind = #Bodies + 1
Bodies[ind] = love.physics.newBody( World, Pos.x, Pos.y, Mass )
Bodies[ind]:setPosition( Pos.x, Pos.y )
BData[ind] = {}
-- no idea what's going on here ^, I'm just initializing BData[ind] as a table
BData[ind].Color = Col
BData[ind].Type = PHYS_TYPE_POLY
Shapes[ind] = love.physics.newPolygonShape( Bodies[ind], Table[1], pairs( Table ) )
return Shapes[ind]
end
[/lua]
I know this would probably be more suited to the [i]Lua Scripting[/i] section, but from what I can see it's almost all GLua. I figure I'd have a better chance asking here, if a moderator disagrees, please move the thread.
I'm really stuck on this one, and I don't have much time before the project is due. Any and all help will be much appreciated.
The LOVE forums are also a great place for lua help.
And I think doing BData[Ind] = {} would clear the other data stored.
[QUOTE=Torquil;29145944]And I think doing BData[Ind] = {} would clear the other data stored.[/QUOTE]
Yup.
[editline].[/editline]
I'm not sure which version of lua love uses. However, the general way to do it is this
[lua]local function whatever(x,y, ... ) -- ... implies a list of arguments, which is how you have unlimited arguments
-- In some versions of lua, using ... automatically creates a variable called the "vararg" - a table containing all args.
-- Reference it using arg.
local args = {...} -- Create a table using all the arguments
for k , v in pairs(args) do
print(k,v)
-- k being the arg number (-2 because of the two predefined args) and v the value. Doing your parsing of args in this manner is way easier in a loop.
end
end[/lua]
Doesn't look like anyone actually read your question...
Anyway, you use [url=http://www.lua.org/manual/5.1/manual.html#pdf-unpack]unpack[/url]:
[lua]
love.physics.newPolygonShape(Bodies[ind], unpack(Table))
[/lua]
unpack takes a table with sequential integral keys (array) and puts all the values on the stack in order.
Imagine if Table had three keys; 1, 2 and 3. The above would then be equivalent of doing:
[lua]
love.physics.newPolygonShape(Bodies[ind], Table[1], Table[2], Table[3])
[/lua]
Another unpack example:
[lua]
local one, two = unpack{1, 2}
assert(one == 1 and two == 2)
[/lua]
An alternative is to receive the polygons as individual parameters instead of in a table:
[lua]
function Physics:NewPoly( Pos, Mass, Col, ... )
-- ...
love.physics.newPolygonShape(Bodies[ind], ...)
end
[/lua]
edit:
Also, you can add keys in a table literal, which arguably looks a lot neater:
[lua]
BData[ind] = {
Color = Col;
Type = PHYS_TYPE_POLY;
}[/lua]
(Finally, your call to setPosition is redundant)
[editline]13th April 2011[/editline]
[QUOTE=Torquil;29145944]
And I think doing BData[Ind] = {} would clear the other data stored.[/QUOTE]
Only if the value at key "ind" was already non-nil and no other references existed to that data. He's just creating a new entry. (Using three separate tables instead of just using one, for some reason)
I recommend using only one table so you have less keys to keep track of:
[lua]
local body = {}
Bodies[#Bodies + 1] = body
body.Body = love.physics.newBody( World, Pos.x, Pos.y, Mass )
body.Data = {
Color = Col;
Type = PHYS_TYPE_POLY;
}
body.Shape = love.physics.newPolygonShape( body.Body, unpack(Table) )
return body -- or body.Shape if you only wanted that
[/lua]
Thanks! That was exactly what I was looking for. Ultimately, NewPoly taking (...) would be ideal, but there would be no way to store all of the mouse positions.
love.physics.newBody() doesn't return a table, it returns another userdata type. I would love to be able to store color/typedata in one place a little more simply, but I was in a rush to get my little physics demo working.
I suppose I could do this:
[lua]
function Physics:NewSphere()
Shapes[#Shapes + 1] = {}
Shapes[#Shapes].Body = love.physics.newBody()
Shapes[#Shapes].Shape = love.physics.newCircleShape()
Shapes[#Shapes].Color = Color
return Shapes[#Shapes]
[/lua]
I spent most of the night cleaning the little redundancies up, but thanks. Have a heart.
That's exactly what my last code example does, except it uses a local variable for the table instead of looking it up in the Bodies table 5 times.
Sorry, you need to Log In to post a reply to this thread.