Well, Pico8 is designed to work with a framebuffer, and Löve isn't designed to do that, but there are ways around it.
circfill with a radius of 1 is just 5 points: up, down, left, right and centre. Using that, you can implement a simple purpose-specific circfill that only does that.
Code: Select all
-- Set filter to nearest for all textures by default
love.graphics.setDefaultFilter("nearest", "nearest")
-- Create framebuffer
local fb = love.image.newImageData(128, 128)
-- Fill the framebuffer with white
fb:mapPixel(function (x, y)
return 1, 1, 1, 1
end)
local function circfill(x, y, r, g, b)
fb:setPixel(x, y, r, g, b, 1)
if y > 0 then
fb:setPixel(x, y-1, r, g, b, 1)
end
if x > 0 then
fb:setPixel(x-1, y, r, g, b, 1)
end
if x < 127 then
fb:setPixel(x+1, y, r, g, b, 1)
end
if y < 127 then
fb:setPixel(x, y+1, r, g, b, 1)
end
end
local function rnd(n)
return love.math.random(0, n-1)
end
-- Plant the seeds
for i = 1, 26 do
fb:setPixel(rnd(128), rnd(128), 0, 0, 0, 1)
end
-- Create a GPU-side image from our CPU-side framebuffer
local img = love.graphics.newImage(fb)
local grabbing = 2000
function love.update(dt)
-- Update the framebuffer
for i = 1, grabbing do
local x = rnd(128)
local y = rnd(128)
local c = fb:getPixel(x, y)
if c == 0 then
circfill(x, y, 0, 0, 0)
end
end
end
function love.draw()
-- Send the framebuffer to the GPU
img:replacePixels(fb)
-- Draw the image
local w, h = love.graphics.getDimensions()
local min = math.min(w, h)
love.graphics.draw(img, w/2, h/2, 0, min/128, min/128, 64, 64)
end
Note that this doesn't work at 30 Hz like Pico-8 does, it works at the refresh rate of the monitor (60 Hz in many cases, but it can be different depending on the monitor and graphics mode). It can be refined further with a timer, to make it work at 30 Hz; just replace love.update with this:
Code: Select all
local timer = 0
function love.update(dt)
if timer <= 0 then
-- Update the framebuffer
for i = 1, grabbing do
local x = rnd(128)
local y = rnd(128)
local c = fb:getPixel(x, y)
if c == 0 then
circfill(x, y, 0, 0, 0)
end
end
timer = timer + 1/30
end
timer = timer - dt
end
BrotSagtMist wrote: ↑Sun Dec 05, 2021 11:15 pm
If you do know a better way then please say so, i am currently running this 20 times each frame to get points on my map and i am not happy with it.
If you can't convert it to a framebuffer-based approach like the above, it might be better to convert to ImageData once and then grab the pixels from the ImageData.