draw smooth line using a circle following user touch

Hi everybody,

been trying to draw a line following user touch event.

I’m using display a circle in each coordinate passed by event listener. It works, but when you move your touch a bit faster the line get break up. Was my method right by using circle to form a line? Anyway to make the line smooth?

my objective is:
I want to build a connecting dots game. the dot will change color if user connect a line to that dot.

Any help would be much appreciated :slight_smile:

Regards,
Yohan [import]uid: 124207 topic_id: 24764 reply_id: 324764[/import]

I dont know exactly to achieve this, but is it maybe a good idea to give every dot a number. And then make the game track which dots the user touches. And if the user touches the dots in the right order it will connect the dot.

But if you want to make it look more like draw somthing, I dont know how to do that… [import]uid: 118839 topic_id: 24764 reply_id: 101076[/import]

Hi all,

@alexander0: thanks for the respond, yes I think that would be the way to check if all the dots are followed correctly. thanks bro :slight_smile:

I have an update on this. I have put some code for this.
You can draw lines and when the lines touch the dot, it will change into a bigger dot and with a different color.

[lua]local lineTable = {}
local lineWidth = 4

–local lineColor = {R=math.random(0,255), G=math.random(0,255), B=math.random(0,255)}
– These required variables set the R, G, & B color values for your drawn lines. I’ve set it up in this example to pick random values.
local lineColor = {R=255,G=0,B=0}

local grp1 = display.newGroup()

local addListener1, addListener2, addListener3

grpindex = 0

local drawcircle1 = function(x,y)
local _x = x
local _y = y
grpindex = grpindex + 1
local drawc = display.newCircle(_x, _y, 8 )
drawc:setFillColor( 0, 255, 0, 255 )
grp1:insert( grpindex, drawc )
end

circlehit = function(hitnumber)
local hitx = hitnumber

local drawcircle2 = function(x,y)
local _x = x
local _y = y
grpindex = grpindex + 1
local drawc = display.newCircle(_x, _y, 10 )
drawc:setFillColor( 0, 0, 255, 255 )
grp1:insert( grpindex, drawc )
end

if hitx == 1 then
local circle11 = drawcircle2(100,100)
elseif hitx == 2 then
local circle22 = drawcircle2(200,100)
elseif hitx == 3 then
local circle33 = drawcircle2(300,100)
end
end

–draw circle one by one
grpindex = grpindex + 1
circle1 = display.newCircle(100, 100, 8 )
circle1:setFillColor( 0, 255, 0, 255 )
grp1:insert( grpindex, circle1 )

grpindex = grpindex + 1
circle2 = display.newCircle(200, 100, 8 )
circle2:setFillColor( 0, 255, 0, 255 )
grp1:insert( grpindex, circle2 )

grpindex = grpindex + 1
circle3 = display.newCircle(300, 100, 8 )
circle3:setFillColor( 0, 255, 0, 255 )
grp1:insert( grpindex, circle3 )
–finish drawing circle one by one
function state1Cb( event )
print(“state1”)
circle1:removeEventListener( “touch”, state1Cb )
circlehit(1)
timer.performWithDelay( 1, addListener2 ) – ** Do this instead
return true
end

– state2
function state2Cb( event )
print(“state2”)
circle2:removeEventListener( “touch”, state2Cb )
circlehit(2)
timer.performWithDelay( 1, addListener3 )
return true
end

function state3Cb( event )
print(“state3”)
circle1:removeEventListener( “touch”, state3Cb )
circlehit(3)
timer.performWithDelay( 1, addListener1 )
return true
end

function addListener2( )
circle2:addEventListener( “touch”, state2Cb )
end

function addListener1()
circle1:addEventListener( “touch”, state1Cb )
end

function addListener3()
circle3:addEventListener( “touch”, state3Cb )
end

– start
addListener1()
local newLine = function(event)

local function drawLine()
local line = display.newLine(linePoints[#linePoints-1].x,linePoints[#linePoints-1].y,linePoints[#linePoints].x,linePoints[#linePoints].y)
line:setColor(lineColor.R, lineColor.G, lineColor.B);
line.width=lineWidth;
lineTable[i]:insert(line)

local circle = display.newCircle(linePoints[#linePoints].x,linePoints[#linePoints].y,lineWidth/2)
circle:setFillColor(lineColor.R, lineColor.G, lineColor.B)
lineTable[i]:insert(circle)
end

if event.phase==“began” then
i = #lineTable+1
lineTable[i]=display.newGroup()
display.getCurrentStage():setFocus(event.target)

local circle = display.newCircle(event.x,event.y,lineWidth/2)
circle:setFillColor(lineColor.R, lineColor.G, lineColor.B)
lineTable[i]:insert(circle)

linePoints = nil
linePoints = {};

local pt = {}
pt.x = event.x;
pt.y = event.y;
table.insert(linePoints,pt);

elseif event.phase==“moved” then
local pt = {}
pt.x = event.x;
pt.y = event.y;

if not (pt.x==linePoints[#linePoints].x and pt.y==linePoints[#linePoints].y) then
table.insert(linePoints,pt)
drawLine()
end

elseif event.phase==“cancelled” or “ended” then
display.getCurrentStage():setFocus(nil)
i=nil
end

return true
end

Runtime:addEventListener(“touch”, newLine) [/lua]

but next I want to modify this code so that I could draw the first state circle (circle1) using a function. I want to put the coordinate of each sets of dot into array.

so I change this code
[lua]–draw circle one by one
grpindex = grpindex + 1
circle1 = display.newCircle(100, 100, 8 )
circle1:setFillColor( 0, 255, 0, 255 )
grp1:insert( grpindex, circle1 )

grpindex = grpindex + 1
circle2 = display.newCircle(200, 100, 8 )
circle2:setFillColor( 0, 255, 0, 255 )
grp1:insert( grpindex, circle2 )

grpindex = grpindex + 1
circle3 = display.newCircle(300, 100, 8 )
circle3:setFillColor( 0, 255, 0, 255 )
grp1:insert( grpindex, circle3 )
–finish drawing circle one by one[/lua]

to this, using a function
[lua]circle1 = drawcircle1 (100,100)
circle2 = drawcircle1 (200,100)
circle3 = drawcircle1 (300,100)[/lua]

and I get this error
[text]
this is the first line
…s/funedge01/Documents/corona_apps/drawline1/main.lua:129: attempt to index global ‘circle1’ (a nil value)

Copyright © 2009-2012 A n s c a , I n c .
Version: 2.0.0
Build: 2012.777
The file sandbox for this project is located at the following folder:
(/Users/funedge01/Library/Application Support/Corona Simulator/drawline1-8CAC3FAA30ED39EC7E35D03E944C6B26)
Runtime error: …s/funedge01/Documents/corona_apps/drawline1/main.lua:129: attempt to index global ‘circle1’ (a nil value)
stack traceback:
[C]: ?
…s/funedge01/Documents/corona_apps/drawline1/main.lua:129: in function ‘addListener1’
…s/funedge01/Documents/corona_apps/drawline1/main.lua:137: in main chunk

[/text]
below are the full new code so you could reference the error line number

[lua]CiderRunMode = {};CiderRunMode.runmode = true;CiderRunMode.assertImage = true;require “CiderDebugger”;-----------------------------------------------------------------------------------------

– main.lua


–USAGE
–1) Place require(“CiderDebugger”) as the first line in main.lua.
–2) Run the program in the simulator.
–3) Open Cider application.
–4) Open this project in Cider.
–5) Click the debug button.
–6) You will see the program counter stop at the next line.
–7) Begin using the debugger tools.
require(“CiderDebugger”)
print(“this is the first line”)
–Rest of your code

display.setStatusBar( display.HiddenStatusBar )
–local background1 = display.newImageRect( “doting_page_1.png”, display.contentWidth, display.contentHeight)
–background1:setReferencePoint( display.TopLeftReferencePoint )
–background1.x, background1.y = 0,0

– VARIABLES & LINE TABLE (required)

local lineTable = {}
local lineWidth = 4

–local lineColor = {R=math.random(0,255), G=math.random(0,255), B=math.random(0,255)}
– These required variables set the R, G, & B color values for your drawn lines. I’ve set it up in this example to pick random values.
local lineColor = {R=255,G=0,B=0}

local grp1 = display.newGroup()

local addListener1, addListener2, addListener3

grpindex = 0

local drawcircle1 = function(x,y)
local _x = x
local _y = y
grpindex = grpindex + 1
local drawc = display.newCircle(_x, _y, 8 )
drawc:setFillColor( 0, 255, 0, 255 )
grp1:insert( grpindex, drawc )
end

circlehit = function(hitnumber)
local hitx = hitnumber

local drawcircle2 = function(x,y)
local _x = x
local _y = y
grpindex = grpindex + 1
local drawc = display.newCircle(_x, _y, 10 )
drawc:setFillColor( 0, 0, 255, 255 )
grp1:insert( grpindex, drawc )
end

if hitx == 1 then
local circle11 = drawcircle2(100,100)
elseif hitx == 2 then
local circle22 = drawcircle2(200,100)
elseif hitx == 3 then
local circle33 = drawcircle2(300,100)
end
end

–draw circle one by one
–grpindex = grpindex + 1
–circle1 = display.newCircle(100, 100, 8 )
–circle1:setFillColor( 0, 255, 0, 255 )
–grp1:insert( grpindex, circle1 )

–grpindex = grpindex + 1
–circle2 = display.newCircle(200, 100, 8 )
–circle2:setFillColor( 0, 255, 0, 255 )
–grp1:insert( grpindex, circle2 )

–grpindex = grpindex + 1
–circle3 = display.newCircle(300, 100, 8 )
–circle3:setFillColor( 0, 255, 0, 255 )
–grp1:insert( grpindex, circle3 )
–finish drawing circle one by one

circle1 = drawcircle1 (100,100)
circle2 = drawcircle1 (200,100)
circle3 = drawcircle1 (300,100)
function state1Cb( event )
print(“state1”)
circle1:removeEventListener( “touch”, state1Cb )
circlehit(1)
timer.performWithDelay( 1, addListener2 ) – ** Do this instead
return true
end

– state2
function state2Cb( event )
print(“state2”)
circle2:removeEventListener( “touch”, state2Cb )
circlehit(2)
timer.performWithDelay( 1, addListener3 )
return true
end

function state3Cb( event )
print(“state3”)
circle1:removeEventListener( “touch”, state3Cb )
circlehit(3)
timer.performWithDelay( 1, addListener1 )
return true
end

function addListener2( )
circle2:addEventListener( “touch”, state2Cb )
end

function addListener1()
circle1:addEventListener( “touch”, state1Cb )
end

function addListener3()
circle3:addEventListener( “touch”, state3Cb )
end

– start
addListener1()
local newLine = function(event)

local function drawLine()
local line = display.newLine(linePoints[#linePoints-1].x,linePoints[#linePoints-1].y,linePoints[#linePoints].x,linePoints[#linePoints].y)
line:setColor(lineColor.R, lineColor.G, lineColor.B);
line.width=lineWidth;
lineTable[i]:insert(line)

local circle = display.newCircle(linePoints[#linePoints].x,linePoints[#linePoints].y,lineWidth/2)
circle:setFillColor(lineColor.R, lineColor.G, lineColor.B)
lineTable[i]:insert(circle)
end

if event.phase==“began” then
i = #lineTable+1
lineTable[i]=display.newGroup()
display.getCurrentStage():setFocus(event.target)

local circle = display.newCircle(event.x,event.y,lineWidth/2)
circle:setFillColor(lineColor.R, lineColor.G, lineColor.B)
lineTable[i]:insert(circle)

linePoints = nil
linePoints = {};

local pt = {}
pt.x = event.x;
pt.y = event.y;
table.insert(linePoints,pt);

elseif event.phase==“moved” then
local pt = {}
pt.x = event.x;
pt.y = event.y;

if not (pt.x==linePoints[#linePoints].x and pt.y==linePoints[#linePoints].y) then
table.insert(linePoints,pt)
drawLine()
end

elseif event.phase==“cancelled” or “ended” then
display.getCurrentStage():setFocus(nil)
i=nil
end

return true
end

Runtime:addEventListener(“touch”, newLine) [/lua]

the objective is still the same like what I’ve posted in the first post. Maybe the next thing would be to track if the lines not only connected all the dots according to the sequence but also match the pattern line provided.

Guys, I really need a hand…any help would be very very appreciated

Regards,
Yohan [import]uid: 124207 topic_id: 24764 reply_id: 101781[/import]