[SOLVED] Pivot line on the starting point

What i want to do is draw a strait line with my finger, then i want to be able to pivot the line at the starting point while the finger is still pressed on the screen and the line will still lengthen the further it gets from the starting point. Ive been racking my brain for a while now trying to figure out how to do this with keeping the line strait and pivoting it on the starting point. I tried doing display.newLine but i can’t manipulate the starting or ending x,y with touch events. So that is out of the picture i guess. I also tried all of these great line codes out there but i cant seem to get them to just draw a strait line to pivot and lengthen from point a to b. Also the line has an event listener on it. Any help would be greatly appreciated! I’ve been working at this for a while now, would love to move on haha. [import]uid: 126161 topic_id: 23481 reply_id: 323481[/import]

If anybody has any idea how to do this it would be greatly appreciated. This seems so simple and if i could change display.newLine’s x2,y2 on the fly during a moving touch event it would be very simple. I am pretty much out of ideas with how to do this. [import]uid: 126161 topic_id: 23481 reply_id: 94296[/import]

Well i solved the problem with making the line pivot and lenthen while remaining strait by using the following code

[lua]local physics = require (“physics”)
physics.start()
physics.setGravity (0,0)
physics.setDrawMode (“debug”)
local lines
local drawLine = function (event)
if event.phase == “moved” then
if lines == nil then
lines = display.newLine (event.xStart, event.yStart, event.x, event.y)
lines.width = 5
physics.addBody(lines, “kinematic”, {isSensor = true})
print (lines.contentWidth, lines.contentHeight)
else
display.remove(lines)
lines = nil
end

if event.phase == “ended” then
display.remove(lines)
lines = nil
end
end
end
Runtime:addEventListener (“touch”, drawLine)[/lua]

what i did not realize is that the lines physics box is a square, it is not the size of the line, that really throws a monkey wrench into my plans, i would like the box to stay the width of the line and grow with the length and pretty much be the same size as the line at all times but cant seem to change the box to fit what i need. Any Suggestions would be great
[import]uid: 126161 topic_id: 23481 reply_id: 94588[/import]

well with SteveK’s perfectly awesome code that uses newrect to take the place of newline i have almost got what i want, the only problem i am having now is the physics hybrid mode shows the physics box perfectly and everything looks great, using the code below and using collisions on multiple items, when the line is horizontal, everything works great but when i try to move the line vertically or diagonally, the physic shape looks good but the collisions are way off. Any advice for what could be causing this problem?
Here is the drag and drop code so you can see what i mean.

[lua]local physics = require (“physics”)
physics.start()
physics.setGravity (0,0)
physics.setDrawMode (“debug”)

local lineCol = function (event)
if event.phase == “began” then
display.remove(event.other)
event.other = nil
end
end

local lines
local newLine
local x1; local x2; local y1; local y2
local function drawLine2()

if x1 and x2 and y1 and y2 ~= nil then
if x1 > x2 then
x1, x2 = x2, x1
y1, y2 = y2, y1
end
local deltaX = x2 - x1
local deltaY = ( y1 < y2 ) and ( y2 - y1 ) or ( y1 - y2 )
local hypotenuse = math.sqrt( ( deltaX * deltaX ) + ( deltaY * deltaY ) )
local angle = math.deg( math.atan( deltaY / deltaX ) )
angle = ( y1 < y2 ) and angle or ( angle * -1 )

if newLine == nil then
newLine = display.newRect( x1, y1, hypotenuse, 4 )
newLine:setReferencePoint( display.CenterLeftReferencePoint )
newLine:setFillColor( 255, 0, 0 ); newLine.x = x1; newLine.y = y1; newLine:rotate( angle );
physics.addBody (newLine, {isSensor = true}); newLine: addEventListener (“collision”, lineCol)
else
display.remove (newLine)
newLine = nil
end
return newLine
end
end
Runtime: addEventListener (“enterFrame”, drawLine2)

local manuLine = function (event)
if event.phase == “moved” then
x1 = event.xStart; y1 = event.yStart; x2 = event.x; y2 = event.y
end
if event.phase == “ended” then
x1 = nil; y1 = nil; x2 = nil; y2 = nil
display.remove (newLine)
newLine = nil
end
end
Runtime: addEventListener (“touch”, manuLine)

local senTable = {}
for i = 1, 225 do
–ROW 1
if i <= 15 then
senTable[i] = display.newRect (0, 0, 8, 8)
senTable[i].x = i * 20; senTable[i].y = 120;
senTable[i]: setFillColor (0, 0, 0); senTable[i].alpha = 0.01;
–ROW 2
elseif i > 15 and i < 31 then
senTable[i] = display.newRect ( 0, 0, 8, 8)
senTable[i].x = (i * 20) - 300; senTable[i].y = 140;
senTable[i]: setFillColor (0, 0, 0); senTable[i].alpha = 0.01;
–ROW 3
elseif i > 30 and i < 46 then
senTable[i] = display.newRect ( 0, 0, 8, 8)
senTable[i].x = (i * 20) - 600; senTable[i].y = 160;
senTable[i]: setFillColor (0, 0, 0); senTable[i].alpha = 0.01;
–ROW 4
elseif i > 45 and i < 61 then
senTable[i] = display.newRect ( 0, 0, 8, 8)
senTable[i].x = (i * 20) - 900; senTable[i].y = 180;
senTable[i]: setFillColor (0, 0, 0); senTable[i].alpha = 0.01;
–ROW 5
elseif i > 60 and i < 76 then
senTable[i] = display.newRect ( 0, 0, 8, 8)
senTable[i].x = (i * 20) - 1200; senTable[i].y = 200;
senTable[i]: setFillColor (0, 0, 0); senTable[i].alpha = 0.01;
–ROW 6
elseif i > 75 and i < 91 then
senTable[i] = display.newRect ( 0, 0, 8, 8)
senTable[i].x = (i * 20) - 1500; senTable[i].y = 220;
senTable[i]: setFillColor (0, 0, 0); senTable[i].alpha = 0.01;
–ROW 7
elseif i > 90 and i < 106 then
senTable[i] = display.newRect ( 0, 0, 8, 8)
senTable[i].x = (i * 20) - 1800; senTable[i].y = 240;
senTable[i]: setFillColor (0, 0, 0); senTable[i].alpha = 0.01;
–ROW 8
elseif i > 105 and i < 121 then
senTable[i] = display.newRect ( 0, 0, 8, 8)
senTable[i].x = (i * 20) - 2100; senTable[i].y = 260;
senTable[i]: setFillColor (0, 0, 0); senTable[i].alpha = 0.01;
–ROW 9
elseif i > 120 and i < 136 then
senTable[i] = display.newRect ( 0, 0, 8, 8)
senTable[i].x = (i * 20) - 2400; senTable[i].y = 280;
senTable[i]: setFillColor (0, 0, 0); senTable[i].alpha = 0.01;
–ROW 10
elseif i > 135 and i < 151 then
senTable[i] = display.newRect ( 0, 0, 8, 8)
senTable[i].x = (i * 20) - 2700; senTable[i].y = 300;
senTable[i]: setFillColor (0, 0, 0); senTable[i].alpha = 0.01;
–ROW 11
elseif i > 150 and i < 166 then
senTable[i] = display.newRect ( 0, 0, 8, 8)
senTable[i].x = (i * 20) - 3000; senTable[i].y = 320;
senTable[i]: setFillColor (0, 0, 0); senTable[i].alpha = 0.01;
–ROW 12
elseif i > 165 and i < 181 then
senTable[i] = display.newRect ( 0, 0, 8, 8)
senTable[i].x = (i * 20) - 3300; senTable[i].y = 340;
senTable[i]: setFillColor (0, 0, 0); senTable[i].alpha = 0.01;
–ROW 13
elseif i > 180 and i < 196 then
senTable[i] = display.newRect ( 0, 0, 8, 8)
senTable[i].x = (i * 20) - 3600; senTable[i].y = 360;
senTable[i]: setFillColor (0, 0, 0); senTable[i].alpha = 0.01;
–ROW 14
elseif i > 195 and i < 211 then
senTable[i] = display.newRect ( 0, 0, 8, 8)
senTable[i].x = (i * 20) - 3900; senTable[i].y = 380;
senTable[i]: setFillColor (0, 0, 0); senTable[i].alpha = 0.01;
–ROW 15
elseif i > 210 and i < 226 then
senTable[i] = display.newRect ( 0, 0, 8, 8)
senTable[i].x = (i * 20) - 4200; senTable[i].y = 400;
senTable[i]: setFillColor (0, 0, 0); senTable[i].alpha = 0.01;
elseif i == 226 then
break
end
end
for k = 1, #senTable do
physics.addBody (senTable[k], “kinematic”, {isSensor = true})
end[/lua]

Any advice would be greatly appreciated! please! :slight_smile: [import]uid: 126161 topic_id: 23481 reply_id: 95319[/import]

I wish I had time to test your code. Maybe tomorrow. But what I would try then as an experiment would be to change the line 31 to be: newLine:setReferencePoint( display.CenterReferencePoint) When I did my Pinball Soccer game, I found that I had to rotate my flippers using a center reference point for the physics to work for collisions correctly. [import]uid: 23636 topic_id: 23481 reply_id: 95332[/import]

Thanks Bruce, i had read about not using a different reference point with physics objects but i guess when i copied the code over to test it i just didnt think about it, that is what is causing the problem with physics, but that reference point is also what is causing the draw line feature to work exactly how i want it to (minus the physics problems.) so i decided to try and go with a non physics collision, now when the line collides with a box, the collisions dont work sometimes also when i run a line vertical it works most of the time and when i run a line horizontal it works always but any form of diagonal starts taking out way more more than it should. Here is some plug and play code to show what i mean. any advice would be greatly appreciated.
[lua]local newLine
local senTable = {}
local x1; local x2; local y1; local y2
local function drawLine2()

if x1 and x2 and y1 and y2 ~= nil then
if x1 > x2 then
x1, x2 = x2, x1
y1, y2 = y2, y1
end
local deltaX = x2 - x1
local deltaY = ( y1 < y2 ) and ( y2 - y1 ) or ( y1 - y2 )
local hypotenuse = math.sqrt( ( deltaX * deltaX ) + ( deltaY * deltaY ) )
local angle = math.deg( math.atan( deltaY / deltaX ) )
angle = ( y1 < y2 ) and angle or ( angle * -1 )

if newLine == nil then
newLine = display.newRect( x1, y1, hypotenuse, 4 )
newLine:setReferencePoint( display.CenterLeftReferencePoint )
newLine:setFillColor( 255, 0, 0 ); newLine.x = x1; newLine.y = y1; newLine:rotate( angle );
else
display.remove (newLine)
newLine = nil
end
return newLine
end
end
Runtime: addEventListener (“enterFrame”, drawLine2)

local manuLine = function (event)
if event.phase == “moved” then
x1 = event.xStart; y1 = event.yStart; x2 = event.x; y2 = event.y
end
if event.phase == “ended” then
x1 = nil; y1 = nil; x2 = nil; y2 = nil
display.remove (newLine)
newLine = nil
end
end
Runtime: addEventListener (“touch”, manuLine)
–NON-PHYSICS COLLISION LISTENER (RECTANGLE)
local function hasCollided(obj1, obj2)
if obj1 == nil then
return false
end
if obj2 == nil then
return false
end

local left = obj1.contentBounds.xMin <= obj2.contentBounds.xMin and obj1.contentBounds.xMax >= obj2.contentBounds.xMin
local right = obj1.contentBounds.xMin >= obj2.contentBounds.xMin and obj1.contentBounds.xMin <= obj2.contentBounds.xMax
local up = obj1.contentBounds.yMin <= obj2.contentBounds.yMin and obj1.contentBounds.yMax >= obj2.contentBounds.yMin
local down = obj1.contentBounds.yMin >= obj2.contentBounds.yMin and obj1.contentBounds.yMin <= obj2.contentBounds.yMax
return (left or right) and (up or down)
end

local isCheckingCollisions = false
local function testCollisions ()
if isCheckingCollisions then
return true
end
isCheckingCollisions = true
for i=1, #senTable do
if hasCollided(senTable[i], newLine) then
–Collision functions go here!
display.remove (senTable[i])
senTable[i] = nil
end
end
isCheckingCollisions = false
return true
end
Runtime: addEventListener (“enterFrame”, testCollisions)

for i = 1, 225 do
–ROW 1
if i <= 15 then
senTable[i] = display.newRect (0, 0, 8, 8)
senTable[i].x = i * 20; senTable[i].y = 120;
–ROW 2
elseif i > 15 and i < 31 then
senTable[i] = display.newRect ( 0, 0, 8, 8)
senTable[i].x = (i * 20) - 300; senTable[i].y = 140;
–ROW 3
elseif i > 30 and i < 46 then
senTable[i] = display.newRect ( 0, 0, 8, 8)
senTable[i].x = (i * 20) - 600; senTable[i].y = 160;
–ROW 4
elseif i > 45 and i < 61 then
senTable[i] = display.newRect ( 0, 0, 8, 8)
senTable[i].x = (i * 20) - 900; senTable[i].y = 180;
–ROW 5
elseif i > 60 and i < 76 then
senTable[i] = display.newRect ( 0, 0, 8, 8)
senTable[i].x = (i * 20) - 1200; senTable[i].y = 200;
–ROW 6
elseif i > 75 and i < 91 then
senTable[i] = display.newRect ( 0, 0, 8, 8)
senTable[i].x = (i * 20) - 1500; senTable[i].y = 220;
–ROW 7
elseif i > 90 and i < 106 then
senTable[i] = display.newRect ( 0, 0, 8, 8)
senTable[i].x = (i * 20) - 1800; senTable[i].y = 240;
–ROW 8
elseif i > 105 and i < 121 then
senTable[i] = display.newRect ( 0, 0, 8, 8)
senTable[i].x = (i * 20) - 2100; senTable[i].y = 260;
–ROW 9
elseif i > 120 and i < 136 then
senTable[i] = display.newRect ( 0, 0, 8, 8)
senTable[i].x = (i * 20) - 2400; senTable[i].y = 280;
–ROW 10
elseif i > 135 and i < 151 then
senTable[i] = display.newRect ( 0, 0, 8, 8)
senTable[i].x = (i * 20) - 2700; senTable[i].y = 300;
–ROW 11
elseif i > 150 and i < 166 then
senTable[i] = display.newRect ( 0, 0, 8, 8)
senTable[i].x = (i * 20) - 3000; senTable[i].y = 320;
–ROW 12
elseif i > 165 and i < 181 then
senTable[i] = display.newRect ( 0, 0, 8, 8)
senTable[i].x = (i * 20) - 3300; senTable[i].y = 340;
–ROW 13
elseif i > 180 and i < 196 then
senTable[i] = display.newRect ( 0, 0, 8, 8)
senTable[i].x = (i * 20) - 3600; senTable[i].y = 360;
–ROW 14
elseif i > 195 and i < 211 then
senTable[i] = display.newRect ( 0, 0, 8, 8)
senTable[i].x = (i * 20) - 3900; senTable[i].y = 380;
–ROW 15
elseif i > 210 and i < 226 then
senTable[i] = display.newRect ( 0, 0, 8, 8)
senTable[i].x = (i * 20) - 4200; senTable[i].y = 400;
elseif i == 226 then
break
end
end[/lua] [import]uid: 126161 topic_id: 23481 reply_id: 95388[/import]

3dreams,

Yeah I realized afterwards that my quick response was wrong since it didn’t deal with your line’s position correctly. But I have more thoughts on it, so I will try some ideas today and let you know. [import]uid: 23636 topic_id: 23481 reply_id: 95403[/import]

Thanks bruce i would love to hear your thoughts on this, this is the last small part of a game i am making that is left to code before i can work on the levels, once i get this figured out i can have the game ready for the market within 3 days so any advice with my situation would be greatly appreciated. [import]uid: 126161 topic_id: 23481 reply_id: 95591[/import]

Copy and paste this code to try it out. Draw a straight line with your finger, then you can pivot the line at the starting point while the finger is still pressed on the screen and the line will still lengthen the further it gets from the starting point. And you can move the line in an arc so that collisions with your blocks will destroy them.

local physics = require ("physics")  
physics.start()  
physics.setGravity (0,0)  
--physics.setDrawMode ("hybrid")  
  
local Scene = display.newGroup();  
  
local bg = display.newRect(display.screenOriginX, display.screenOriginY, display.contentWidth - display.screenOriginX \* 2, display.contentHeight - display.screenOriginY \* 2) -- Cover the screen, no matter what size  
bg:setFillColor(174,173,159) --grey  
Scene:insert(bg);  
local lineCol = function (event)  
 if event.phase == "began" then  
 display.remove(event.other)  
 event.other = nil  
 end  
end  
   
local lines  
local newLine  
local visibleLine  
local x1; local x2  
local y1; local y2  
local visibleLineWidth = 8  
local bodyLineWidth = 18  
local polygonShape  
  
local function drawLine2()  
 if x1 and x2 and y1 and y2 ~= nil then  
 local deltaX = x2 - x1  
 local deltaY = ( y1 \< y2 ) and ( y2 - y1 ) or ( y1 - y2 )  
 local hypotenuse = math.sqrt( ( deltaX \* deltaX ) + ( deltaY \* deltaY ) )  
 local angle = math.deg( math.atan( deltaY / deltaX ) )  
 angle = ( y1 \< y2 ) and angle or ( angle \* -1 )  
  
 if visibleLine == nil then  
 visibleLine = display.newRect( x1, y1, hypotenuse, visibleLineWidth )  
 visibleLine:setFillColor( 255, 0, 0 )  
 Scene:insert(visibleLine)  
 end  
  
 if newLine == nil then  
 newLine = display.newRect( x1, y1, hypotenuse\*2, bodyLineWidth )  
 newLine:setReferencePoint( display.CenterReferencePoint )  
 newLine:setFillColor( 0, 0, 0 )  
 newLine.x = x1 --center on the starting point  
 newLine.y = y1 --center on the starting point  
 Scene:insert(1, newLine)  
  
 if x1 \> x2 then --put visible line to the left of center  
 visibleLine:setReferencePoint( display.CenterRightReferencePoint )  
 polygonShape = {-hypotenuse,-bodyLineWidth/2, 0,-bodyLineWidth/2, 0,bodyLineWidth/2, -hypotenuse,bodyLineWidth/2}  
 else --put visible line to the right of center  
 visibleLine:setReferencePoint( display.CenterLeftReferencePoint )  
 polygonShape = {0,-bodyLineWidth/2, hypotenuse,-bodyLineWidth/2, hypotenuse,bodyLineWidth/2, 0,bodyLineWidth/2}  
 end  
 transition.to(visibleLine, {time=1, width = hypotenuse, x = x1, y = y1, rotation = angle})  
  
 newLine.rotation = angle  
 physics.addBody(newLine, {density = 10, friction = 0, bounce = 0, shape = polygonShape })  
 newLine.isBullet = true  
 newLine: addEventListener ("collision", lineCol)  
 else  
 display.remove (newLine)  
 newLine = nil  
 end  
 return newLine  
 end  
end  
Runtime: addEventListener ("enterFrame", drawLine2)  
  
local manuLine = function (event)  
 if event.phase == "moved" then  
 x1 = event.xStart; y1 = event.yStart; x2 = event.x; y2 = event.y  
 end  
 if event.phase == "ended" then  
 x1 = nil; y1 = nil; x2 = nil; y2 = nil  
 display.remove (newLine)  
 display.remove (visibleLine)  
 newLine = nil  
 visibleLine = nil  
 end  
end  
Runtime: addEventListener ("touch", manuLine)  
   
local senTable = {}  
for i = 1, 225 do  
 --ROW 1  
 if i \<= 15 then  
 senTable[i] = display.newRect (0, 0, 8, 8)  
 senTable[i].x = i \* 20; senTable[i].y = 120;  
 --ROW 2  
 elseif i \> 15 and i \< 31 then  
 senTable[i] = display.newRect ( 0, 0, 8, 8)  
 senTable[i].x = (i \* 20) - 300; senTable[i].y = 140;  
 --ROW 3  
 elseif i \> 30 and i \< 46 then  
 senTable[i] = display.newRect ( 0, 0, 8, 8)  
 senTable[i].x = (i \* 20) - 600; senTable[i].y = 160;  
 --ROW 4  
 elseif i \> 45 and i \< 61 then  
 senTable[i] = display.newRect ( 0, 0, 8, 8)  
 senTable[i].x = (i \* 20) - 900; senTable[i].y = 180;  
 --ROW 5  
 elseif i \> 60 and i \< 76 then  
 senTable[i] = display.newRect ( 0, 0, 8, 8)  
 senTable[i].x = (i \* 20) - 1200; senTable[i].y = 200;  
 --ROW 6  
 elseif i \> 75 and i \< 91 then  
 senTable[i] = display.newRect ( 0, 0, 8, 8)  
 senTable[i].x = (i \* 20) - 1500; senTable[i].y = 220;  
 --ROW 7  
 elseif i \> 90 and i \< 106 then  
 senTable[i] = display.newRect ( 0, 0, 8, 8)  
 senTable[i].x = (i \* 20) - 1800; senTable[i].y = 240;  
 --ROW 8  
 elseif i \> 105 and i \< 121 then  
 senTable[i] = display.newRect ( 0, 0, 8, 8)  
 senTable[i].x = (i \* 20) - 2100; senTable[i].y = 260;  
 --ROW 9  
 elseif i \> 120 and i \< 136 then  
 senTable[i] = display.newRect ( 0, 0, 8, 8)  
 senTable[i].x = (i \* 20) - 2400; senTable[i].y = 280;  
 --ROW 10  
 elseif i \> 135 and i \< 151 then  
 senTable[i] = display.newRect ( 0, 0, 8, 8)  
 senTable[i].x = (i \* 20) - 2700; senTable[i].y = 300;  
 --ROW 11  
 elseif i \> 150 and i \< 166 then  
 senTable[i] = display.newRect ( 0, 0, 8, 8)  
 senTable[i].x = (i \* 20) - 3000; senTable[i].y = 320;  
 --ROW 12  
 elseif i \> 165 and i \< 181 then  
 senTable[i] = display.newRect ( 0, 0, 8, 8)  
 senTable[i].x = (i \* 20) - 3300; senTable[i].y = 340;  
 --ROW 13  
 elseif i \> 180 and i \< 196 then  
 senTable[i] = display.newRect ( 0, 0, 8, 8)  
 senTable[i].x = (i \* 20) - 3600; senTable[i].y = 360;  
 --ROW 14  
 elseif i \> 195 and i \< 211 then  
 senTable[i] = display.newRect ( 0, 0, 8, 8)  
 senTable[i].x = (i \* 20) - 3900; senTable[i].y = 380;  
 --ROW 15  
 elseif i \> 210 and i \< 226 then  
 senTable[i] = display.newRect ( 0, 0, 8, 8)  
 senTable[i].x = (i \* 20) - 4200; senTable[i].y = 400;  
-- elseif i == 226 then  
-- break  
 end  
  
 if i \< 226 then  
 physics.addBody (senTable[i], "static")  
 senTable[i].isBullet = true  
 senTable[i]:setFillColor( 0, 0, 0 )  
 senTable[i].alpha = 1  
 Scene:insert(senTable[i])  
 end  
end  
  

But notice that there is still a problem with some missed collisions when moving the line fast. There are other blog posts about this problem, and I don’t know the fool-proof answer. [import]uid: 23636 topic_id: 23481 reply_id: 95614[/import]

Bruce, you are the man. I had tried to set the physics shape but could not get it perfect, you did, you have set this up exactly the way i wanted it. As far as missing collisions while going fast, The user is encouraged to go slow and has no reason to go fast whatsoever so i don’t foresee that being a problem. Thank you so much, you helped me big time with this function! After a little tweaking, it fit perfectly in my code and words as expected. Thanks again! [import]uid: 126161 topic_id: 23481 reply_id: 95699[/import]

Great to hear that it works for you. I enjoyed the coding exercise. And now I’d like to create a game of my own using it somehow.
[import]uid: 23636 topic_id: 23481 reply_id: 95845[/import]