How to paint without redraw.

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
duhspbr
Prole
Posts: 5
Joined: Tue Nov 22, 2016 6:11 pm

How to paint without redraw.

Post 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)

Code: Select all

if life.give == 'lemons' then
	life.make('lemonade')
end
User avatar
veethree
Inner party member
Posts: 877
Joined: Sat Dec 10, 2011 7:18 pm

Re: How to paint without redraw.

Post by veethree »

Draw the circle to a canvas, and don't clear it between frames.
User avatar
Sir_Silver
Party member
Posts: 286
Joined: Mon Aug 22, 2016 2:25 pm
Contact:

Re: How to paint without redraw.

Post 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 175 times
User avatar
duhspbr
Prole
Posts: 5
Joined: Tue Nov 22, 2016 6:11 pm

Re: How to paint without redraw.

Post 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!

Code: Select all

if life.give == 'lemons' then
	life.make('lemonade')
end
User avatar
Jack5500
Party member
Posts: 148
Joined: Wed Dec 07, 2011 8:38 pm
Location: Hamburg, Germany

Re: How to paint without redraw.

Post 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.
User avatar
Sir_Silver
Party member
Posts: 286
Joined: Mon Aug 22, 2016 2:25 pm
Contact:

Re: How to paint without redraw.

Post 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 179 times
User avatar
duhspbr
Prole
Posts: 5
Joined: Tue Nov 22, 2016 6:11 pm

Re: How to paint without redraw.

Post 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!

Code: Select all

if life.give == 'lemons' then
	life.make('lemonade')
end
User avatar
Sir_Silver
Party member
Posts: 286
Joined: Mon Aug 22, 2016 2:25 pm
Contact:

Re: How to paint without redraw.

Post by Sir_Silver »

Cheers, :3.
User avatar
Bunnybacon
Prole
Posts: 20
Joined: Fri Mar 25, 2016 8:42 am

Re: How to paint without redraw.

Post 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
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: How to paint without redraw.

Post 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).

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot], Google [Bot] and 6 guests