I'm having trouble understanding this

if you move your finger around, eventually the lines will start glitch in and getting bigger/wrong angles.


--# Main
-- Trail

-- Use this function to perform your initial setup
function setup()
    ball = physics.body(POLYGON,vec2(-25,-25),vec2(-25,25),vec2(25,25),vec2(25,-25))
    ball.position = vec2(WIDTH/2,HEIGHT/2)
    flor = physics.body(EDGE,vec2(0,0),vec2(WIDTH,0))
    img = image(100,20)
    setContext(img)
        stroke(255)
        strokeWidth(10)
        line(10,10,90,10)
    setContext()
    trail = Trail(50,1,100,ball,"..")
    bpos = vec2()
    Fps = 0
    speed = 3.5
    time = 0
end

function touched(t)
    bpos = vec2(t.x,t.y)
    speed = t.y/100
    if t.state == ENDED then end
end

-- This function gets called once every frame
function draw()
    -- This sets a dark background color 
    background(40, 40, 50)
    time = time + DeltaTime*speed
    -- This sets the line thickness
    strokeWidth(5)
    fill(205)
    if ball then
        --ball.position = vec2(WIDTH/2,HEIGHT/2)
        rect(ball.x-25,ball.y-25,50,50)
        ball.linearVelocity = (bpos-ball.position)*10 
    end
    -- Do your drawing here
    line(0,0,WIDTH,0)
    --bpos = vec2(WIDTH/2,HEIGHT/2)+vec2(math.sin(time)*200,math.cos(time)*200)
    trail:draw()
    Fps=1/DeltaTime
    text(math.ceil(Fps),150,50)
end


--# Trail
Trail = class()

function Trail:init(startsize,endsize,length,body,tex)
    -- you can accept and set parameters here
    self.body = body
    self.tsegs = {}
    self.count = math.ceil(length/4)
    print(self.count)
    self.m = mesh()
    for i=1,self.count do
       self.tsegs[i] = {}
       self.tsegs[i].r = self.m:addRect(0,0,1,1)
       self.tsegs[i].p = body.position
       self.tsegs[i].a = 0
        self.tsegs[i].c = i
    end
    self.m.texture = img
    self.id = 0
    self.vlen = self.count*32
    self.td = 0
end

function Trail:draw()
    local b = self.body
    self.td = self.td + 1
    
    b.p = b.position
    
    local d = self.tsegs[self.id]
    
    if self.id<self.count then
        self.id = self.id + 1
    else
        self.id = 1
    end
    if self.id>=2 then
         if self.id-2==0 then d = self.tsegs[self.count] else d = self.tsegs[self.id-2] end
    else 
        if self.id == 1 then
            d = self.tsegs[self.count-1] 
        end
        if self.id == 0 then
            d = self.tsegs[self.count-2] 
        end
    end
    local v
    
    v = self.tsegs[self.id]
    v.p = b.position
    self.vlen = 0
    
    local av = (b.p-d.p)
    v.a = math.atan2(av.y,av.x)
    self.m:setRect(v.r,d.p.x-av.x,d.p.y-av.y,av:len(),20,v.a)
    self.m:draw()
end

function Trail:touched(touch)
    -- Codea does not automatically call this method
end

I’ve been trying to debug it in my spare time but it’s just not working, any help is much appreciated.

Not sure what you are trying to achieve but here’s my general touch handler which I’ve set up to show trails. Currently handles multiple touches and there’s a bunch of extra stuff but maybe it will help

-- Touchtracker
-- by West
-- Use this function to perform your initial setup
function setup()
    touches={}
    tsup={} --tsup contains the supplementary info about the start position of the touch
    points={}
    pulse={}
    parameter.boolean("includeTarget",false)
    parameter.boolean("includeTrail",true)
    parameter.boolean("includeStart",false)
    parameter.boolean("includeDuration",false)
    parameter.boolean("includeHistory",false)
    parameter.boolean("joinHistory",false)
    parameter.boolean("includePulse",false)
    parameter.boolean("includeClassification",false)
end

-- This function gets called once every frame
function draw()
    -- This sets a background color 
    background(106, 164, 152, 255)
    noStroke()
    --draw any active touch pulses
    for i,p in pairs(pulse) do
        local pulsesize=500 --the maximum radius of the touch circle pulse
        local fade=100-(p.r/pulsesize)*100 --calculate the
        fill(255,255,255,fade)
        ellipse(p.x,p.y,p.r)
        p.rate = p.rate + 1
        p.r = p.r + p.rate
        if p.r>pulsesize then
            table.remove(pulse,i)
        end
    end
    
    fill(255)
    --draw a circle at each of the touched points
    if includeHistory==true then
        for i,pt in pairs(points) do
            ellipse(pt.x,pt.y,10)
            if joinHistory==true then
                --draw lines between all historic touch points
                strokeWidth(2)
                if i>1 then
                    stroke(255)
                    line(pt.x,pt.y,prevx,prevy)
                end
                prevx=pt.x
                prevy=pt.y
            end
        end
    end
    --draw start and stop circles and connect them with lines for all active touches
    strokeWidth(2)
    for i,t in pairs(touches) do
        fill(255)
        stroke(255)
        if includeStart==true then
            line(tsup[i].tstartx,tsup[i].tstarty,t.x,t.y)
            ellipse(tsup[i].tstartx,tsup[i].tstarty,10)
        end
        fill(255)
        if includeDuration==true then
            local formattime=math.floor(10*(ElapsedTime-tsup[i].starttime))/10
            text(formattime,t.x,t.y+50)
        end
        ellipse(t.x,t.y,10)
        if includeTarget==true then
            local endpt=math.max(1200-800*(ElapsedTime-tsup[i].starttime),50+10*math.sin(5*ElapsedTime))
            local spin=ElapsedTime*40
            pushMatrix()
            translate(t.x,t.y)
            rotate(spin)
            translate(-endpt,0)
            sprite("Cargo Bot:How Arrow",0,0)
            translate(endpt,0)
            rotate(90)
            translate(-endpt,0)
            sprite("Cargo Bot:How Arrow",0,0)
            translate(endpt,0)
            rotate(90)
            translate(-endpt,0)
            sprite("Cargo Bot:How Arrow",0,0)
            translate(endpt,0)
            rotate(90)
            translate(-endpt,0)
            sprite("Cargo Bot:How Arrow",0,0)
            translate(endpt,0)
            popMatrix()
        end
        --draw path of touch
        if includeTrail==true then
            fadespeed=500
            for j,p in pairs(tsup[i].path) do
                trailfade=math.max((p.age-ElapsedTime)*fadespeed,-255)
                stroke(255,255,255,255+trailfade)
                fill(255,255,255,255+trailfade)
                if trailfade>-255 then
                   -- ellipse(p.pos.x,p.pos.y,5)
                    if j>1 then
                        line(prevx,prevy,p.pos.x,p.pos.y)
                    end
                end
                prevx=p.pos.x
                prevy=p.pos.y
            end
        end
    end
end

function touched(touch)
    if touch.state==MOVING then
        --record path
       if tsup[touch.id]~=nil then
           table.insert(tsup[touch.id].path,{pos=vec2(touch.x,touch.y),age=ElapsedTime})
       end
    end
    if touch.state==ENDED or touch.state==CANCELLED then
        processTouch(touch)
        touches[touch.id] = nil
        tsup[touch.id]=nil
    else
        touches[touch.id] = touch
        --if there is no supplementary info associated with the current touch then add it
        if tsup[touch.id]==nil then 
            tsup[touch.id]={tstartx=touch.x,tstarty=touch.y,starttime=ElapsedTime,path={}} 
        end
    end
end

function processTouch(touch)
    if includeHistory==true then
        table.insert(points,vec2(touch.x,touch.y)) --add a point to the points table
    end
    if includePulse==true then
        table.insert(pulse,{x=touch.x,y=touch.y,r=8,rate=1}) --add a new pulse
    end
    if includeClassification==true then
        if ElapsedTime-tsup[touch.id].starttime<0.2 then
            --very short event
            if tsup[touch.id]==nil then
                print("tap")
            elseif vec2(touch.x,touch.y):dist(vec2(tsup[touch.id].tstartx,tsup[touch.id].tstarty))<10 then
                print("tap")
            else
                print("dash")
            end
        elseif ElapsedTime-tsup[touch.id].starttime<1 then  
            --a slightly longer gesture
                if touch.x>tsup[touch.id].tstartx+25 and math.abs(touch.y-tsup[touch.id].tstarty)<50 then
                    print("swipe right")
                elseif touch.x<tsup[touch.id].tstartx-25 and math.abs(touch.y-tsup[touch.id].tstarty)<50 then
                    print("swipe left")
                elseif touch.y>tsup[touch.id].tstarty+25 and math.abs(touch.x-tsup[touch.id].tstartx)<50 then
                    print("swipe up")
                elseif touch.y<tsup[touch.id].tstarty-25 and math.abs(touch.x-tsup[touch.id].tstartx)<50 then
                    print("swipe down")
                end
        end
    end
end

@Luatee Not exactly sure what’s happening in your code, but here’s a version that I had. Maybe later I’ll take your code and see if I can figure out what’s causing the glitches. Just drag your finger around the screen.


displayMode(FULLSCREEN)

function setup()
    tab={}
    x,y=WIDTH/2,HEIGHT/2
    sx,sy=0,0
    length=200
    fill(255,0,0)
end

function draw()
    background(40,40,50)     
    x=x+sx
    y=y+sy
    if #tab<length then
        table.insert(tab,1,vec2(x,y))
    else
        table.insert(tab,1,vec2(x,y))
        table.remove(tab,#tab)
    end
    for a,b in pairs(tab) do
        ellipse(b.x,b.y,10)
    end
    sx=sx*.99
    sy=sy*.99
end

function touched(t)
    if t.state==BEGAN or t.state==MOVING then
        h=vec2(t.x-x,t.y-y):normalize()
        sx=h.x*5
        sy=h.y*5
    end
end

@dave1707 I’m working on implementing trails in to my game and this is what has happened.
You drag the body around and watch the trails, every so often a segment will glitch. It occurs more frequently then stops and the code works again, then it starts glitching. It’s weird, if you play about with it you’ll see.

I’ll take a look at your code @West as its one of the trail designs I’d like to put in.

Try this

-- LuateeTrails

--# Main
-- Trail

-- Use this function to perform your initial setup
function setup()
    ball = physics.body(POLYGON,vec2(-25,-25),vec2(-25,25),vec2(25,25),vec2(25,-25))
    ball.position = vec2(WIDTH/2,HEIGHT/2)
    flor = physics.body(EDGE,vec2(0,0),vec2(WIDTH,0))
    img = image(100,20)
    setContext(img)
        stroke(255)
        strokeWidth(10)
        line(10,10,90,10)
    setContext()
    trail = Trail(50,1,100,ball,"..")
    bpos = vec2()
    Fps = 0
    speed = 3.5
    time = 0
    parameter.watch("dbug")
end

function touched(t)
    bpos = vec2(t.x,t.y)
    speed = t.y/100
    if t.state == ENDED then end
end

-- This function gets called once every frame
function draw()
    -- This sets a dark background color 
    background(40, 40, 50)
    time = time + DeltaTime*speed
    -- This sets the line thickness
    strokeWidth(5)
    fill(205)
    if ball then
        --ball.position = vec2(WIDTH/2,HEIGHT/2)
        rect(ball.x-25,ball.y-25,50,50)
        ball.linearVelocity = (bpos-ball.position)*10 
    end
    -- Do your drawing here
    line(0,0,WIDTH,0)
    --bpos = vec2(WIDTH/2,HEIGHT/2)+vec2(math.sin(time)*200,math.cos(time)*200)
    trail:draw()
    Fps=1/DeltaTime
    text(math.ceil(Fps),150,50)
end


--# Trail
Trail = class()

function Trail:init(startsize,endsize,length,body,tex)
    -- you can accept and set parameters here
    self.body = body
    self.tsegs = {}
    self.count = math.ceil(length/4)
    print(self.count)
    self.m = mesh()
    for i=1,self.count do
       self.tsegs[i] = {}
       self.tsegs[i].r = self.m:addRect(0,0,1,1)
       self.tsegs[i].p = body.position
       self.tsegs[i].a = 0
        self.tsegs[i].c = i
    end
    self.m.texture = img
    self.id = 0
    self.vlen = self.count*32
    self.td = 0
end

function Trail:draw()
    local b = self.body
    self.td = self.td + 1

    --[[
    b.p = b.position

    local d = self.tsegs[self.id]

    if self.id<self.count then
        self.id = self.id + 1
    else
        self.id = 1
    end
    if self.id>=2 then
         if self.id-2==0 then d = self.tsegs[self.count] else d = self.tsegs[self.id-2] end
    else 
        if self.id == 1 then
            d = self.tsegs[self.count-1] 
        end
        if self.id == 0 then
            d = self.tsegs[self.count-2] 
        end
    end
    local v
    --]]
    local v,d
    self.id = self.id%self.count + 1
    d = self.tsegs[(self.id-3)%self.count + 1]
    v = self.tsegs[self.id]
    v.p = b.position
    self.vlen = 0

    local av = (v.p-d.p)
    dbug = av
    v.a = math.atan2(av.y,av.x)
    self.m:setRect(v.r,d.p.x,d.p.y,av:len(),20,v.a)
    self.m:draw()
end

function Trail:touched(touch)
    -- Codea does not automatically call this method
end

I made a couple of insignificant changes to the Trail:draw function to do with selecting the correct segments. The main change was to the setRect call in Trail:draw. The trail segment was positioned so that it ended at the previous (but one) segment’s location pointing towards the current position. This, I think, led to gaps where the positions suddenly changed direction. Now, it is centred at the previous (but one) segment’s location and this smooths over those gaps.