Manipulating images

I made a simple falling sand game up on CC, this used grid cells in a table. I have revised this to be a bit simpler, more efficient, and more customizable.

Rock
Water
Lava
Steam
Eraser

Will add more for people who enjoy it, you should be able to understand how the update loop works in terms of moving pixels around so feel free to add your own materials!

-- FallingSand

-- Use this function to perform your initial setup
function setup()
    gs = 25
    screen = image(gs,gs)
    noSmooth()
    tool = 1
    n = 0
    nd = 0
    mx,my = WIDTH/gs,HEIGHT/gs
    parameter.integer("gs",2,100,25,function() reset() end)
    parameter.action("Water",function() tool = 1 end)
    parameter.action("Rock",function() tool = 2 end)
    parameter.action("Steam",function() tool = 3 end)
    parameter.action("Lava",function() tool = 4 end)   
        
    parameter.action("eraser",function() tool = 0 end)
end

function reset()
    screen = image(gs,gs)
    mx,my = WIDTH/gs,HEIGHT/gs
end

function clear(x,y)
    screen:set(x,y,0,0,0,0)
end

function set(x,y,col)
    screen:set(x,y,col.r,col.g,col.b,col.a)
end

function update()
    local me,up,down,left,right = color(),color(),color(),color(),color()
    local tz = 0
    for x=1,gs do
        tz = 0
        for y=1,gs do
            n = math.random(0,1)
            nd = math.random(-1,1)
            up.r,up.g,up.b,up.a = screen:get(x,math.min(y+1,gs))
            down.r,down.g,down.b,down.a = screen:get(x,math.max(y-1,1))
            left.r,left.g,left.b,left.a = screen:get(math.min(x+1,gs),y)
            right.r,right.g,right.b,right.a = screen:get(math.max(x-1,1),y)
            me.r,me.g,me.b,me.a = screen:get(x,y)
            if me.b == 255 then
                if down.r == 0 and down.g == 0 and down.b == 0 and down.a == 0 then
                    clear(x,y)   
                    set(x,math.max(y-1,1),color(0,0,255))
                end
                if y-1 == 0 or (down.a ~= 0) then
                    if n == 0 then
                        if left.r == 0 and left.g == 0 and left.b == 0 and left.a == 0 then
                            clear(x,y)   
                            set(math.max(x+1,1),y,color(0,0,255))
                        end
                    elseif n == 1 then
                        if right.r == 0 and right.g == 0 and right.b == 0 and right.a == 0 then
                            clear(x,y)   
                            set(math.min(x-1,gs),y,color(0,0,255))
                        end
                    end
                end
            elseif me.r == 70 then
                if down.r == 0 and down.g == 0 and down.b == 0 and down.a == 0 then
                    clear(x,y)   
                    set(x,math.max(y-1,1),color(70,70,70))
                end
            end
            if me.r == 255 then
                if down.r == 0 and down.g == 0 and down.b == 0 and down.a == 0 then
                    clear(x,y)   
                    set(x,math.max(y-1,1),color(255,50,20))
                end
                if y-1 == 0 or (down.a ~= 0) then
                    if nd == -1 then
                        if left.r == 0 and left.g == 0 and left.b == 0 and left.a == 0 then
                            clear(x,y)   
                            set(math.max(x+1,1),y,color(255,50,20))
                        end
                    elseif n == 1 then
                        if right.r == 0 and right.g == 0 and right.b == 0 and right.a == 0 then
                            clear(x,y)   
                            set(math.min(x-1,gs),y,color(255,50,20))
                        end
                    end
                end
                if left.b == 255 and left.r == 0 then
                    clear(x,y)
                    --set(x,y,color(100,140,140))
                    set(math.max(x-1,1),y,color(100,140,140))
                elseif right.b == 255 and right.r == 0 then
                    clear(x,y)
                    --set(x,y,color(100,140,140))
                    set(math.min(x+1,gs),y,color(100,140,140))
                end
                if down.b == 255 then
                    clear(x,y)
                    --set(x,y,color(100,140,140))
                    set(x,math.max(y-1,1),color(100,140,140))
                end
            end
            if me.r == 100 then
                if y+1 == gs+1 then
                    tween.delay(0.5,function()  
                        set(x,y,color(99,99,255))
                    end)
                    clear(x,y)
                    set(x,y,color(99,99,254))
                end
                if up.r == 0 and up.g == 0 and up.b == 0 and up.a == 0 and tz < 1 then
                    clear(x,y)  
                    set(x,math.min(y+1,gs),color(100,140,140))
                    tz = tz + 1
                elseif up.r == 0 and up.g == 0 and up.b == 255 and up.a ~= 0 then
                    tween.delay(0.3,function()  
                        set(x,math.min(y+1,gs),color(99,99,255))
                    end)
                    clear(x,y)
                    set(x,y,color(0,0,255))
                end
                if y+1 ~= gs+1 and (up.a ~= 0) then
                    if n == 0 then
                        if left.r == 0 and left.g == 0 and left.b == 0 and left.a == 0 then
                            clear(x,y)   
                            set(math.max(x+1,1),y,color(100,140,140))
                        end
                    elseif n == 1 then
                        if right.r == 0 and right.g == 0 and right.b == 0 and right.a == 0 then
                            clear(x,y)   
                            set(math.min(x-1,gs),y,color(100,140,140))
                        end
                    end
                end
            end
        end
    end
end

function touched(t)
    local x,y = math.ceil(t.x/mx),math.ceil(t.y/my)
    if tool == 1 then
        screen:set(x,y,0,0,255,255)
    elseif tool == 2 then
        screen:set(x,y,70,70,70,255)
    elseif tool == 3 then
        screen:set(x,y,100,140,140,255) 
    elseif tool == 4 then
        screen:set(x,y,255,50,20,255)
    end
    if tool == 0 then
        screen:set(x,y,0,0,0,0) 
    end
end
-- This function gets called once every frame
function draw()
    n = n + 1
    -- This sets a dark background color 
    background(40, 40, 50)
    --if (n%3)==0 then
        update()
   -- end
    -- This sets the line thickness
    strokeWidth(5)
    -- Do your drawing here
    sprite(screen,WIDTH/2,HEIGHT/2,WIDTH,HEIGHT)
    pushStyle()
        fill(255,0,0)
        text(1/DeltaTime,100,100)
    popStyle()
    
end

@luatee very cool, thanks. That’s a nice principle for a game.

@Jmv38 it’s very old in concept, have a look at the full game, there’s an even better take on it in java if I can find it.