• Love2D function parsing problem
    5 replies, posted
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.