Page 1 of 1

How to paint without redraw.

Posted: Tue Nov 22, 2016 7:17 pm
by duhspbr
Hello Guys!

I would like to know how to create a new circle without having to redraw it. For example, it moves to the left using the code I posted below, however I do not want it to redraw with a new coordinate, but rather keep the previous one but generating successively a "trace."

Thank you!

Code: Select all

function love.load()
    y = 0
    x = 0
end
 
function love.update(dt)
    x = x + 0.05
    y = y + 0.05
end

function love.draw( )
    love.graphics.setColor(0, 0, 0)
    love.graphics.circle("line", x, y, 20, 100)

Re: How to paint without redraw.

Posted: Tue Nov 22, 2016 8:45 pm
by veethree
Draw the circle to a canvas, and don't clear it between frames.

Re: How to paint without redraw.

Posted: Wed Nov 23, 2016 6:26 am
by Sir_Silver
Forgive me if I interpreted what you're trying to do here wrong, it helps to be explicit about exactly what you're trying to do.

I wrote something for you that draws circles trailing your cursor's position, hopefully this helps you. I'll share the code and love file too. :emo:

Code: Select all

local mouse_positions = {}
local rand = math.random

function love.load()
	math.randomseed(os.time())
end

function love.draw()
	for i = 1, #mouse_positions do
		local pos = mouse_positions[i]
		local x, y = pos[1], pos[2]
		
		love.graphics.setColor(rand(0, 255), rand(0, 255), rand(0, 255))
		love.graphics.circle("fill", x, y, 10)		
		
		love.graphics.setColor(0, 0, 0)
		love.graphics.circle("line", x, y, 10)		
	end
end

function love.mousemoved(x, y, dx, dy)
	mouse_positions[#mouse_positions + 1] = {x, y}
end
trail.love
(355 Bytes) Downloaded 176 times

Re: How to paint without redraw.

Posted: Thu Nov 24, 2016 11:04 am
by duhspbr
Maybe I was not very clear with the example, I apologize.
Another example to simulate the effect that I mentioned: When we draw in ms paint, we click with the mouse button and drag right? But instead he wanted the square to paint the screen. The problem is that in my example, with each frame the square repaints the screen in a new position instead of having stayed there. Is it better to understand?

Thank you very much!

Re: How to paint without redraw.

Posted: Thu Nov 24, 2016 11:31 am
by Jack5500
What you are describing is the nature of the Löve loops. For the effect you want, you have to either use a canvas like suggested, or store the object from the last frame and redraw it like in Sir_silvers solution.

Re: How to paint without redraw.

Posted: Thu Nov 24, 2016 11:54 am
by Sir_Silver
Based on your analogy to ms paint, I'm guessing your trying to make something similar, but your own, to it. Here's another example that you can play with, which is basically a really basic (and not good) clone of ms paint. As always, code and love file attached.

Code: Select all

local mouse_positions = {}
local size = 10

local color_black = {0, 0, 0}
local color_white = {255, 255, 255}

local down = love.mouse.isDown
local get_mouse_pos = love.mouse.getPosition

function love.load()
	love.graphics.setBackgroundColor(color_white)
end

function love.update(dt)
	local x, y = get_mouse_pos()
	
	if down(1) then
		mouse_positions[#mouse_positions + 1] = {color_black, x, y, size}
	elseif down(2) then
		mouse_positions[#mouse_positions + 1] = {color_white, x, y, size}
	end
end

function love.draw()
	local x, y = get_mouse_pos()
	
	for i = 1, #mouse_positions do
		local obj = mouse_positions[i]
		
		love.graphics.setColor(obj[1])
		love.graphics.circle("fill", obj[2], obj[3], obj[4])
	end
	
	love.graphics.setColor(0, 0, 0)
	love.graphics.circle("line", x, y, size)
end

function love.wheelmoved(x, y)
	if y == 1 then
		size = math.max(1, size - 1)
	elseif y == -1 then
		size = math.min(size + 1, 50)
	end
end

What this code allows you to do is "paint" with a variable sized brushed on the screen using your left/right mouse buttons and scroll wheel. If this is more of what you were trying to go for, I recommend using what I've written more as a stepping stone to understand one way to accomplish what you're trying to do, and not just try to use it outright. The more than you continue to "paint" with this code, as in hold down the left or right mouse button - even if you're painting white - the more tables you're creating that need to be rendered to the screen. I hope I understood what you were trying to say this time lol.
paint.love
simple paint clone
(499 Bytes) Downloaded 180 times

Re: How to paint without redraw.

Posted: Thu Nov 24, 2016 12:31 pm
by duhspbr
What's your problem guys? I've never seen such supportive support! Out of this world!

I got both examples and I solved the problem here!

Thank you all very much! I'm loving the community and language!

Just Love!

Re: How to paint without redraw.

Posted: Thu Nov 24, 2016 10:49 pm
by Sir_Silver
Cheers, :3.

Re: How to paint without redraw.

Posted: Fri Nov 25, 2016 12:38 pm
by Bunnybacon
A funky alternative is to change and replace the love.run function.
The downside if this is that it disables clearing on all graphics, so you can't have elements that don't trail.
Just add this to your main document.

Code: Select all

function love.run()
 
	if love.math then
		love.math.setRandomSeed(os.time())
	end
 
	if love.load then love.load(arg) end
 
	-- We don't want the first frame's dt to include time taken by love.load.
	if love.timer then love.timer.step() end
 
	local dt = 0
 
	-- Main loop time.
	while true do
		-- Process events.
		if love.event then
			love.event.pump()
			for name, a,b,c,d,e,f in love.event.poll() do
				if name == "quit" then
					if not love.quit or not love.quit() then
						return a
					end
				end
				love.handlers[name](a,b,c,d,e,f)
			end
		end
 
		-- Update dt, as we'll be passing it to update
		if love.timer then
			love.timer.step()
			dt = love.timer.getDelta()
		end
 
		-- Call update and draw
		if love.update then love.update(dt) end -- will pass 0 if love.timer is disabled
 
		if love.graphics and love.graphics.isActive() then
			--love.graphics.clear(love.graphics.getBackgroundColor())
			love.graphics.origin()
			if love.draw then love.draw() end
			love.graphics.present()
		end
 
		if love.timer then love.timer.sleep(0.001) end
	end
 
end

Re: How to paint without redraw.

Posted: Fri Nov 25, 2016 1:45 pm
by s-ol
Bunnybacon wrote:A funky alternative is to change and replace the love.run function.
The downside if this is that it disables clearing on all graphics, so you can't have elements that don't trail.
Just add this to your main document.

Code: Select all

function love.run()
 
	if love.math then
		love.math.setRandomSeed(os.time())
	end
 
	if love.load then love.load(arg) end
 
	-- We don't want the first frame's dt to include time taken by love.load.
	if love.timer then love.timer.step() end
 
	local dt = 0
 
	-- Main loop time.
	while true do
		-- Process events.
		if love.event then
			love.event.pump()
			for name, a,b,c,d,e,f in love.event.poll() do
				if name == "quit" then
					if not love.quit or not love.quit() then
						return a
					end
				end
				love.handlers[name](a,b,c,d,e,f)
			end
		end
 
		-- Update dt, as we'll be passing it to update
		if love.timer then
			love.timer.step()
			dt = love.timer.getDelta()
		end
 
		-- Call update and draw
		if love.update then love.update(dt) end -- will pass 0 if love.timer is disabled
 
		if love.graphics and love.graphics.isActive() then
			--love.graphics.clear(love.graphics.getBackgroundColor())
			love.graphics.origin()
			if love.draw then love.draw() end
			love.graphics.present()
		end
 
		if love.timer then love.timer.sleep(0.001) end
	end
 
end
another issue is that the OS might decide to invalidate or destroy (parts of) your main framebuffer (when resizing for example) and you won't be able to recover these. Drawing to a Canvas is failsafe in contrast (and allows to mix per-frame updating graphics parts and 'buffered' ones).