Kinda like Spawn

Well, this is my first post. I wrote an App similar to Spawn. Here it is:

--# Main
function setup()
    displayMode(FULLSCREEN)
    backingMode(RETAINED)
    spawns={}
    for i=0,100 do
        table.insert(spawns,Spawn(math.random(WIDTH),math.random(HEIGHT)))
    end
    lineCapMode(SQUARE)
    touches={}
    attTimer=math.floor(math.random(400))
    fakeTouch={}
    spawnable=0
end

function touched(touch)
    if touch.state == ENDED then
        touches[touch.id] = nil
    else
        if touch.tapCount==2 then
            for i,obj in ipairs(spawns) do
                obj.x=touch.x
                obj.y=touch.y
                obj.direction=math.random(math.pi*2)
            end
        end
        touches[touch.id] = touch
        if touch.state==BEGAN then
            math.randomseed(touch.id)
            local red=math.random(255)
            local green=math.random(255)
            local blue=math.random(255)
            while red>50 and green>50 and blue>50 do
                red=math.random(255)
                green=math.random(255)
                blue=math.random(255)
            end
            for i,obj in ipairs(spawns) do
                if math.ceil(math.random(2))==1 then
                    obj.id=0
                end
                if obj.id==0 then
                    obj.id=touch.id
                    obj.tored=red+math.random(-20,20)
                    obj.togreen=green+math.random(-20,20)
                    obj.toblue=blue+math.random(-20,20)
                end
            end
        end
    end
end

function draw()
    attTimer = attTimer + 1
    if attTimer==250 or attTimer==400 then
        local touch={}
        touch.x=math.random(WIDTH)
        touch.y=math.random(HEIGHT)
        touch.state=BEGAN
        touch.tapCount=0
        touch.id=math.random(1000,2000)
        touched(touch)
        table.insert(fakeTouch,touch.id)
    elseif (attTimer==50 or attTimer==150) and table.maxn(fakeTouch)>0 then
        local index=table.maxn(fakeTouch)
        index=math.ceil(math.random(index))
        local id=fakeTouch[index]
        local touch={}
        touch.id=id
        touch.state=ENDED
        touch.tapCount=0
        touched(touch)
        table.remove(fakeTouch,index)
    elseif attTimer==450 then
        attTimer=0
    end
    fill(255, 255, 255, 10)
    noStroke()
    rect(0,0,WIDTH,HEIGHT)
    strokeWidth(3)
    stroke(255, 255, 255, 255)
    for i,obj in ipairs(spawns) do
        obj:draw(i)
    end
end

--# Spawn
Spawn = class()

function Spawn:init(x,y)
    self.x = x
    self.y = y
    self.direction=math.random(math.pi*2)
    self.speed=18+math.random(4)
    self.id=0
    self.ax=0
    self.ay=0
    self.red=0
    self.green=0
    self.blue=0
    self.tored=0
    self.togreen=0
    self.toblue=0
    self.turning=math.random(3,10)
end

function Spawn:attract(x,y)
    local dir1=math.atan2(y-self.y,x-self.x)
    local dir2=2*math.pi+dir1
    local dir
    if math.abs(dir1-self.direction)<math.abs(dir2-self.direction) then
        dir=dir1
    else
        dir=dir2
    end
    dir = dir + (math.random(2)-1)*.1
    self.direction = self.direction + (dir-self.direction)/self.turning
end

function Spawn:respond()
    if self.x<0 or self.x>WIDTH then
        self.direction=math.atan2(math.sin(self.direction),-math.cos(self.direction))
        if self.x<0 then
            self.x=0
        else
            self.x=WIDTH
        end
    else
        self.direction=math.atan2(-math.sin(self.direction),math.cos(self.direction))
        if self.y<0 then
            self.y=0
        else
            self.y=HEIGHT
        end
    end
end

function Spawn:draw()
    if self.id>0 then
        if touches[self.id]==nil then
            self.id=0
            self.tored=0
            self.togreen=0
            self.toblue=0
        else
            local touch=touches[self.id]
            self.ax=touch.x
            self.ay=touch.y
            self:attract(touch.x,touch.y)
            self.red = self.red + (self.tored-self.red)/100
            self.green = self.green + (self.togreen-self.green)/100
            self.blue = self.blue + (self.toblue-self.blue)/100
            
        end
    else
        self.direction = self.direction + .01
    end
    if self.x<0 or self.y<0 or self.x>WIDTH or self.y>HEIGHT then
        self:respond(index)
    end
    self.red = self.red + (self.tored-self.red)/30
    self.green = self.green + (self.togreen-self.green)/30
    self.blue = self.blue + (self.toblue-self.blue)/30
    local x=self.x
    local y=self.y
    if self.direction>2*math.pi then
        self.direction = self.direction - 2*math.pi
    elseif self.direction<0 then
        self.direction = self.direction + 2*math.pi
    end 
    self.x = self.x + self.speed *math.cos(self.direction)
    self.y = self.y + self.speed *math.sin(self.direction)
    stroke(0, 0, 0, 255)
    tint(255, 255, 255, 36)
    line(x,y+1,self.x,self.y+1)
    stroke(self.red,self.green,self.blue)
    line(x,y,self.x,self.y)
end

Wow, amazing! I’m a newbie and I can not stop wondering such pieces of work from very talented people, from which I learn a lot. Congratulations =D>