Hey guys,
I’m trying to use dynamic Edge Shape (Chain) Body - by drawing a line on the screen, then translate it to physic obj.
And while gravity works on it fine - the object is not rotateable. Even if I draw a line - it just stuck at the same orientation.
This kind of question is a perfect candidate for a mini-demo that you upload so we can download it, look at it, and run it. Just a main.lua file with the minimum set of code is enough.
In fact, you could probably demonstrate this in about 50 lines of code or less and then just paste it here between two sets of three-ticks
W=display.contentWidth;
H=display.contentHeight;
local physics=require("physics");
physics.setDrawMode("hybrid");
physics.start();
function newGroup(parent)
local mc = display.newGroup();
parent:insert(mc);
return mc
end
local bg=display.newRect(W/2,H/2,W*2,H*2);
bg:setFillColor(113/255/2, 170/255/2, 157/255/2);
local game = display.newGroup();
local face = display.newGroup();
local linemc;
local touchStarX, touchStarY;
bg:addEventListener("touch",function ( e )
if(e.phase == "began")then
linemc = display.newGroup();
game:insert(linemc)
touchStarX, touchStarY = e.x, e.y;
elseif(e.phase == "moved")then
local r = 4;
local rr = r*r;
local prev = linemc[linemc.numChildren];
if(prev)then
local dx, dy = prev.x - e.x, prev.y - e.y;
local dd = dx*dx + dy*dy;
if(dd<rr)then
return
end
end
local b = display.newCircle(linemc, e.x, e.y, 3);
b:setFillColor(8/10);
else
if linemc.numChildren > 1 then
local a1 = linemc[1];
local b = newGroup(game);
b.x, b.y = a1.x, a1.y;
local chain = {};
for i=1,linemc.numChildren do
local p = linemc[i];
table.insert(chain, p.x-b.x);
table.insert(chain, p.y-b.y);
end
for i=linemc.numChildren, 1, -1 do
local p = linemc[i];
b:insert(p);
p:translate(-b.x, -b.y)
end
physics.addBody(b, "dynamic",
{
chain = chain,
connectFirstAndLastChainVertex = false,
density = 1, friction = 0.1, bounce = 0.1
}
)
end
end
end);
for i=1,10 do
local b = display.newRect(game, 100+100*i, H-100, 50, 50);
physics.addBody(b, "static");
end
It helps because I generally find I can’t be sure the descriptions folks give correctly describe that goal(s) people have and the problem they are encountering. Communicating is hard. We always think we’re being clear, but then the folks reading what we say may interpret what we mean differently.
It is always better to have a run-able example demonstrating the issue. This is why I almost always provide a downloadable micro-project when talking about issues and examples.
Also, by forcing yourself to make such a demo one will often find the problem. i.e. By simplifying the issue and being forced to demonstrate it you get a second look at the problem that is often illuminating.
I’ll dump the code you pasted into a file and run it, then I’ll re-read your post and see if I can work out what isn’t working and if there is a solution. It will be a bit before I get to do this.
Originally (I believe) Box2D introduced the chain shape to allow users to make complex static shapes that have the ability to be collided with by other simple dynamic objects. These are often used for terrains and such, but have been used in many other clever cases. Note: The shape now supports all body types as you know.
These shapes may violate the ‘no concave’ shapes rule and thus have no definable inside or outside. Instead, collisions with these bodies are determined based on line versus shape collision calculations where the line is the nearby segment(s) of the chain shape.
If you’re familiar with collision detection calculations, you will know that handling arbitrary shapes can become immensely costly. This is probably the reason that the author(s) of Box2D placed some limitations on the shape. Those limitations are:
Body cannot rotate - You discovered this. Allowing it to rotate would require the Box2D code to calculate an an arbitrarily long sequence of line-segments ‘bodies’ every frame.
Chains don’t collide with other Chains - You may not have noticed this, but chains can’t register collisions with eachother.
Chains are best used for static bodies - While you can make them dynamic or kinematic, it is far better to use them as static ones.
So, how do you get a line-like shape that can also rotate?
You only have one option I can think of. Create a sequence of thin polygonal bodies attached to each other with joints. This is not a super solution as it can quickly get out of hand in terms of complexity and cost. It is also hard to make it look nice.
You may just have to suffer the ‘no rotation’ limitation and continue.
Shape Complexity Reduction - An optimization tip
Whether you go with joint-connected polygons or stick with chain shapes, you should probably consider reducing the number of verticies in your ‘line’. You can do this by converting to a spline and then using that list of vertices to draw you line.