Branchie particles

-- Particles!!!
displayMode(OVERLAY)
function setup()
    points={}
    frame = 0
    rectMode(CENTER)
    backingMode(RETAINED)
    parameter.integer("branching",60,1000,300)
    parameter.number("SizeLossPerFrame",0,1,.01)
    parameter.number("FracSizeAtBranch",.5,1.5,.75)
    parameter.number("MinSize",.25,2,.5)
    parameter.integer("maxpartspeed",60,150,100)
    parameter.integer("minpartspeed",1,60,50)
    parameter.integer("minpartsize",2,20,2)
    parameter.integer("maxpartsize",2,30,12)
    parameter.integer("Burn",1,255,25)
    parameter.integer("numpertouch",1,10,1)
    parameter.action("pointburst",pb)
    parameter.integer("numperburst",10,1000,20)
    parameter.color("bgcol",color(255,255,255))
    parameter.boolean("squares",false)
    parameter.boolean("neg",false)
    parameter.boolean("flashneg",false)
end
function draw()
    frame = frame + 1
    fill(bgcol.r,bgcol.g,bgcol.b,255/Burn)
    rect(WIDTH/2,HEIGHT/2,WIDTH+4,HEIGHT+4)
    fill(255-bgcol.r,255-bgcol.g,255-bgcol.b)
    if squares then
    for i=#points,1,-1 do
        if points[i].x < 0 or points[i].x > WIDTH or points[i].y < 0 or points[i].y > HEIGHT or points[i].size <= MinSize then
            tween.stop(points[i].t1)
            if points[i].t2 then
                tween.stop(points[i].t2)
            end
            table.remove(points,i)
            else
            points[i].size = points[i].size - SizeLossPerFrame
            if math.random(branching) <= 1 then
                split(i)
            end
            if not neg then fill(points[i].r,points[i].g,points[i].b) end
            rect(points[i].x,points[i].y,points[i].size,points[i].size)
        end
    end
    else
        for i=#points,1,-1 do
        if points[i].x < 0 or points[i].x > WIDTH or points[i].y < 0 or points[i].y > HEIGHT or points[i].size <= MinSize then
            tween.stop(points[i].t1)
            if points[i].t2 then
                tween.stop(points[i].t2)
            end
            table.remove(points,i)
            else
            points[i].size = points[i].size - SizeLossPerFrame
            if math.random(branching) <= 1 then
                split(i)
            end
            if not neg then fill(points[i].r,points[i].g,points[i].b) end
            ellipse(points[i].x,points[i].y,points[i].size)
        end
    end
    end
    if flashneg and frame%10 ==0 then
    neg = not neg
    end
end
function touched(t)
    for i=0,numpertouch do
     addpoint(t)
    end
end
function addpoint(p,velx,vely,psize)
    if velx==nil and vely==nil then
        if math.random(4)%2 == 0 then
            velx = 0
            while velx==0 do
                velx = 2-math.random(3)
            end
            vely = 0
            else
            velx = 0
            vely = 0
            while vely ==0 do
                vely = 2-math.random(3)
            end
        end
    end
    table.insert(points,{x=p.x,y=p.y,vx=velx,vy=vely,pps = math.random(minpartspeed,maxpartspeed),r=math.random(255),g=math.random(255),b=math.random(255),size = psize or math.random(math.min(minpartsize,maxpartsize),math.max(minpartsize,maxpartsize))})
    if velx~=0 then
        if velx > 0 then
            points[#points].t1 = tween(math.max((WIDTH-p.x)/points[#points].pps,0),points[#points],{x=WIDTH+1,r=math.random(255),g=math.random(255),b=math.random(255)})
        else
            points[#points].t1 = tween(math.max((p.x)/points[#points].pps,0),points[#points],{x=-1,r=math.random(255),g=math.random(255),b=math.random(255)})
        end
    else
        if vely > 0 then
            points[#points].t1 = tween(math.max((HEIGHT-p.y)/points[#points].pps,0),points[#points],{y=HEIGHT+1,r=math.random(255),g=math.random(255),b=math.random(255)})
        else
            points[#points].t1 = tween(math.max((p.y)/points[#points].pps,0),points[#points],{y=-1,r=math.random(255),g=math.random(255),b=math.random(255)})
        end
    end
end
function split(i)
    addpoint(points[i],points[i].vx,points[i].vy,points[i].size*(FracSizeAtBranch))
    points[i].size = points[i].size*(FracSizeAtBranch)
    if points[i].vx~=0 then
        points[i].t2 = tween(50/points[i].pps,points[i],{y=points[i].y+50},nil,function(i) i.t2 = nil end, points[i])
        points[#points].t2 = tween(50/points[#points].pps,points[#points],{y=points[#points].y-50},nil,function(i) i.t2 = nil end, points[#points])
    else
        points[i].t2 = tween(50/points[i].pps,points[i],{x=points[i].x+50},nil,function(i) i.t2 = nil end, points[i])
        points[#points].t2 = tween(50/points[#points].pps,points[#points],{x=points[#points].x-50},nil,function(i) i.t2 = nil end, points[#points])
    end
end
function pb()
    local xa,ya=math.random(WIDTH),math.random(HEIGHT)
    for i = 0,numperburst do
        addpoint({x=xa,y=ya})
    end
end

Neat! I just added a parameter for background color, I think white looks nice

Nice idea! Added in the original post

This might give you some ideas

http://codea.io/talk/discussion/2973/particular-particles-v2-1-2-randomizer-and-export-of-particle-effects/p1

Looked cool, but my school ipad blocks cc and coolcodea and whatnot

I loved this, very helpful if you’re going to draw london tube :smiley:

Pretty serious code i’d say

I’m very glad you enjoyed it :slight_smile: