Page 1 of 2

Attaching multiple shapes to fixture and setting an image

Posted: Sun Aug 12, 2012 5:24 pm
by geocine
I created a code from this example. https://love2d.org/wiki/Tutorial:Physics

I want to replace the ball object so I created a pig object, I used a program to compute multiple polygon shapes that will be used for my particular object.

Here is my image.
rXc3s.png
rXc3s.png (17.9 KiB) Viewed 616 times
Here is my code

Code: Select all

	imagePig = love.graphics.newImage("queen_pig.png")
	--let's create the pig
	objects.pig = {}
	objects.pig.body = love.physics.newBody(world, 1024/2, 768/2, "dynamic")
	objects.pig.image = imagePig
	objects.pig.shapes = {
			love.physics.newPolygonShape(9, 46, 8, 44, 8, 38,  14, 36, 11, 46),
			love.physics.newPolygonShape(-33, 14,  -31, 13,  -21, 22,  -33, 17),
			love.physics.newPolygonShape(23, 22,  23, 26,  21, 34,  5, 27,  20, 20),
			love.physics.newPolygonShape(-32, 29,  -36, 24,  -36, 19,  -33, 17,  -21, 22,  -26, 29),
			love.physics.newPolygonShape(28, 17,  20, 20,  28, 12),
			love.physics.newPolygonShape(-17, 37,  -17, 28,  -14, 25,  -3, 27,  -3, 37,  -6, 40,  -12, 40),
			love.physics.newPolygonShape( 8, 38,  7, 33,   14, 36),
			love.physics.newPolygonShape(26, 28,  26, 30,  21, 34,  23, 26),
			love.physics.newPolygonShape(5, 31,  5, 27,  21, 34,  14, 36  ,  7, 33),
			love.physics.newPolygonShape( 21, 41,  19, 41,  14, 36,  21, 34),
			love.physics.newPolygonShape(-17, 25,  -21, 22,  -37, -19,  31, 10,  28, 12,  -14, 25),
			love.physics.newPolygonShape(-29, -29,  -12, -35,  10, -35,  21, -32,  31, 10,  -37, -19 ),
			love.physics.newPolygonShape(32, 34,  32, 36,  21, 34,  26, 30),
			love.physics.newPolygonShape( -36, 8,  -39, 0,  -39, -11  ,  -37, -19,  -21, 22,  -31, 13),
			love.physics.newPolygonShape(34, -21,  37, -12,  36, 1,  31, 10,  21, -32,  28, -28),
			love.physics.newPolygonShape(20, 20,  5, 27,  -3, 27,  -14, 25,  28, 12)
			
		}
	for i=0, table.getn(objects.pig.shapes) do
      objects.pig.fixtures[i] = love.physics.newFixture(objects.pig.body, objects.pig.shapes[i],2)
	  objects.pig.fixtures[i]:setRestitution(0.9) --let the pig to bounce
    end
I tried to store the ploygon shapes into a table/array. Then loop through each shape and add a new fixture for each shape. However I get this error on this line:

Code: Select all

objects.pig.fixtures[i] = love.physics.newFixture(objects.pig.body, objects.pig.shapes[i],2)
Incorrect parameter type: expected userdata

When drawing the ball , the example used this code.

Code: Select all

love.graphics.circle("fill", objects.ball.body:getX(), objects.ball.body:getY(), objects.ball.shape:getRadius())
Now, how do I draw my image with the multiple polygons set? I just don't want it to be a plain circle even though this pig image could actually be a circle.

To make this simple I want to accomplish something like the image below:
lvVRV.png
lvVRV.png (21.06 KiB) Viewed 616 times

Re: Attaching multiple shapes to fixture and setting an imag

Posted: Sun Aug 12, 2012 5:33 pm
by OmarShehata
I believe the problem is in your loop here:

Code: Select all

for i=0, table.getn(objects.pig.shapes) do
Tables in Lua start at 1, not 0. So shapes where i is 0 is not defined, and produces an error.

Starting at i=1 should fix this problem.

Re: Attaching multiple shapes to fixture and setting an imag

Posted: Sun Aug 12, 2012 5:40 pm
by geocine
Thanks Omar,
I updated the code to:

Code: Select all

   objects.pig.fixtures ={}
	for i=1, table.getn(objects.pig.shapes) do
      objects.pig.fixtures[i] = love.physics.newFixture(objects.pig.body, objects.pig.shapes[i],2)
	  objects.pig.fixtures[i]:setRestitution(0.9) --let the ball bounce
    end
Now, how do I see my pig?

When drawing the ball , the example used this code.

Code: Select all

    love.graphics.circle("fill", objects.ball.body:getX(), objects.ball.body:getY(), objects.ball.shape:getRadius())

Re: Attaching multiple shapes to fixture and setting an imag

Posted: Sun Aug 12, 2012 6:01 pm
by Robin
In love.load(), create a new image, like so:

Code: Select all

pigImage = love.graphics.newImage("pig.png")
And replace that call to love.graphics.circle with

Code: Select all

love.graphics.draw(pigImage, objects.ball.body:getX(), objects.ball.body:getY())
Except you'll probably have another body for it, but yeah.

See documentation for love.graphics.newImage, love.graphics.draw and Image

Re: Attaching multiple shapes to fixture and setting an imag

Posted: Sun Aug 12, 2012 6:07 pm
by Boolsheet
table.getn is moving into the deprecated area. Use the length operator # instead:

Code: Select all

for i = 1, #objects.pig.shapes do
-- ...
end
First, I suggest you draw the polygons themselves just to make sure they are where you expect them to be.

Code: Select all

for i = 1, #objects.pig.shapes do
	love.graphics.polygon("line", objects.pig.body:getWorldPoints(objects.pig.shapes[i]:getPoints()))
end
And to extend Robin's example:

Code: Select all

love.graphics.draw(imagePig, objects.pig.body:getX(), objects.pig.body:getY(), objects.pig.body:getAngle(), 1, 1, imagePig:getWidth()/2, imagePig:getHeight()/2)
This assumes that the body origin is supposed to be in the center of the image. The last two arguments are the offsets and using the image size divided by two there will make it rotate around the center.

Re: Attaching multiple shapes to fixture and setting an imag

Posted: Mon Aug 13, 2012 2:12 am
by geocine
Thanks Robin and Boolsheet.

I tried to draw my polygon and my image using Boolsheet's code. Here is what it looks like. Seems that the polygon is inverted . How do I fix the polygon so that it snaps into the image?

I just want to draw the polygons along with the image for debugging purposes. If I do that though, the body rotates within the center of the image. The image does not rotate with the body.

Code: Select all

for i = 1, #objects.pig.shapes do
   love.graphics.polygon("line", objects.pig.body:getWorldPoints(objects.pig.shapes[i]:getPoints()))
end

Code: Select all

love.graphics.draw(imagePig, objects.pig.body:getX(), objects.pig.body:getY(), objects.pig.body:getAngle(), 1, 1, imagePig:getWidth()/2, imagePig:getHeight()/2)
XHhTj.png
XHhTj.png (16.87 KiB) Viewed 617 times

Re: Attaching multiple shapes to fixture and setting an imag

Posted: Mon Aug 13, 2012 4:54 am
by Boolsheet
This depends on how you got the polygons in the first place. Box2D describes its coordinate system where positive Y goes up. In LÖVE's coordinate system, positive Y goes down. If you use an application that targets Box2D, it will expect the system of Box2D and the shapes appear upside down if you draw them directly in LÖVE.

If you're lucky, you can just multiply all the Y coordinates of the polygon shapes with -1.

Re: Attaching multiple shapes to fixture and setting an imag

Posted: Mon Aug 13, 2012 11:51 am
by geocine
Hi Boolsheet, thanks for the reply. I multiplied every Y point to -1 and it worked.

Last, could you help me center the image to the body. Here is my .love file.

Re: Attaching multiple shapes to fixture and setting an imag

Posted: Mon Aug 13, 2012 1:29 pm
by Boolsheet
Use the offset arguments of love.graphics.draw to get it aligned. Increase the Y offset some more, I guess.

I don't know how you got the polygons. If it's an application it probably also had some kind of offset or assumed the center of the image and the flipping of Y messed that up. Not sure what to recommend beside trial and error. :P

Re: Attaching multiple shapes to fixture and setting an imag

Posted: Mon Aug 13, 2012 6:21 pm
by geocine
Thanks Boolsheet. I have updated my exporter template which generates these polygons. Now I have the exact body I needed.

I am now using these polygons:

Code: Select all

love.physics.newPolygonShape(  12.00, -40.50  ,  15.00, -30.50  ,  9.00, -32.50  ,  9.00, -38.50  ,  10.00, -40.50 ),
love.physics.newPolygonShape(  -32.00, -11.50  ,  -20.00, -16.50  ,  -30.00, -7.50  ,  -32.00, -8.50 ),
love.physics.newPolygonShape(  21.00, -14.50  ,  6.00, -21.50  ,  22.00, -28.50  ,  24.00, -20.50  ,  24.00, -16.50 ),
love.physics.newPolygonShape(  -25.00, -23.50  ,  -20.00, -16.50  ,  -32.00, -11.50  ,  -35.00, -13.50  ,  -35.00, -18.50  ,  -31.00, -23.50 ),
love.physics.newPolygonShape(  29.00, -6.50  ,  21.00, -14.50  ,  29.00, -11.50 ),
love.physics.newPolygonShape(  -11.00, -34.50  ,  -5.00, -34.50  ,  -2.00, -31.50  ,  -2.00, -21.50  ,  -13.00, -19.50  ,  -16.00, -22.50  ,  -16.00, -31.50 ),
love.physics.newPolygonShape(  15.00, -30.50  ,  8.00, -27.50  ,  9.00, -32.50 ),
love.physics.newPolygonShape(  24.00, -20.50  ,  22.00, -28.50  ,  27.00, -24.50  ,  27.00, -22.50 ),
love.physics.newPolygonShape(  8.00, -27.50  ,  15.00, -30.50  ,  22.00, -28.50  ,  6.00, -21.50  ,  6.00, -25.50 ),
love.physics.newPolygonShape(  22.00, -28.50  ,  15.00, -30.50  ,  20.00, -35.50  ,  22.00, -35.50 ),
love.physics.newPolygonShape(  -13.00, -19.50  ,  29.00, -6.50  ,  32.00, -4.50  ,  -36.00, 24.50  ,  -20.00, -16.50  ,  -16.00, -19.50 ),
love.physics.newPolygonShape(  -36.00, 24.50  ,  32.00, -4.50  ,  22.00, 37.50  ,  11.00, 40.50  ,  -11.00, 40.50  ,  -28.00, 34.50 ),
love.physics.newPolygonShape(  27.00, -24.50  ,  22.00, -28.50  ,  33.00, -30.50  ,  33.00, -28.50 ),
love.physics.newPolygonShape(  -30.00, -7.50  ,  -20.00, -16.50  ,  -36.00, 24.50  ,  -38.00, 16.50  ,  -38.00, 5.50  ,  -35.00, -2.50 ),
love.physics.newPolygonShape(  29.00, 33.50  ,  22.00, 37.50  ,  32.00, -4.50  ,  37.00, 4.50  ,  38.00, 17.50  ,  35.00, 26.50 ),
love.physics.newPolygonShape(  29.00, -6.50  ,  -13.00, -19.50  ,  -2.00, -21.50  ,  6.00, -21.50  ,  21.00, -14.50 )
And here is how it looks like. Neat.
4ut5W.png
4ut5W.png (25.33 KiB) Viewed 619 times
Thanks Omar for directing me to codeandweb. Thanks Boolsheet for helping me throughout. I added Karma to both of you.