Pixel Renderer

A while back, I made a discussion showing off a proof of concept I had in which anybody could manipulate screen data from code without the use of images (like a C64). Now, I have completed this project. This is in NO WAY the final version I shall be working on. Anyways, without further ado, the code.

--# Main
function setup()
    displayMode(FULLSCREEN)
    supportedOrientations(LANDSCAPE_LEFT)
    rectMode(CORNER)
    FPS=0 --      -\\   Used for
    framcnt=0 --    > Calculating 
    lastscnd=0 -- _/     FPS
    pxSizeW=57 --Width of pixels
    pxSizeH=43--Height of pixels
    s = {
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
    }
    parameter.watch("FPS")
end

function draw()
    noStroke()
    noSmooth() --Smoothing tended to make a stroke-like effect
    code()
    for y=1,16 do
        for x=1,16 do
            fill(s[x][y])
            rect(x*pxSizeW,y*pxSizeH,pxSizeW,pxSizeH)
       end
    end
    
    --Code down here calculates FPS
    framcnt = framcnt + 1
    if (ElapsedTime > lastscnd + 1) then
        lastscnd = lastscnd + 1
        FPS=framcnt
        framcnt = 0
    end
end

function code() --Put your game code here
    d = {
        {255,255,0,0},
        {255,0,255,0},
        {255,0,0,255},
        {255,0,0,255},
        {255,0,255,0},
        {255,255,0,0}
    }
    e = {
        {255,255,255,0},
        {255,0,0,0},
        {255,0,0,0},
        {255,255,0,0},
        {255,0,0,0},
        {255,255,255,0}
    }
    m = {
        {255,255,255,255},
        {255,255,0,255},
        {255,0,0,255},
        {255,0,0,255},
        {255,0,0,255},
        {255,0,0,255}
    }
    o = {
        {255,255,255,255},
        {255,0,0,255},
        {255,0,0,255},
        {255,0,0,255},
        {255,0,0,255},
        {255,255,255,255}
    }
    smile = {
        {0,255,0,255,0},
        {0,0,0,0,0},
        {255,0,0,0,255},
        {0,255,255,255,0}
    }
    Graphics:sFill(120)
    Graphics:sprite(d, vec2(0,0))
    Graphics:sprite(e, vec2(12,0))
    Graphics:sprite(m, vec2(0,10))
    Graphics:sprite(o, vec2(12,10))
    Graphics:sprite(smile, vec2(math.floor(math.sin(ElapsedTime)*6+6),6))
end

--# Graphics
Graphics = class()

function Graphics:sFill(c)
    for y = 1, 16 do
        for x = 1, 16 do
            s[y][x] = c
        end
    end
end

function Graphics:sprite(d,p)
    y=1
    x=1
    for y = 1, #d do
        for x = 1, #d[y] do
            if (y+p.y <= 16 and x+p.x <= 16) then
                s[y+p.y][x+p.x] = d[y][x]
            end
        end
    end
end

function Graphics:hLine(y,l,sx,c)
    for i = sx,sx+l do
        s[y][i] = c
    end
end

function Graphics:vLine(x,l,sy,c)
    for i = sy,sy+l do
        s[i][x] = c
    end
end
--# README
--[[
    To use this "game engine", put your code in 'function code()'
    The engine uses portrait mode.
    The Graphics class has many useful functions:
        sFill- fills the screen
            c: the color to fill the screen with
        
        sprite- generates a sprite
            d: a 2-dimensional array containing the pixel data of the sprite
            p: a vec2 value of where the bottom left hand corner of the sprite will be placed
        
        hLine- displays a horizontal line
            y: the y-coordinate of the line
            l: the length of the line
            sx: the starting x-coordinate of the line (left to right)
            c: the color of the line
        
        vLine- displays a vertical line
            x: the x-coordinate of the line
            l: the length of the line
            sy: the starting y-coordinate of the line (top to bottom)
            c: the color of the line
]]

@niorg2606 Here’s something I had that’s similar to what you’re doing. You’re making letters as 4x6, mine are 5x7.

function setup()
    parameter.integer("size",1,30,5)
    A={ {0,0,1,0,0},{0,1,0,1,0},{1,0,0,0,1},{1,0,0,0,1},{1,1,1,1,1},{1,0,0,0,1},{1,0,0,0,1} }
    B={ {1,1,1,1,0},{1,0,0,0,1},{1,0,0,0,1},{1,1,1,1,0},{1,0,0,0,1},{1,0,0,0,1},{1,1,1,1,0} }
    C={ {0,1,1,1,0},{1,0,0,0,1},{1,0,0,0,0},{1,0,0,0,0},{1,0,0,0,0},{1,0,0,0,1},{0,1,1,1,0} }
    str1={A,B,C,C,B,A}
    str2={C,A,B}
    str3={B}
    x=50
    y=200
    dx=1
    dy=1
end

function draw()
    background(0, 205, 255, 255)
    fill(255)
    show(str1,100,300)
    show(str2,100,100)
    show(str3,x,y)
    x=x+dx
    y=y+dy
    if x>WIDTH or x<0 then
        dx=-dx
    end
    if y>HEIGHT or y<0 then
        dy=-dy
    end
end

function show(s,x,y)
    for z=1,#s do
        for a=1,7 do
            for b=1,5 do
                v=s[z]
                if v[a][b]==1 then
                    fill(255, 45, 0, 255)
                    rect(x+(b-1)*size+(z-1)*6*size,y+(7-a)*size,size,size)    
                end
            end
        end
    end
end

@dave1707 That’s a cool way to render strings. Maybe I should add something like it :wink:
This new version includes circles, color, and a new marble game example.


--# Main
function setup()
    displayMode(FULLSCREEN)
    supportedOrientations(LANDSCAPE_LEFT)
    rectMode(CORNER)
    FPS=0 --      -\\   Used for
    framcnt=0 --    > Calculating 
    lastscnd=0 -- _/     FPS
    pxSizeW=48 --Width of pixels
    pxSizeH=48--Height of pixels
    s = {
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
    }
    parameter.watch("FPS")
    px=1
    py=2
    gameover=false
    win=false
end

function draw()
    noStroke()
    noSmooth() --Smoothing tended to make a stroke-like effect
    code()
    for y=1,16 do
        for x=1,16 do
            fill(s[x][y])
            rect(math.floor(x*pxSizeW)+pxSizeW*1.5,math.floor(y*pxSizeH)-pxSizeH*1,pxSizeW,pxSizeH)
       end
    end
    
    --Code down here calculates FPS
    framcnt = framcnt + 1
    if (ElapsedTime > lastscnd + 1) then
        lastscnd = lastscnd + 1
        FPS=framcnt
        framcnt = 0
    end
end

function code() --Put your game code here
    if (not gameover and not win) then
        Graphics:sFill(100)
        Graphics:sprite({{255}}, vec2(math.floor(px),16-math.floor(py)))
        Graphics:hLine(8,16,0,0)
        Graphics:vLine(4,4,12,0)
        Graphics:vLine(8,4,9,0)
        Graphics:vLine(12,4,12,0)
        Graphics:sprite({{color(0,255,0)}},vec2(14,14))
        Graphics:circle(9,4,math.abs(math.sin(ElapsedTime)*2),255)
        
        px = px + Gravity.y/2
        py = py - Gravity.x/2
        
        if (s[16-math.floor(py)][math.floor(px)] == 0) then
            gameover=true
        elseif (s[16-math.floor(py)][math.floor(px)] ~= 255 and s[16-math.floor(py)][math.floor(px)] ~= nil and s[16-math.floor(py)][math.floor(px)] ~= 100) then
            win=true
        end
    elseif (gameover) then
        Graphics:sFill(color(255,0,0))
    else
        Graphics:sFill(color(0,255,0))
    end
end

--# Graphics
Graphics = class()

function Graphics:sFill(c)
    for y = 1, 16 do
        for x = 1, 16 do
            s[y][x] = c
        end
    end
end

function Graphics:sprite(d,p)
    y=1
    x=1
    for y = 1, #d do
        for x = 1, #d[y] do
            if (y+p.y <= 16 and x+p.x <= 16) then
                s[y+p.y][x+p.x] = d[y][x]
            end
        end
    end
end

function Graphics:hLine(y,l,sx,c)
    for i = sx,sx+l do
        s[y][i] = c
    end
end

function Graphics:vLine(x,l,sy,c)
    for i = sy,sy+l do
        s[i][x] = c
    end
end

function Graphics:circle(x,y,r,c)
    for i=0,360 do
        s[math.floor(math.sin(i)*r)+y][math.floor(math.cos(i)*r)+x] = c
    end
end

--# README
--[[
    To use this "game engine", put your code in 'function code()'
    The engine uses portrait mode.
    The Graphics class has many useful functions:
        sFill- fills the screen
            c: the color to fill the screen with
        
        sprite- generates a sprite
            d: a 2-dimensional array containing the pixel data of the sprite
            p: a vec2 value of where the bottom left hand corner of the sprite will be placed
        
        hLine- displays a horizontal line
            y: the y-coordinate of the line
            l: the length of the line
            sx: the starting x-coordinate of the line (left to right)
            c: the color of the line
        
        vLine- displays a vertical line
            x: the x-coordinate of the line
            l: the length of the line
            sy: the starting y-coordinate of the line (top to bottom)
            c: the color of the line
        circle- Computes and draws a circle
            x: the x-coordinate of the circle
            y: the y-coordinate of the circle
            r: radius of the circle
            c: the color of the circle
]]