Struggling to make this better than it is

Hey everyone. It’s a bit rough as its a draft, hence why it still doesn’t work great but it’s a snake enemy with basic movement, just finding it a bit hard to make it faster and smoother. Any help is welcome, take this code for your own use if you wish its all free.


--# Enemy2
Enemy2 = class()
whitecircle = readImage("Documents:Settings")
function Enemy2:init(pos)
    -- you can accept and set parameters here
    self.id = math.random()
    self.typ = 2
    self.enyt = {}
    self.m = mesh()
    self.m.texture = whitecircle
    self.r = {}
    for i=1,5 do
        self.enyt[i] = physics.body(CIRCLE,20)
        self.enyt[i].position = pos+vec2((i-1)*40,0)
        self.enyt[i].friction = 2
        self.enyt[i].categories = {1}
        self.enyt[i].info = "enemy"..tostring(self.id)
        self.r[i] = self.m:addRect(self.enyt[i].x,self.enyt[i].y,40,40)
    end
    self.eny = self.enyt[1]
    self.enyj = {}
    for i=2,5 do
        self.enyj[i] = physics.joint(DISTANCE,self.enyt[i-1],self.enyt[i],self.enyt[i-1].position,self.enyt[i].position)
        self.enyj[i].frequency = 4.5
        self.enyj[i].dampingRatio = 0.5
    end
    
    self.move = false
    self.alive = true
    self.movei = 0 
    self.mti = 0
    self.w,self.h = 40,40
    self.health = 200
    self.dir = -1
    self.changing = false
    self.i = 0
end

function Enemy2:touching()
    
    local rc = physics.raycast(self.eny.position,self.eny.position+vec2(0,-22),0)
    if rc then
        return true
    else
        return false
    end
end

function Enemy2:setID(id)
    self.id = id
    for i=1,5 do
        self.enyt[i].info = "enemy"..tostring(self.id)
    end
end

function Enemy2:doDamage(hp)
    self.health = self.health - hp
    if self.health<#self.enyt*40-40 then
        level.enemies:killEnemy(self.id)
    end 
end

function Enemy2:kill(k)
    self.enyt[k]:destroy()
    table.remove(self.enyt,k)
    self.m:resize(self.m.size-6)
end

function Enemy2:crawl()
    local dir = self.dir
    self.mti = self.mti -dir
    self.i = self.i + 1
    if self.enyt[self.mti] then
        self.enyt[self.mti]:applyForce(vec2(self.dir*(6-self.i)*80,200))
        tween.delay(0.2,function() self:crawl() end)
    else
        self.move = false
        self.movei = 0
        self.mti = 0
        self.i = 0
    end
end

function Enemy2:draw()
    if not self.alive or self.eny.position:dist(ply.pos)>800 then return end
    if self.movei > 130 and not self.move then
        if self:touching() then
            if self.dir == 1 then
                self.mti = #self.enyt+1
            else
                self.mti = 0 
            end
            self:crawl()
            self.move = true
        end
    elseif self:touching() then
        self.movei = self.movei + 4
    end
    local ed = vec2()
    for i=1,#self.enyt do
        local e = self.enyt[i]
        local ep = e.position
        if i>1 then
            local el = self.enyt[i-1]
            local elp = el.position
            e.angularVelocity = -e.angularVelocity/200
        elseif self.enyt[i+1] then
            e.angularVelocity = -e.angularVelocity/200
        end
        self.m:setRect(self.r[i],ep.x,ep.y,40,40,e.angle/mp)
        ed = ed + ep
    end 
    ed = ed / #self.enyt
    if self.dir ~= sign(ply.pos.x-ed.x) then
        self.dir = sign(ply.pos.x-ed.x)
    end
    self.m:draw()
    pushStyle()
    fill((100-self.health)*2.55,self.health*2.55,0,155)
    text("Health: "..self.health,ed.x,ed.y+60)
    popStyle()
end

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

--# Main
-- SnakeEnemy
mp = (180/math.pi)
-- Use this function to perform your initial setup
function setup()
    enemy = Enemy2(vec2(200,100))
    ply = {}
    ply.pos = vec2(600,40)
    floor = physics.body(CHAIN,false,vec2(0,0),vec2(WIDTH,0))
end

function sign(x)
    if x < 0 then x = -1 elseif x > 0 then x = 1 else x = 0 end
    return x
end
-- This function gets called once every frame
function draw()
    -- This sets a dark background color 
    background(40, 40, 50)

    -- This sets the line thickness
    strokeWidth(5)
    sprite("Platformer Art:Battor Flap 1",ply.pos.x,ply.pos.y)
    -- Do your drawing here
    enemy:draw()
end

function touched(td)
    ply.pos = vec2(td.x,td.y)
    
end

Move the player by touching on the screen.