In sense the following should work, just add the following to init.lua :
[As a note, try placing the Sbody:update() in love.update as-well for consistency)
Code: Select all
function Sbody:setRadius(r)
--brute force method
if not self.dead then
local r = math.max(4,r)
local x,y = self.sourceBody:getPosition()
local world = self.world
local tess = #self.tess or 2;
self.tess = {};
for i=1, tess do
self.tess[i] = {};
end
for i = #self.nodes, 1, -1 do
self.nodes[i].body:destroy();
self.nodes[i] = nil;
end
self.nodes = {}
self.sourceShape:setRadius(r*4)
local nodes = r/2;
for node = 1, nodes do
local angle = (2*math.pi)/nodes*node;
local posx = x+r*math.cos(angle);
local posy = y+r*math.sin(angle);
local b = love.physics.newBody(world, posx, posy, "dynamic");
local f = love.physics.newFixture(b, self.nodeShape);
f:setFriction(30);
f:setRestitution(0);
b:setAngularDamping(50);
local j = love.physics.newDistanceJoint(self.sourceBody, b, posx, posy, posx, posy, true);
j:setDampingRatio(0.1);
j:setFrequency(12*(20/r));
table.insert(self.nodes, {body = b, fixture = f, joint = j});
end
for i = 1, #self.nodes do
if i < #self.nodes then
local j = love.physics.newDistanceJoint(self.nodes[i].body, self.nodes[i+1].body, self.nodes[i].body:getX(), self.nodes[i].body:getY(),
self.nodes[i+1].body:getX(), self.nodes[i+1].body:getY(), false);
self.nodes[i].joint2 = j;
end
end
local i = #self.nodes;
local j = love.physics.newDistanceJoint(self.nodes[i].body, self.nodes[1].body, self.nodes[i].body:getX(), self.nodes[i].body:getY(),
self.nodes[1].body:getX(), self.nodes[1].body:getY(), false);
self.nodes[i].joint3 = j;
self:update()
end
end
function Sbody:update()
if not self.dead then
local pos = {};
for i = 1, #self.nodes, self.smooth do
v = self.nodes[i];
table.insert(pos, v.body:getX());
table.insert(pos, v.body:getY());
end
tessellate(pos, self.tess[1]);
for i=1,#self.tess - 1 do
tessellate(self.tess[i], self.tess[i+1]);
end
end
end
[specs]
OS : Windows 7 64
RAM : 8GB
CPU : intel i5 3.20 & 3.60 GHz
GCard : Geforce GTX 650
The hit to FPS while scaling Radius constantly by 1 up and down every love.update() call :
from a radius of ~48 with tess at 1 and smoothing at 1, a constant increase to ~82 at a rate of 1 per frame caused a tank of 38.FPS from a original of 59
decreasing back to ~48 at the same rate brings the FPS up to 59 again,
it seems this affects the radius perfectly without tanking too hard (since i get the same FPS of ~38 if i spawn my player with a radius of 82)
The only issue to arise is that the user can glitch through objects (like a floor) since the nodes will be shifted and created over the floor, but perhaps this should be up to the user to compensate for since its a matter of moving the player as is.
I also have this snippet, since moving the softBody.sourceBody alone using setPosition is messy :
Code: Select all
function Sbody:translate(x,y)
self.sourceBody:setPosition(self.sourceBody:getX()+x,self.sourceBody:getY()+y)
for k,v in pairs(self.nodes) do
v.body:setPosition(v.body:getX()+x,v.body:getY()+y)
end
end