Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Lightning touch

in Examples Posts: 735

Something I’ve been messing around with. Touch the screen to generate a lightning effect. Satisfies your inner Palpatine!

-- Lightning Touch
displayMode(FULLSCREEN)

function setup()
    target=vec2(WIDTH/2,HEIGHT/2)
    generateArc()
    showLightning=false
end

function draw()
    -- This sets a dark background color
    background(42, 42, 83, 255)
    if showLightning then
    for i,a in pairs(arc) do
        if math.random(5)>1 then
        --do nothing - leave the arc blank    
        else
            local w=math.random(3)
            strokeWidth(w*5)

            stroke(102, 34, 129, 255)
            line(a.s.x,a.s.y,a.a.x,a.a.y)
            line(a.a.x,a.a.y,a.b.x,a.b.y)
            line(a.b.x,a.b.y,target.x,target.y)

            strokeWidth(w*3)

            stroke(182, 0, 255, 255)
            line(a.s.x,a.s.y,a.a.x,a.a.y)
            line(a.a.x,a.a.y,a.b.x,a.b.y)
            line(a.b.x,a.b.y,target.x,target.y)

            strokeWidth(w)
            stroke(255, 255, 255, 255)
            line(a.s.x,a.s.y,a.a.x,a.a.y)
            line(a.a.x,a.a.y,a.b.x,a.b.y)
            line(a.b.x,a.b.y,target.x,target.y)

        end
    end

    peturb()

    stroke(182, 0, 255, 255)
    fill(255)
    ellipse(target.x,target.y,10+math.random(5))
    end
end

function touched(t)
    target.x=t.x
    target.y=t.y
    generateArc()
    for i=1,25 do
        peturb()
    end
    if t.state==BEGAN then
        showLightning=true
    elseif t.state==ENDED or t.state==CANCELLED then
        showLightning=false        
    end
end

function peturb()
    for i,a in pairs(arc) do
        a.a.x=a.a.x+math.random(7)-4
        a.a.y=a.a.y+math.random(7)-4
        a.b.x=a.b.x+math.random(7)-4
        a.b.y=a.b.y+math.random(7)-4
    end
end

function generateArc()
    arc={}
    table.insert(arc,{s=vec2(0,0),a=vec2(target.x/3,target.y/3),b=vec2(2*target.x/3,2*target.y/3)})
    table.insert(arc,{s=vec2(WIDTH,0),a=vec2(WIDTH-(WIDTH-target.x)/3,target.y/3),b=vec2(WIDTH-2*(WIDTH-target.x)/3,2*target.y/3)})
    table.insert(arc,{s=vec2(0,HEIGHT),a=vec2(target.x/3,HEIGHT-(HEIGHT-target.y)/3),b=vec2(2*target.x/3,HEIGHT-2*(HEIGHT-target.y)/3)})
    table.insert(arc,{s=vec2(WIDTH,HEIGHT),a=vec2(WIDTH-(WIDTH-target.x)/3,HEIGHT-(HEIGHT-target.y)/3),b=vec2(WIDTH-2*(WIDTH-target.x)/3,HEIGHT-2*(HEIGHT-target.y)/3)})
    table.insert(arc,{s=vec2(WIDTH/2,0),a=vec2(WIDTH/2-(WIDTH/2-target.x)/3,target.y/3),b=vec2(WIDTH/2-2*((WIDTH/2-target.x)/3),2*target.y/3)})
    table.insert(arc,{s=vec2(WIDTH/2,HEIGHT),a=vec2(WIDTH/2-(WIDTH/2-target.x)/3,HEIGHT-(HEIGHT-target.y)/3),b=vec2(WIDTH/2-2*((WIDTH/2-target.x)/3),HEIGHT-2*(HEIGHT-target.y)/3)})
    table.insert(arc,{s=vec2(0,HEIGHT/2),a=vec2(target.x/3,HEIGHT/2-(HEIGHT/2-target.y)/3),b=vec2(2*target.x/3,HEIGHT/2-2*((HEIGHT/2-target.y)/3))})
    table.insert(arc,{s=vec2(WIDTH,HEIGHT/2),a=vec2(WIDTH-(WIDTH-target.x)/3,HEIGHT/2-(HEIGHT/2-target.y)/3),b=vec2(WIDTH-2*(WIDTH-target.x)/3,HEIGHT/2-2*((HEIGHT/2-target.y)/3))})
end

Comments

  • dave1707dave1707 Mod
    Posts: 7,683

    @West Nice effect. Reminds me of those plasma globes. Need to add more touches to really jazz it up.

  • AnatolyAnatoly Mod
    Posts: 831

    From the code above, here would be a multitouch version:

    -- Lightning Touch
    displayMode(FULLSCREEN)
    
    function setup()
        --target=vec2(WIDTH/2,HEIGHT/2)
        generateArc(vec2(0, 0))
        showLightning=false
        touches = {}
    end
    
    function draw()
        -- This sets a dark background color
        background(42, 42, 83, 255)
        if showLightning then
            for _, b in pairs(touches) do
                for i, a in pairs(b.arc) do
                    if math.random(5)>1 then
                        --do nothing - leave the arc blank    
                    else
                        local w=math.random(3)
                        strokeWidth(w*5)
    
                        stroke(b.col:blend(color(0, 255)))
                        line(a.s.x, a.s.y, a.a.x, a.a.y)
                        line(a.a.x, a.a.y, a.b.x, a.b.y)
                        line(a.b.x, a.b.y, b.t.x, b.t.y)
    
                        strokeWidth(w*3)
    
                        stroke(b.col)
                        line(a.s.x, a.s.y, a.a.x, a.a.y)
                        line(a.a.x, a.a.y, a.b.x, a.b.y)
                        line(a.b.x, a.b.y, b.t.x, b.t.y)
    
                        strokeWidth(w)
                        stroke(255, 255, 255, 255)
                        line(a.s.x, a.s.y, a.a.x, a.a.y)
                        line(a.a.x, a.a.y, a.b.x, a.b.y)
                        line(a.b.x, a.b.y, b.t.x, b.t.y)
    
                    end
                end
    
                --peturb()
    
                stroke(182, 0, 255, 255)
                fill(255)
                ellipse(b.t.x, b.t.y, 10+math.random(5))
            end
        end
    end
    
    function touched(t)
        if t.state==ENDED or t.state==CANCELLED then
            touches[t.id] = nil
            return
        else
            touches[t.id] = {
                t = t,
                arc = generateArc(vec2(t.x, t.y)),
                col = color(math.random(150, 255), math.random(0, 50), math.random(200, 255))
            }
        end
    
        local touchesAmount = 0
        for a, b in pairs(touches) do
            touchesAmount = a
        end
    
        showLightning = true
        if touchesAmount == 0 then
            showLightning = false
            return
        end
    
        --target.x=t.x
        --target.y=t.y
        --generateArc()
        for i=1,25 do
            touches[t.id].arc = peturb(touches[t.id].arc)
        end
    end
    
    function peturb(arc)
        for i,a in pairs(arc) do
            a.a.x=a.a.x+math.random(7)-4
            a.a.y=a.a.y+math.random(7)-4
            a.b.x=a.b.x+math.random(7)-4
            a.b.y=a.b.y+math.random(7)-4
        end
        return arc
    end
    
    function generateArc(target)
        arc={}
        table.insert(arc,{s=vec2(0,0),a=vec2(target.x/3,target.y/3),b=vec2(2*target.x/3,2*target.y/3)})
        table.insert(arc,{s=vec2(WIDTH,0),a=vec2(WIDTH-(WIDTH-target.x)/3,target.y/3),b=vec2(WIDTH-2*(WIDTH-target.x)/3,2*target.y/3)})
        table.insert(arc,{s=vec2(0,HEIGHT),a=vec2(target.x/3,HEIGHT-(HEIGHT-target.y)/3),b=vec2(2*target.x/3,HEIGHT-2*(HEIGHT-target.y)/3)})
        table.insert(arc,{s=vec2(WIDTH,HEIGHT),a=vec2(WIDTH-(WIDTH-target.x)/3,HEIGHT-(HEIGHT-target.y)/3),b=vec2(WIDTH-2*(WIDTH-target.x)/3,HEIGHT-2*(HEIGHT-target.y)/3)})
        table.insert(arc,{s=vec2(WIDTH/2,0),a=vec2(WIDTH/2-(WIDTH/2-target.x)/3,target.y/3),b=vec2(WIDTH/2-2*((WIDTH/2-target.x)/3),2*target.y/3)})
        table.insert(arc,{s=vec2(WIDTH/2,HEIGHT),a=vec2(WIDTH/2-(WIDTH/2-target.x)/3,HEIGHT-(HEIGHT-target.y)/3),b=vec2(WIDTH/2-2*((WIDTH/2-target.x)/3),HEIGHT-2*(HEIGHT-target.y)/3)})
        table.insert(arc,{s=vec2(0,HEIGHT/2),a=vec2(target.x/3,HEIGHT/2-(HEIGHT/2-target.y)/3),b=vec2(2*target.x/3,HEIGHT/2-2*((HEIGHT/2-target.y)/3))})
        table.insert(arc,{s=vec2(WIDTH,HEIGHT/2),a=vec2(WIDTH-(WIDTH-target.x)/3,HEIGHT/2-(HEIGHT/2-target.y)/3),b=vec2(WIDTH-2*(WIDTH-target.x)/3,HEIGHT/2-2*((HEIGHT/2-target.y)/3))})
        return arc
    end
    

    Note: I have only added all needs for multitouch, all your algorithms stayed, and they are great! I look to seeing more from you)

  • Posts: 735

    @dave1707 cheers - yes, though I’ve hard-coded in the location of the source points which makes it pretty inflexible.

    @Anatoly good job on the multi touch

  • Posts: 735

    An updated version with multi touch and arcs on travel from a source point to the nearest touch. Additional demos of touch point to touch point arcs and arcs from initial touch point to current position are also demonstrated.

    -- Lightning Touch
    --displayMode(FULLSCREEN)
    
    function setup()
        target=vec2(WIDTH/2,HEIGHT/2)
        arc={}
        showLightning=true
        touches={}
        tsup={}
        sources={
        {s=vec2(0,0),t=vec2(WIDTH/2,HEIGHT/2)},
        {s=vec2(WIDTH/2,0),t=vec2(WIDTH/2,HEIGHT/2)},
        {s=vec2(WIDTH,0),t=vec2(WIDTH/2,HEIGHT/2)},
        {s=vec2(WIDTH,HEIGHT/2),t=vec2(WIDTH/2,HEIGHT/2)},
        {s=vec2(WIDTH,HEIGHT),t=vec2(WIDTH/2,HEIGHT/2)},
        {s=vec2(WIDTH/2,HEIGHT),t=vec2(WIDTH/2,HEIGHT/2)},
        {s=vec2(0,HEIGHT),t=vec2(WIDTH/2,HEIGHT/2)},
        {s=vec2(0,HEIGHT/2),t=vec2(WIDTH/2,HEIGHT/2)}
        }
        parameter.boolean("sourceTouches",true)
        parameter.boolean("connectTouches")
        parameter.boolean("anchorTouches")
        parameter.boolean("globe",false)
        parameter.color("arcCol",182,0,255)
    end
    
    function draw()
        -- This sets a dark background color
        background(42, 42, 83, 255)
    
        if globe then
            local r=math.min(WIDTH,HEIGHT)/2
            noFill()
            ellipse(WIDTH/2,HEIGHT/2,r*2)
            sources={}
            for i=0,360,5 do
                table.insert(sources,{s=vec2(WIDTH/2+ r*math.cos(math.rad(i)),HEIGHT/2+ r*math.sin(math.rad(i))),t=vec2(WIDTH/2,HEIGHT/2)})
            end
        else
                sources={
        {s=vec2(0,0),t=vec2(WIDTH/2,HEIGHT/2)},
        {s=vec2(WIDTH/2,0),t=vec2(WIDTH/2,HEIGHT/2)},
        {s=vec2(WIDTH,0),t=vec2(WIDTH/2,HEIGHT/2)},
        {s=vec2(WIDTH,HEIGHT/2),t=vec2(WIDTH/2,HEIGHT/2)},
        {s=vec2(WIDTH,HEIGHT),t=vec2(WIDTH/2,HEIGHT/2)},
        {s=vec2(WIDTH/2,HEIGHT),t=vec2(WIDTH/2,HEIGHT/2)},
        {s=vec2(0,HEIGHT),t=vec2(WIDTH/2,HEIGHT/2)},
        {s=vec2(0,HEIGHT/2),t=vec2(WIDTH/2,HEIGHT/2)}
        }
        end
    
        if showLightning then
            arc={}
            --draw arc between each source point and nearest touch
            if sourceTouches then
                for j,s in pairs(sources) do
                    s.t.x=-1
                    s.t.y=-1
                    for i,t in pairs(touches) do
                        if s.t.x==-1 then
                            s.t.x=t.x
                            s.t.y=t.y
                        end
                        if vec2(s.s.x,s.s.y):dist(vec2(t.x,t.y))<vec2(s.s.x,s.s.y):dist(vec2(s.t.x,s.t.y)) then
                            s.t.x=t.x
                            s.t.y=t.y
                        end
                    end
                end
    
                for j,s in pairs(sources) do
                    createArc(s.s.x,s.s.y,s.t.x,s.t.y)
                end
            end
            if anchorTouches then
                for i,t in pairs(touches) do
                    createArc(t.x,t.y,tsup[i].tstartx,tsup[i].tstarty)
                end
            end
    
            --draw an arc between each touch
            if connectTouches then
                for i,t in pairs(touches) do
                    for j,f in pairs(touches) do
                        if j~=f then
                            createArc(t.x,t.y,f.x,f.y)
                            createArc(t.x,t.y,f.x,f.y)
                        end
                    end
                end
            end
    
            for i=1,25 do
                peturb()
            end
    
            for i,a in pairs(arc) do
                if math.random(5)>1 then
                    --do nothing - leave the arc blank to create flicker
                else
                    local w=math.random(3)
                    strokeWidth(w*5)
                    stroke(arcCol.r//3,arcCol.g//3,arcCol.b//3,255)
                    line(a.s.x,a.s.y,a.a.x,a.a.y)
                    line(a.a.x,a.a.y,a.b.x,a.b.y)
                    line(a.b.x,a.b.y,a.t.x,a.t.y)
    
                    strokeWidth(w*3)
                    stroke(arcCol.r,arcCol.g,arcCol.b,255)
                    line(a.s.x,a.s.y,a.a.x,a.a.y)
                    line(a.a.x,a.a.y,a.b.x,a.b.y)
                    line(a.b.x,a.b.y,a.t.x,a.t.y)
    
                    strokeWidth(w)
                    stroke(255, 255, 255, 255)
                    line(a.s.x,a.s.y,a.a.x,a.a.y)
                    line(a.a.x,a.a.y,a.b.x,a.b.y)
                    line(a.b.x,a.b.y,a.t.x,a.t.y)
    
                end
            end
    
            stroke(arcCol.r,arcCol.g,arcCol.b,255)
            fill(255)
    
            local tcount=0
            for i,t in pairs(touches) do
                tcount = tcount + 1
                fill(255)
                ellipse(t.x,t.y,10+math.random(5))
    
            end
            if tcount==0 then showLightning=false end
        end
    end
    
    function touched(t)
    
        if t.state==MOVING then
            --record path
            if tsup[t.id]~=nil then
                table.insert(tsup[t.id].path,{pos=vec2(t.x,t.y),age=ElapsedTime})
            end
        end
        if t.state==ENDED or t.state==CANCELLED then
            touches[t.id] = nil
            tsup[t.id]=nil
        else
            touches[t.id] = t
            showLightning=true
    
            --if there is no supplementary info associated with the current touch then add it
            if tsup[t.id]==nil then
                tsup[t.id]={tstartx=t.x,tstarty=t.y,starttime=ElapsedTime,path={}}
            end
        end
    end
    
    function peturb()
        for i,a in pairs(arc) do
            a.a.x=a.a.x+math.random(7)-4
            a.a.y=a.a.y+math.random(7)-4
            a.b.x=a.b.x+math.random(7)-4
            a.b.y=a.b.y+math.random(7)-4
        end
    end
    
    function createArc(sx,sy,tx,ty)
        --create a line with two bend points between (sx,sy) and (tx,ty)
        local mp1x=(sx-tx)/3
        local mp1y=(sy-ty)/3
        local mp2x=2*(sx-tx)/3
        local mp2y=2*(sy-ty)/3
        table.insert(arc,{s=vec2(sx,sy),a=vec2(sx-mp1x,sy-mp1y),b=vec2(sx-mp2x,sy-mp2y),t=vec2(tx,ty)})
    end
    
    
    
  • dave1707dave1707 Mod
    Posts: 7,683

    @West Nice job. I especially like the globe option with connect touches.

  • Posts: 735

    @dave1707 thanks - was pretty pleased at how it turned out

Sign In or Register to comment.