--# Main supportedOrientations(LANDSCAPE_RIGHT) displayMode(OVERLAY) -- CodeaBalls -- Use this function to perform your initial setup function setup() edge1 = physics.body( EDGE, vec2(0,0), vec2(WIDTH,0) ) edge1.type = STATIC edge1.sleepingAllowed = false edge2 = physics.body( EDGE, vec2(WIDTH,0), vec2(WIDTH,HEIGHT) ) edge2.type = STATIC edge2.sleepingAllowed = false edge3 = physics.body( EDGE, vec2(WIDTH,HEIGHT), vec2(0,HEIGHT) ) edge3.type = STATIC edge3.sleepingAllowed = false edge4 = physics.body( EDGE, vec2(0,HEIGHT), vec2(0,0) ) edge4.type = STATIC edge4.sleepingAllowed = false BTest = Ball(WIDTH/2,HEIGHT/2,80,2,3) parameter.boolean("debugBall",false) parameter.number("DampingRato",0.5,30,3,function(v) BTest:setDamping(v) end) parameter.number("Frequency",0.5,30,2,function(v) BTest:setFrequency(v) end) end -- This function gets called once every frame function draw() -- This sets a dark background color background(0, 184, 255, 255) -- This sets the line thickness strokeWidth(BTest.radius/3) stroke(0, 120, 255, 255) if debugBall then strokeWidth(5) fill(255, 0, 0, 0) else fill(0,100,235,255) end for i = 1,4 do local edg = _G["edge"..i] line(edg.points[1].x,edg.points[1].y,edg.points[2].x,edg.points[2].y) end -- Do your drawing here BTest:draw(debugBall) physics.gravity(Gravity) end --# Ball Ball = class() function Ball:init(x,y,radius,damping,frequency) -- the position we will create the softbody at self.x, self.y = x or 0, y or 0 -- the radius of the entire softbody self.radius = radius or 124 -- the amount of outer nodes local nodes = self.radius/4 -- the frequency and damping of our physics self.damping = damping or 0.4 self.frequency = frequency or 0.8 -- lets create our center body and store it in a table self.centerNode = physics.body( CIRCLE, 32 ) self.centerNode.x, self.centerNode.y = self.x, self.y self.centerNode.sleepingAllowed = false -- next lets create our outer nodes and store them in a table self.outerNodes = {} for node = 1, nodes do -- the angle from the center body to the outer node local angle = (2 * math.pi) / nodes * node -- get the position of the new node using the angle and radius as offset local nodeX = self.x + self.radius * math.cos(angle) local nodeY = self.y + self.radius * math.sin(angle) -- create our body and fix our shape to it local nodeBody = physics.body( CIRCLE,self.radius/6 ) nodeBody.x, nodeBody.y = nodeX, nodeY nodeBody.sleepingAllowed = false --[[ now lets connect the node to the center body with a distanceJoint you may notice we use the same position for both anchor points of the joint I personally find this creates a much better outcome, as the outer nodes stay in rotation with the center body --]] local nodeJoint = physics.joint( DISTANCE, nodeBody, self.centerNode, vec2(nodeX, nodeY), vec2(nodeX, nodeY) ) -- next lets set the damping and frequency nodeJoint.frequency, nodeJoint.dampingRatio = self.frequency, self.damping -- and finally, lets add everything to the outerNodes table table.insert(self.outerNodes, {body = nodeBody, joint = nodeJoint}) end -- lets iterate over the nodes for i = 1, #self.outerNodes do -- we get two nodes, the one on this iteration and the following node local nodeA = self.outerNodes[i] -- get the node following i local nodeB = self.outerNodes[(i % #self.outerNodes) + 1] -- create a distanceJoint between the two nodes, this time with no frequency or damping nodeA.joint2 = physics.joint( DISTANCE, nodeA.body, nodeB.body, nodeA.body.position, nodeB.body.position ) end end function Ball:setFrequency(frec) for k,node in ipairs(self.outerNodes) do node.joint.frequency = frec end end function Ball:setDamping(damp) for k,node in ipairs(self.outerNodes) do node.joint.dampingRatio = damp end end function Ball:draw(dbg) if dbg then ellipseMode(RADIUS) ellipse( self.centerNode.x, self.centerNode.y, self.centerNode.radius) for k,node in ipairs(self.outerNodes) do ellipse( node.body.x, node.body.y, node.body.radius ) if not self.outerNodes[k+1] then tnode = self.outerNodes[1] else tnode = self.outerNodes[k+1] end line( node.body.x, node.body.y, tnode.body.x, tnode.body.y ) end else for i=1,#self.outerNodes do local node, tnode = self.outerNodes[i] if not self.outerNodes[i+1] then tnode = self.outerNodes[1] else tnode = self.outerNodes[i+1] end if not node.mesh then node.mesh = mesh() end node.mesh.vertices = { node.body.position, self.centerNode.position, tnode.body.position } node.mesh:setColors(fill()) node.mesh:draw() line( node.body.x, node.body.y, tnode.body.x, tnode.body.y ) end end end