Infinite Rope Length

Hi, I am try to make a rope that is attached to a two ends, one end is at the top of the screen and the other is attached to a yoyo.

The effect i want to achieve is that when the yoyo is moved (using the directional keys) the ‘rope’ moves along with it for example if the down arrow is pressed, then the rope extends to the new position of the yoyo yet still being fixed at both ends.

The way i am currently doing this is that i have a runtime listener on enterframe which creates a new rope depending on the x and y position of the yoyo, however by doing this i have a blinking rope effect (due the the removing and re-creating of the display.newLine).

I am wondering if there is any other way of implementing such effect without the blinking effect i.e. a solid white rope?

Heres my code if anyone doesn’t understand my problem:
[lua]display.setStatusBar (display.HiddenStatusBar)
– Hides the status bar
_W = display.contentWidth
_H = display.contentHeight

local background = display.newImage (“jungle_bkg.png”)
– Sets the background

local yoyo= display.newRect( 0, 0, 50, 50 )
yoyo.x = 240
yoyo.y = 160
yoyo:setFillColor(100, 230, 255)

local top = display.newRect( 0, 0, 10, 10 )
top.x = _W/2
top.y = 0
top:setFillColor(135, 255, 100)


local up = display.newImageRect( “up.png”, 40, 50 )
up.x = 100
up.y = 190

local down = display.newImageRect( “down.png”, 40, 50 )
down.x = 100
down.y = 270

local left = display.newImageRect( “left.png”, 50, 40 )
left.x = 60
left.y = 230

local right = display.newImageRect( “right.png”, 50, 40 )
right.x = 140
right.y = 230
– Puts in all four movement arrow images and positions them

local motionx = 0
local motiony = 0
local speed = 10

local function stop (event)
if event.phase ==“ended” then
motionx = 0
motiony = 0
end
end

Runtime:addEventListener(“touch”, stop )
– When no arrow is pushed, this will stop me from moving.

local function moveYoyo (event)
yoyo.x = yoyo.x + motionx
yoyo.y = yoyo.y + motiony
end

Runtime:addEventListener(“enterFrame”, moveYoyo)
– When an arrow is pushed, this will make me move.

function up:touch()
motionx = 0
motiony = -speed
end
up:addEventListener(“touch”, up)

function down:touch()
motionx = 0
motiony = speed
end
down:addEventListener(“touch”, down)

function left:touch()
motionx = -speed
motiony = 0
end
left:addEventListener(“touch”,left)

function right:touch()
motionx = speed
motiony = 0
end
right:addEventListener(“touch”,right)

– The above four functions are stating the arrows should all listen for touches and defining
– the way I should move based on each touch.
function DrawLine()
if line then
line:removeSelf()
line = nil
else
line = display.newLine(top.x, top.y, yoyo.x, yoyo.y )
–line:setColor(math.random(255), math.random(255), math.random(255))
line.width = 10
end
end

Runtime:addEventListener(“enterFrame”, DrawLine)

–drawline creates a line[/lua]

Thanks :slight_smile: [import]uid: 34863 topic_id: 29838 reply_id: 329838[/import]

cleankeepersgames - that code will lead to a spectacular crash as there is a new *additional* line drawn every frame.

What you meant is code like this:

[lua]…

function DrawLine()
if line then
line:removeSelf()
line = nil

line = display.newLine(top.x, top.y, yoyo.x, yoyo.y )
line.width = 10
end

end

Runtime:addEventListener(“enterFrame”, DrawLine)

…[/lua] [import]uid: 160496 topic_id: 29838 reply_id: 119710[/import]

Hi. My solution is for your problem :

...  
  
local line  
  
function DrawLine()   
 if line then  
 line:removeSelf()  
 line = nil  
 end  
  
 line = display.newLine(top.x, top.y, yoyo.x, yoyo.y )  
 --line:setColor(math.random(255), math.random(255), math.random(255))  
 line.width = 10   
end  
   
Runtime:addEventListener("enterFrame", DrawLine)  
  
...  

It’s mean Always draw line. Don’t leave blank just after remove the previous line. This is cause your blinking. [import]uid: 171206 topic_id: 29838 reply_id: 119705[/import]

@mike470

I don’t think so. It will work something like that :

  
1st call of DrawLine() :   
line variable not assigned (null), so nothing to delete. And draw the line. Line variable is assigned.  
  
2nd call of DrawLine() :   
line variable assigned (not null), so delete it. And draw the new line. Line variable is assigned.  
  
3rd call of DrawLine() :   
line variable assigned (not null), so delete it. And draw the new line. Line variable is assigned.  
  
...  
  

Any extra line will not draw. At the moment only one line will be.
But your version :
Have you tried it in your simulator. It will not draw any line.

=======================

SORRY mike470!!!

I just missed

local line  

this. But I edited it. Anyway. [import]uid: 171206 topic_id: 29838 reply_id: 119718[/import]

You’re right, I was a bit confused there :slight_smile:

But anyway - it is not a good idea to erase/draw a line *every* frame. Should be doing that only when coordinates need to be changed. [import]uid: 160496 topic_id: 29838 reply_id: 119721[/import]

Thanks for the help guys. using the code that cleankeepersgames suggested, the blinking of the line itself has gone. However as mike470 suggested it isn’t a good idea to draw the line, however how can i implement a method where the coordinates change accordingly with the line? [import]uid: 34863 topic_id: 29838 reply_id: 119739[/import]

ive been having a go on trying to figure this out, so far i believe the only way in which i can do it WITHOUT creating new lines every “enterFrame” is by using the touch event:

[lua]function up:touch(event)
if event.phase == “began” then
motionx = 0
motiony = -speed

myLine = nil

if ( myLine ) then
myLine:removeSelf() – erase previous line, if any
myLine = nil
end

myLine = display.newLine( top.x, top.y, yoyo.x, yoyo.y )
myLine:setColor( 255, 255, 255, 50 )
myLine.width = 16

end
up:addEventListener(“touch”, up)[/lua]

however this will only work when the player moves their finger (whilst its held down) on the up arrow key, i want that the line is connected to the top and the yoyo even when the up arrow is not pressed, and when the arrow is pressed, the yoyo moves and the line (whilst its still connected) moves along with it

any ideas guys?

p.s. the fix that cleankeepergames suggested still blinks on low performance phones, that is not because of the code, but the phones ability to keep creating/disposing lines with a limited CPU power. [import]uid: 34863 topic_id: 29838 reply_id: 119892[/import]

have a couple of variables (local to the module) for the coordinates of the end of the rope. Define, local again, lastRopeX and lastRopeY. In the “enterFrame” function, compare the end of the rope vars with lastRopeX and lastRopeY and, if different, redraw the rope. Then set the lastRopeX and lastRopeY to the end of rope coords. [import]uid: 160496 topic_id: 29838 reply_id: 119909[/import]

do you mean like this:

[lua]local lastRopeX = 150
local lastRopeY = 150

function drawLine()
local myLine
if (yoyo.x ~= lastRopeX or yoyo.y ~= lastRopeY) then
myLine = display.newLine( top.x,top.y, yoyo.x,yoyo.y )
myLine:setColor( 255, 255, 255)
myLine.width = 16

lastRopeX = yoyo.x
lastRopeY = yoyo.y

else
myLine:removeSelf() – erase previous line, if any
myLine = nil
end
end[/lua]

ive set lastRopeX and lastRopeY to 150 as if i didnt assign a value then it would give me a runtime error…however the problem i am getting is another runtime error but due to the removal of myLine set to nil [import]uid: 34863 topic_id: 29838 reply_id: 119946[/import]

[lua]local lastRopeX = math.huge
local lastRopeY = math.huge
local myLine=nil

local function drawLine()
if (yoyo.x ~= lastRopeX or yoyo.y ~= lastRopeY) then
display.remove(myLine); myLine=nil
myLine = display.newLine( top.x,top.y, yoyo.x,yoyo.y )
myLine:setColor( 255)
myLine.width = 16

lastRopeX, lastRopeY = yoyo.x, yoyo.y
end
end[/lua]
– call drawLine from your “enterFrame” listener [import]uid: 160496 topic_id: 29838 reply_id: 119976[/import]

cleankeepersgames - that code will lead to a spectacular crash as there is a new *additional* line drawn every frame.

What you meant is code like this:

[lua]…

function DrawLine()
if line then
line:removeSelf()
line = nil

line = display.newLine(top.x, top.y, yoyo.x, yoyo.y )
line.width = 10
end

end

Runtime:addEventListener(“enterFrame”, DrawLine)

…[/lua] [import]uid: 160496 topic_id: 29838 reply_id: 119710[/import]

Hi. My solution is for your problem :

...  
  
local line  
  
function DrawLine()   
 if line then  
 line:removeSelf()  
 line = nil  
 end  
  
 line = display.newLine(top.x, top.y, yoyo.x, yoyo.y )  
 --line:setColor(math.random(255), math.random(255), math.random(255))  
 line.width = 10   
end  
   
Runtime:addEventListener("enterFrame", DrawLine)  
  
...  

It’s mean Always draw line. Don’t leave blank just after remove the previous line. This is cause your blinking. [import]uid: 171206 topic_id: 29838 reply_id: 119705[/import]

@mike470

I don’t think so. It will work something like that :

  
1st call of DrawLine() :   
line variable not assigned (null), so nothing to delete. And draw the line. Line variable is assigned.  
  
2nd call of DrawLine() :   
line variable assigned (not null), so delete it. And draw the new line. Line variable is assigned.  
  
3rd call of DrawLine() :   
line variable assigned (not null), so delete it. And draw the new line. Line variable is assigned.  
  
...  
  

Any extra line will not draw. At the moment only one line will be.
But your version :
Have you tried it in your simulator. It will not draw any line.

=======================

SORRY mike470!!!

I just missed

local line  

this. But I edited it. Anyway. [import]uid: 171206 topic_id: 29838 reply_id: 119718[/import]

You’re right, I was a bit confused there :slight_smile:

But anyway - it is not a good idea to erase/draw a line *every* frame. Should be doing that only when coordinates need to be changed. [import]uid: 160496 topic_id: 29838 reply_id: 119721[/import]

Thanks for the help guys. using the code that cleankeepersgames suggested, the blinking of the line itself has gone. However as mike470 suggested it isn’t a good idea to draw the line, however how can i implement a method where the coordinates change accordingly with the line? [import]uid: 34863 topic_id: 29838 reply_id: 119739[/import]

ive been having a go on trying to figure this out, so far i believe the only way in which i can do it WITHOUT creating new lines every “enterFrame” is by using the touch event:

[lua]function up:touch(event)
if event.phase == “began” then
motionx = 0
motiony = -speed

myLine = nil

if ( myLine ) then
myLine:removeSelf() – erase previous line, if any
myLine = nil
end

myLine = display.newLine( top.x, top.y, yoyo.x, yoyo.y )
myLine:setColor( 255, 255, 255, 50 )
myLine.width = 16

end
up:addEventListener(“touch”, up)[/lua]

however this will only work when the player moves their finger (whilst its held down) on the up arrow key, i want that the line is connected to the top and the yoyo even when the up arrow is not pressed, and when the arrow is pressed, the yoyo moves and the line (whilst its still connected) moves along with it

any ideas guys?

p.s. the fix that cleankeepergames suggested still blinks on low performance phones, that is not because of the code, but the phones ability to keep creating/disposing lines with a limited CPU power. [import]uid: 34863 topic_id: 29838 reply_id: 119892[/import]

have a couple of variables (local to the module) for the coordinates of the end of the rope. Define, local again, lastRopeX and lastRopeY. In the “enterFrame” function, compare the end of the rope vars with lastRopeX and lastRopeY and, if different, redraw the rope. Then set the lastRopeX and lastRopeY to the end of rope coords. [import]uid: 160496 topic_id: 29838 reply_id: 119909[/import]

do you mean like this:

[lua]local lastRopeX = 150
local lastRopeY = 150

function drawLine()
local myLine
if (yoyo.x ~= lastRopeX or yoyo.y ~= lastRopeY) then
myLine = display.newLine( top.x,top.y, yoyo.x,yoyo.y )
myLine:setColor( 255, 255, 255)
myLine.width = 16

lastRopeX = yoyo.x
lastRopeY = yoyo.y

else
myLine:removeSelf() – erase previous line, if any
myLine = nil
end
end[/lua]

ive set lastRopeX and lastRopeY to 150 as if i didnt assign a value then it would give me a runtime error…however the problem i am getting is another runtime error but due to the removal of myLine set to nil [import]uid: 34863 topic_id: 29838 reply_id: 119946[/import]

[lua]local lastRopeX = math.huge
local lastRopeY = math.huge
local myLine=nil

local function drawLine()
if (yoyo.x ~= lastRopeX or yoyo.y ~= lastRopeY) then
display.remove(myLine); myLine=nil
myLine = display.newLine( top.x,top.y, yoyo.x,yoyo.y )
myLine:setColor( 255)
myLine.width = 16

lastRopeX, lastRopeY = yoyo.x, yoyo.y
end
end[/lua]
– call drawLine from your “enterFrame” listener [import]uid: 160496 topic_id: 29838 reply_id: 119976[/import]