Code Doodles!

General discussion about LÖVE, Lua, game development, puns, and unicorns.
User avatar
rmcode
Party member
Posts: 454
Joined: Tue Jul 15, 2014 12:04 pm
Location: Germany
Contact:

Re: Code Doodles!

Post by rmcode »

Rain drops (Source code):
drops.gif
drops.gif (2.63 MiB) Viewed 21568 times
User avatar
HugoBDesigner
Party member
Posts: 403
Joined: Mon Feb 24, 2014 6:54 pm
Location: Above the Pocket Dimension
Contact:

Re: Code Doodles!

Post by HugoBDesigner »

Long time since I last posted a doodle!

Code: Select all

function love.load()
	windowW, windowH = 800, 600
	graphwidth = windowW-100
	graphheight = windowH-100
	maxval = 512
	font = love.graphics.newFont(12)
	love.graphics.setFont(font)
	love.graphics.setBackgroundColor(205, 205, 205)
	
	points = {}
end

function love.update(dt)
	if #points < maxval then
		local n = #points+1
		table.insert(points, operation(n))
	end
end

function love.draw()
	love.graphics.setColor(255, 255, 255, 255)
	love.graphics.rectangle("fill", windowW/2-graphwidth/2, windowH/2-graphheight/2, graphwidth, graphheight)
	
	love.graphics.setColor(0, 0, 0, 255)
	
	love.graphics.line(windowW/2-graphwidth/2, windowH/2-graphheight/2, windowW/2-graphwidth/2, windowH/2+graphheight/2)
	love.graphics.line(windowW/2-graphwidth/2, windowH/2+graphheight/2, windowW/2+graphwidth/2, windowH/2+graphheight/2)
	local off = 3
	love.graphics.line(windowW/2-graphwidth/2, windowH/2-graphheight/2, windowW/2-graphwidth/2+off, windowH/2-graphheight/2)
	love.graphics.line(windowW/2+graphwidth/2, windowH/2+graphheight/2-off, windowW/2+graphwidth/2, windowH/2+graphheight/2)
	
	local perc = 10
	for y = 0, perc do
		local yy = windowH/2-graphheight/2 + y*(graphheight/perc)
		
		if y < perc then
			love.graphics.setColor(0, 0, 0, 55)
			pointyline(windowW/2-graphwidth/2, yy, windowW/2+graphwidth/2, yy, off)
		end
		
		love.graphics.setColor(0, 0, 0, 255)
		love.graphics.line(windowW/2-graphwidth/2-off, yy, windowW/2-graphwidth/2, yy)
		local s = math.floor((perc-y)/perc*100) .. "%"
		love.graphics.print(s, windowW/2-graphwidth/2-off*2-font:getWidth(s), yy-font:getHeight()/2)
	end
	
	local val = maxval/16
	for x = 0, val do
		local xx = windowW/2-graphwidth/2 + x*(graphwidth/val)
		
		if x > 0 then
			love.graphics.setColor(0, 0, 0, 55)
			pointyline(xx, windowH/2-graphheight/2, xx, windowH/2+graphheight/2, off)
		end
		
		love.graphics.setColor(0, 0, 0, 255)
		love.graphics.line(xx, windowH/2+graphheight/2, xx, windowH/2+graphheight/2+off)
		local s = math.floor(x/val*maxval)
		love.graphics.print(s, xx+font:getHeight()/2, windowH/2+graphheight/2+off*2, math.pi*1/3)
	end
	
	local s = "Sampled " .. #points .. " out of " .. maxval .. " (" .. math.floor(#points/maxval*100) .. "%)"
	love.graphics.print(s, windowW-off-font:getWidth(s), windowH-off-font:getHeight())
	
	love.graphics.setColor(0, 205, 255, 255)
	
	for i, v in ipairs(points) do
		local p1x, p1y = windowW/2-graphwidth/2, windowH/2+graphheight/2
		if i > 1 then
			p1x = windowW/2-graphwidth/2+graphwidth/maxval*(i-1)
			p1y = windowH/2+graphheight/2-graphheight*(points[i-1]/(i-1))
		end
		local p2x = windowW/2-graphwidth/2+graphwidth/maxval*i
		local p2y = windowH/2+graphheight/2-graphheight*(v/i)
		love.graphics.line(p1x, p1y, p2x, p2y)
	end
end

function pointyline(x1, y1, x2, y2, pointyness) --Pointyness should be a word, it sounds so funny :P
	local pointyness = pointyness or 10
	local a = math.atan2(y2-y1, x2-x1)
	
	local size = distance(x1, y1, x2, y2)
	
	for i = 1, math.ceil(size/pointyness) do
		local p1x, p1y = math.cos(a)*(i-1)*pointyness, math.sin(a)*(i-1)*pointyness
		local p2x, p2y = math.cos(a)*i*pointyness, math.sin(a)*i*pointyness
		
		if i == math.ceil(size/pointyness) then
			p2x = x2-x1
			p2y = y2-y1
		end
		
		if math.mod(i, 2) ~= 0 then
			love.graphics.line(p1x+x1, p1y+y1, p2x+x1, p2y+y1)
		end
	end
end

function pointyrectangle(x, y, w, h, pointyness)
	pointyline(x, y, x + w, y, pointyness)
	pointyline(x, y, x, y + h, pointyness)
	pointyline(x + w, y, x + w, y + h, pointyness)
	pointyline(x, y + h, x + w, y + h, pointyness)
end

function distance(x1, y1, x2, y2)
	return math.sqrt((x1-x2)^2 + (y1-y2)^2)
end

function operation(n)
	local divs = 0
	for i = 1, n do
		if math.mod(n, i) == 0 then
			divs = divs+1
		end
	end
	return divs
end
Image

EDIT: Removed a wait variable I set up for recording
@HugoBDesigner - Twitter
HugoBDesigner - Blog
User avatar
TheOddByte
Prole
Posts: 35
Joined: Sun Dec 15, 2013 7:15 pm

Re: Code Doodles!

Post by TheOddByte »

Did this
Image

Controls
G - Toggle gridlines
Left, right - Control wind
+, - - Control size
R - Reset
Attachments
Snowclock.love
(2.51 KiB) Downloaded 525 times
What's the object-oriented way to get wealthy? Inheritance.
User avatar
veethree
Inner party member
Posts: 874
Joined: Sat Dec 10, 2011 7:18 pm

Re: Code Doodles!

Post by veethree »

I got inspired by rmcode's rain thing and made a slightly more elaborate version of it.
rain.gif
rain.gif (7.8 MiB) Viewed 21391 times

Code: Select all

screen = {
	width = love.graphics.getWidth(),
	height = love.graphics.getHeight()
}

function love.load()
	--love setup
	love.graphics.setLineStyle("rough")
	love.filesystem.setIdentity("Rain")

	local _w, _h, _f = love.window.getMode()
	maxIntensity = _f.refreshrate or 0

	--Rain Properties
	rainIntensity = maxIntensity
	rainIntensityMultiplier = 2
	rainDropSize = 16
	rainWindResistance = 0.1
	rippleSpeed = 16
	rippleLife = 0.2
	
	--World Properties
	gravity = 800
	worldDepth = screen.height / 2
	wind = 200

	--Backend Shit
	rain = {}
	rainTick = 0
	canvas = love.graphics.newCanvas(screen.width, screen.height)
	renderFrame = 0
	renderCount = 1
	renderLimit = 1000

	--Background
	sky = verticalGradient(screen.width, screen.height - worldDepth, {129, 178, 214}, {233, 222, 209})
	water = verticalGradient(screen.width, worldDepth, {151, 162, 170}, {0, 33, 60})

	--UI
	controls = [[
		Controls:
		up/down - Change rain intensity
		shift + up/down - Change rain intensity multiplier
		left/right - Change wind strength
		i - toggle info
		r - toggle render
	]]
	showInfo = true
end

function love.update(dt)
	if love.keyboard.isDown("tab") then dt = dt * 0.1 end


	rainTick = rainTick + dt
	if rainTick > (1 / rainIntensity) then
		for i=1, rainIntensityMultiplier do
			spawnDrop()
		end
		rainTick = 0
	end

	--Rain Update
	for i,v in ipairs(rain) do
		if not v.landed then
			--DROP
			v.ox, v.oy = v.x, v.y
			--Gravity
			v.y = v.y + v.speed * dt
			--Wind
			v.x = v.x + (wind * (1 - v.windResistance) ) * dt
			--Angle
			v.angle = angle(v.x, v.y, v.ox, v.oy)
			--Collision
			if v.y > v.landingY then
				v.y = v.landingY
				v.landed = true
			end
		else
			--RIPPLE
			v.radius = v.radius + rippleSpeed * dt
			v.alpha = v.alpha - v.life * dt

			if v.alpha < 0 then
				v.alpha = 0
				table.remove(rain, i)
			end
		end
	end
end

function love.draw()
	love.graphics.setCanvas(canvas)
	love.graphics.setColor(255, 255, 255, 255)
	love.graphics.draw(sky)
	love.graphics.draw(water, 0, screen.height - worldDepth)

	for i,v in ipairs(rain) do
		if not v.landed then
			--DROP
			local x2 = v.x - v.length * math.cos(v.angle)
			local y2 = v.y - v.length * math.sin(v.angle)

			love.graphics.setColor(200, 200, 255, 200)
			love.graphics.line(v.x, v.y, x2, y2)

			--Reflection
			local distance = normal(math.abs(v.landingY - v.y), 0, screen.height - worldDepth )

			local reflectionY = v.landingY - v.y + v.landingY
			local y2 = reflectionY - v.length * math.sin(v.angle)

			love.graphics.setColor(200, 200, 255, 200 * (0.5 - distance))
			love.graphics.line(v.x, y2, x2, reflectionY)

		else
			--RIPPLE
			love.graphics.setColor(200, 200, 255, 255 * v.alpha)
			love.graphics.ellipse("line", v.x, v.y, v.radius * 2, v.radius * 0.5)
		end
	end
	love.graphics.setCanvas()

	love.graphics.setColor(255, 255, 255, 255)
	love.graphics.draw(canvas)

	--UI
	if showInfo then
		love.graphics.setColor(255, 255, 255, 255)
		local s = "Intensity: "..rainIntensity.."x"..rainIntensityMultiplier.."\nWind: "..wind.."\nfps: "..love.timer.getFPS()
		love.graphics.print(s, 12, 12)
	end

	if love.keyboard.isDown("tab") then
		love.graphics.setColor(0, 0, 0, 100)
		love.graphics.rectangle("fill", 0, 0, screen.width, screen.height)
		love.graphics.setColor(255, 255, 255, 255)
		love.graphics.printf(controls, 0, screen.height * 0.2, screen.width, "center")
	end

	--Render
	if render then
		local data = canvas:newImageData()
		data:encode("png", "render_"..renderCount.."/"..renderFrame..".png")
		renderFrame = renderFrame + 1
		if renderFrame > renderLimit then
			render = false
			renderFrame = 0
			renderCount = renderCount + 1
		end
		love.graphics.setColor(255, 0, 0, 255)
		love.graphics.printf("RENDERING (render_"..renderCount.."/"..renderFrame..".png", -12, 12, screen.width, "right")
	end
end

function love.keypressed(key)
	if key == "escape" then love.event.push("quit") end

	if key == "up" then
		if love.keyboard.isDown("lshift") or love.keyboard.isDown("rshift") then
			rainIntensityMultiplier = rainIntensityMultiplier + 1
		else
			rainIntensity = rainIntensity + 10
			if rainIntensity > maxIntensity then
				rainIntensity = maxIntensity
			end
		end
	elseif key == "down" then
		if love.keyboard.isDown("lshift") or love.keyboard.isDown("rshift") then
			rainIntensityMultiplier = rainIntensityMultiplier - 1
			if rainIntensityMultiplier < 1 then
				rainIntensityMultiplier = 1
			end
		else
			rainIntensity = rainIntensity - 10
			if rainIntensity < 0 then
				rainIntensity = 0
			end
		end
	elseif key == "left" then
		wind = wind - 10
	elseif key == "right" then
		wind = wind + 10
	elseif key == "i" then
		showInfo = not showInfo
	elseif key == "r" then
		render = not render
		if not render then
			renderFrame = 0
			renderCount = renderCount + 1
		else
			love.filesystem.createDirectory("render_"..renderCount)
		end
	end
end

function spawnDrop()
	local z = normal(math.random(worldDepth), 0, worldDepth)
	rain[#rain + 1] = {
		x = math.random(-wind, screen.width),
		y = 0,
		z = z,
		angle = 0,
		length = rainDropSize * (1 - z),
		speed = gravity * ((1 - z) + 1),
		windResistance = rainWindResistance * math.random(),
		landingY = screen.height - (worldDepth * z),
		landed = false,
		--RIPPLE
		radius = 0,
		alpha = 1 - (z * 0.2),
		life = (1 - rippleLife) * (z + 1)
	}
end

function verticalGradient(width, height, ...)
	local canvas = love.graphics.newCanvas(width, height)
	local vertices = {}
	for i,v in ipairs({...}) do
		local y = (height  / (#{...} - 1)) * (i - 1)
		vertices[#vertices + 1] = {
			0, y,
			0, 0,
			v[1], v[2], v[3]
			}
		vertices[#vertices + 1] = {
			width, y,
			0, 0,
			v[1], v[2], v[3]
			}
	end
	local mesh = love.graphics.newMesh(vertices, "strip", "dynamic")
	love.graphics.setCanvas(canvas)
	love.graphics.setColor(255, 255, 255, 255)
	love.graphics.draw(mesh, 0, 0)
	love.graphics.setCanvas()
	return canvas
end

function angle(x1, y1, x2, y2)
	return math.atan2(y2-y1, x2-x1) + math.pi
end

function normal(val, min, max)
	return (val - min) / (max - min)
end
Last edited by veethree on Tue Apr 11, 2017 11:46 pm, edited 2 times in total.
User avatar
rmcode
Party member
Posts: 454
Joined: Tue Jul 15, 2014 12:04 pm
Location: Germany
Contact:

Re: Code Doodles!

Post by rmcode »

Nice! <3
PolyDude64
Prole
Posts: 2
Joined: Sun Apr 16, 2017 6:12 am

Re: Code Doodles!

Post by PolyDude64 »

here is mine

Code: Select all

function love.draw()
	love.graphics.setColor(0, 0, 0)
  	local room_width, room_height = love.graphics.getWidth(), love.graphics.getHeight()
  	local medx, medy = room_width/2, room_height/2
  	local time = love.timer.getTime()*2
  	--start scene
  	love.graphics.push()
  	love.graphics.translate(0, room_height/5)
  	--triangle base
  	love.graphics.polygon("fill",medx-50,medy+50,medx+50,medy+50,medx,medy-50)
  	--seesaw
  	love.graphics.setLineWidth(25)
  	local length = 400
  	local saw = math.sin(time)*(math.pi/10)
  	love.graphics.push()
  	love.graphics.translate(medx,medy-50)
  	love.graphics.rotate(saw)
    		love.graphics.line(-length,-10,length,-10)
    		local rad = 50
    		love.graphics.circle("fill", -math.sin(time)*length,-20-(rad),rad)
  	love.graphics.pop()
 	 --end scene
 	 love.graphics.pop()
end
Image
I'd also want you to know that I made a module where you could render your code doodles into image sequences
here
User avatar
steVeRoll
Party member
Posts: 131
Joined: Sun Feb 14, 2016 1:13 pm

Re: Code Doodles!

Post by steVeRoll »

Infinite screen!

Code: Select all

math.randomseed(os.time())

length = 60
time = 0
speed = 1

minDiv = 3
maxDiv = 1.1

div = maxDiv+math.random()*(minDiv-maxDiv)
nextRect = {x=0,y=0,w=0,h=0}

nextRect.w = love.graphics.getWidth()/div
nextRect.h = love.graphics.getHeight()/div
nextRect.x = math.random(0,love.graphics.getWidth()-nextRect.w)
nextRect.y = math.random(0,love.graphics.getHeight()-nextRect.h)

curRect = {x=0,y=0,w=love.graphics.getWidth(),h=love.graphics.getHeight()}

deltaW = love.graphics.getWidth() - nextRect.w
deltaH = love.graphics.getHeight() - nextRect.h

animating = false

screenImg = love.graphics.newImage(love.graphics.newScreenshot(false))

recursions = 0

love.mouse.setVisible(false)

function love.mousepressed()
  if not animating then
    animating = true
    screenImg = love.graphics.newImage(love.graphics.newScreenshot(false))
    love.graphics.setBackgroundColor(math.random(0, 255), math.random(0, 255), math.random(0, 255), 255)
    recursions = recursions + 1
  end
end

function love.keypressed(key)
  if key == "f" then love.window.setFullscreen(not love.window.getFullscreen()) end
end

function love.update()
  if animating then
    time = time + speed
    curRect.x = time/length*nextRect.x
    curRect.y = time/length*nextRect.y
    curRect.w = love.graphics.getWidth()-(time/length*deltaW)
    curRect.h = love.graphics.getHeight()-(time/length*deltaH)
    if time >= length then
      div = maxDiv+math.random()*(minDiv-maxDiv)
      nextRect.w = love.graphics.getWidth()/div
      nextRect.h = love.graphics.getHeight()/div
      nextRect.x = math.random(0,love.graphics.getWidth()-nextRect.w)
      nextRect.y = math.random(0,love.graphics.getHeight()-nextRect.h)
      deltaW = love.graphics.getWidth() - nextRect.w
      deltaH = love.graphics.getHeight() - nextRect.h
      animating = false
      time = 0
    end
  end
end

love.graphics.setNewFont(50)
function love.draw()
  local br,bg,bb = love.graphics.getBackgroundColor()
  love.graphics.setColor(255-br, 255-bg, 255-bb)
  love.graphics.print(recursions)
  love.graphics.setColor(255, 255, 255)
  love.graphics.draw(screenImg, curRect.x, curRect.y, 0, curRect.w/screenImg:getWidth(), curRect.h/screenImg:getHeight())
  if love.window.hasMouseFocus() then love.graphics.circle("fill", love.mouse.getX(), love.mouse.getY(), 5) end
end
infinite_screen.gif
infinite_screen.gif (381.84 KiB) Viewed 21139 times
User avatar
HugoBDesigner
Party member
Posts: 403
Joined: Mon Feb 24, 2014 6:54 pm
Location: Above the Pocket Dimension
Contact:

Re: Code Doodles!

Post by HugoBDesigner »

Just quickly doodled a program that scans through a folder of pictures and selects the one that most closely matches a selected color. It's far from perfect but it works alright!

(Outline is the currently selected color, square at bottom-right is the current picture's average color)
Image
Original size is animated cuz Imgur resizing cancels animation apparently

Code: Select all

function love.load()
	paths = {}
	images = {}
	colors = {}
	local t = love.filesystem.getDirectoryItems("images")
	for i, v in ipairs(t) do
		if string.sub(v, -4, -1) == ".jpg" or string.sub(v, -4, -1) == ".png" then
			table.insert(paths, "images/" .. v)
		end
	end
	
	math.randomseed(os.time())
	tableString = ""
	
	for i, v in ipairs(paths) do
		if i > 1 then tableString = tableString .. "\r\n" end
		tableString = tableString .. v .. " = "
		local img = love.image.newImageData(v)
		local r, g, b, a = getAverage(img)
		images[i] = love.graphics.newImage(v)
		table.insert(colors, {r, g, b, a})
		tableString = tableString .. "[" .. r .. ", " .. g .. ", " .. b .. ", " .. a .. "]"
	end
	
	selections = {}
	selected = false
	selMode = true --true = rgb, false = hsb
	
	love.keypressed("enter", {255, 255, 255})
end

function love.draw()
	if selected then
		love.graphics.setColor(255, 255, 255, 255)
		local off = 10
		local img = images[ selections[selected] ]
		local mw, mh = 800-2*off, 600-2*off
		local sw, sh = mw/img:getWidth(), mh/img:getHeight()
		local scale = math.min(sw, sh)
		
		love.graphics.draw(img, 400-img:getWidth()/2*scale, 300-img:getHeight()/2*scale, 0, scale, scale)
		
		local segs, dist = 16, 2
		love.graphics.setColor(0, 0, 0, 255)
		local px, py
		for i = 1, segs+1 do
			local offx = math.cos(i/segs*math.pi*2)*dist
			local offy = math.sin(i/segs*math.pi*2)*dist
			
			if i == segs+1 then
				love.graphics.setColor(255, 255, 255, 255)
				offx, offy = 0, 0
			end
			
			px = math.floor(400-img:getWidth()/2*scale)
			py = math.floor(300-img:getHeight()/2*scale)
			
			love.graphics.print((#selections > 1 and "[" .. selected .. "/" .. #selections .. "] " or "") .. (selected > 1 and "< " or "") .. paths[ selections[selected] ] .. ((#selections > 1 and selected < #selections) and " >" or ""), px+5+offx, py+5+offy)
			love.graphics.print("Compare mode [TAB]: " .. (selMode and "RGB" or "HSB"), px+5+offx, py+5+20+offy)
			
			px = math.floor(400+img:getWidth()/2*scale)-off-50
			py = math.floor(300+img:getHeight()/2*scale)-off-50
		
			love.graphics.print("Average", px+offx, py-20+offy)
		end
		love.graphics.setColor(0, 0, 0, 255)
		love.graphics.rectangle("fill", px-4, py-4, 58, 58)
		love.graphics.setColor(255, 255, 255, 255)
		love.graphics.rectangle("fill", px-2, py-2, 54, 54)
		love.graphics.setColor(colors[ selections[selected] ])
		love.graphics.rectangle("fill", px, py, 50, 50)
	end
	
	if love.keyboard.isDown("f1") then
		love.graphics.setColor(255, 255, 255, 105)
		love.graphics.rectangle("fill", 0, 0, 800, 600)
		love.graphics.setColor(0, 0, 0, 105)
		love.graphics.rectangle("fill", 0, 0, 800, 600)
		
		local list = {
			"Ctrl + V, space or enter to paste color from clipboard.",
			"Ctrl + R to select a random color.",
			"Tab to switch between RGB comparison and HSB comparison.",
			"Left or right to switch between images when multiple of them match.",
			"Ctrl + C to copy the list of average colors for each image."
		}
		
		local font = love.graphics.getFont()
		local ww = 0
		local hh = 20*#list
		local off = 10
		for i, v in ipairs(list) do
			ww = math.max(font:getWidth(v), ww)
		end
		
		local px, py = math.floor(400-ww/2), math.floor(300-hh/2)
		love.graphics.setColor(0, 0, 0, 255)
		love.graphics.rectangle("fill", px-off-2, py-off-2, ww+off*2+4, hh+off*2+4)
		love.graphics.setColor(155, 155, 155, 255)
		love.graphics.rectangle("fill", px-off, py-off, ww+off*2, hh+off*2)
		
		local segs, dist = 16, 2
		love.graphics.setColor(0, 0, 0, 255)
		for j = 1, segs+1 do
			local offx = math.cos(j/segs*math.pi*2)*dist
			local offy = math.sin(j/segs*math.pi*2)*dist
			
			if j == segs+1 then
				love.graphics.setColor(255, 255, 255, 255)
				offx, offy = 0, 0
			end
			
			for i, v in ipairs(list) do
				local px = math.floor(400-font:getWidth(v)/2)
				local py = math.floor(300-#list*20/2+10-font:getHeight()/2+(i-1)*20)
				
				love.graphics.print(v, px+offx, py+offy)
			end
		end
	end
end

function love.keypressed(key, ctable)
	if key == "tab" and selected then
		selMode = not selMode
		love.keypressed("enter", {love.graphics.getBackgroundColor()})
	elseif key == "c" and (love.keyboard.isDown("lctrl") or love.keyboard.isDown("rctrl")) then
		love.system.setClipboardText(tableString)
	elseif key == "r" and (love.keyboard.isDown("lctrl") or love.keyboard.isDown("rctrl")) then
		love.keypressed("enter", {math.random(256)-1, math.random(256)-1, math.random(256)-1})
	elseif key == "d" or key == "right" then
		if selected then
			selected = selected + 1
			if selected > #selections then
				selected = #selections
			end
		end
	elseif key == "a" or key == "left" then
		if selected then
			selected = selected - 1
			if selected < 1 then
				selected = 1
			end
		end
	elseif key == "enter" or key == "return" or key == "kpenter" or key == "space" or (key == "v" and (love.keyboard.isDown("lctrl") or love.keyboard.isDown("rctrl"))) then
		local c = love.system.getClipboardText()
		if (type(c) == "string" and string.len(c) >= 7) or type(ctable) == "table" then
			local t = string.split(string.gsub(c, " ", ""), ",")
			if type(ctable) == "table" then t = ctable end
			if #t == 4 or #t == 3 then
				local r, g, b, a = false, false, false, false
				if tonumber(t[1]) then
					r = tonumber(t[1])
					if tonumber(t[2]) then
						g = tonumber(t[2])
						if tonumber(t[3]) then
							b = tonumber(t[3])
							if t[4] then
								if tonumber(t[4]) then
									a = tonumber(t[4])
								else
									a = 255
								end
							else
								a = 255
							end
						end
					end
				end
				
				if r then
					if r%1==0 and g%1==0 and b%1==0 and a%1==0 then
						if r >= 0 and r <= 255 and g >= 0 and g <= 255 and b >= 0 and b <= 255 and a >= 0 and a <= 255 then
							print("Current color = [" .. r .. ", " .. g .. ", " .. b .. ", " .. a .. "]")
							local hue, sat, bri = hsb(r, g, b)
							--FINALLY, all checks out
							
							love.graphics.setBackgroundColor(r, g, b)
							
							local max = math.max(r, g, b, a)
							
							local dif = false
							local dif2 = false
							for i, v in ipairs(colors) do
								local cr, cg, cb, ca = unpack(v)
								
								local chue, csat, cbri = hsb(cr, cg, cb)
								
								local d = math.abs(r-cr) + math.abs(g-cg) + math.abs(b-cb) + math.abs(a-ca)
								if not dif then
									dif = {{i}, d}
								elseif d == dif[2] then
									table.insert(dif[1], i)
								elseif d < dif[2] then
									dif = {{i}, d}
								end
								
								
								local d2 = (math.abs(chue-hue))/(math.pi) + math.abs(csat-sat) + math.abs(cbri-bri)
								if not dif2 then
									dif2 = {{i}, d2}
								elseif d2== dif2[2] then
									table.insert(dif2[1], i)
								elseif d2 < dif2[2] then
									dif2 = {{i}, d2}
								end
							end
							
							if selMode then
								selections = dif[1]
							else
								selections = dif2[1]
							end
							selected = 1
						end
					end
				end
			end
		end
	end
end

function hsb(r, g, b) --I STOLED this from Pattern Generator. fite me
	local c = {r, g, b}
	local hue, sat, bri
	
	sat = math.min(unpack(c))/math.max(unpack(c))
	if math.max(unpack(c)) == 0 then
		sat = 0
	end
	bri = 1-math.max(unpack(c))/255
	
	local r, g, b = unpack(c)
	
	r, g, b = r-math.min(r, g, b), g-math.min(r, g, b), b-math.min(r, g, b)
	if math.max(r, g, b) > 0 then
		r, g, b = r/math.max(r, g, b), g/math.max(r, g, b), b/math.max(r, g, b)
	end
	
	if r <= 0 then r = 0 end
	if g <= 0 then g = 0 end
	if b <= 0 then b = 0 end
	
	--=====--
	-- HUE --
	--=====--
	local aa = math.pi/2
	hue = aa
	if r == 1 then
		hue = aa
		if g > 0 then
			hue = hue + g*(aa/3*2)
		else
			hue = hue - b*(aa/3*2)
		end
	elseif g == 1 then
		hue = math.pi+aa/3
		if b > 0 then
			hue = hue + b*(aa/3*2)
		else
			hue = hue - r*(aa/3*2)
		end
	elseif b == 1 then
		hue = math.pi*2-aa/3
		if r > 0 then
			hue = hue + r*(aa/3*2)
		else
			hue = hue - g*(aa/3*2)
		end
	end
	
	if hue < 0 then
		hue = hue + math.pi*2
	elseif hue >= math.pi*2 then
		hue = hue - math.pi*2
	end
	
	sat = 1-sat
	bri = 1-bri
	
	return hue, sat, bri
end

function getAverage(img)
	local rr, rg, rb, ra = 0, 0, 0, 0
	for x = 1, img:getWidth() do
		for y = 1, img:getHeight() do
			local r, g, b, a = img:getPixel(x-1, y-1)
			rr = rr+r; rg = rg+g; rb = rb+b; ra = ra+a
		end
	end
	local i = img:getWidth()*img:getHeight()
	rr = rr/i;rg = rg/i; rb = rb/i; ra = ra/i
	rr = math.floor(rr); rg = math.floor(rg); rb = math.floor(rb); ra = math.floor(ra)
	return math.max(0, math.min(255, rr)), math.max(0, math.min(255, rg)), math.max(0, math.min(255, rb)), math.max(0, math.min(255, ra))
end

function string.split(st, del)
	local del = del or ","
	local ret = {""}
	local wait = 0
	for i = 1, string.len(st) do
		local c = string.sub(st, i, i)
		if wait == 0 then
			if string.sub(st, i, i+string.len(del)-1) == del then
				table.insert(ret, "")
				wait = string.len(del)-1
			else
				ret[#ret] = ret[#ret] .. c
			end
		else
			wait = wait-1
		end
	end
	return ret
end
Attachments
ColorComparator.zip
Executable
(5.19 MiB) Downloaded 504 times
ColorComparator.love
Source
(2.64 MiB) Downloaded 486 times
@HugoBDesigner - Twitter
HugoBDesigner - Blog
User avatar
veethree
Inner party member
Posts: 874
Joined: Sat Dec 10, 2011 7:18 pm

Re: Code Doodles!

Post by veethree »

Made a thing.
1514734036.png
1514734036.png (224.45 KiB) Viewed 19952 times
(it moves)

Code: Select all

screen = {
	width = love.graphics.getWidth(),
	height = love.graphics.getHeight()
}

function love.load()
	t = ""
	love.graphics.setBackgroundColor(10, 10, 30)

	array = {}
	canvas = love.graphics.newCanvas()
	trail = love.graphics.newCanvas()
	time = 0

	--Settings
	count = 64
	gravity = 0.05
	maxDistance = 100
	radius = 4
	toggles = {"point", "line", "cloud", "trail", "info", "controls"}
	render = {
		point = true,
		line = true,
		cloud = true,
		trail = false,
		info = true,
		controls = true
	}

	textColor = {150, 150, 150, 255}
	specialColor = {255, 126, 255, 255}
	headColor = {255, 255, 255, 255}

	reset()
end

function reset()
	array = {}
	time = 0
	local space = 100
	local spec = 5

	for i=1, count do
		local x = (screen.width / 2) + math.sin(i) * 200 + math.random(-space, space)
		local y = (screen.height / 2) + math.cos(i) * 200 + math.random(-space, space)

		local m = -math.random() * 0.5
		local s = true
		spec = spec - 1
		if spec < 0 then
			s = false
		end

		array[i] = {
			x = x,
			y = y,
			lx = x,
			ly = y,
			xVel = 0,
			yVel = 0,
			mass = m,
			radius = radius * m,
			d = 0,
			special = s

		}
	end
	trail = love.graphics.newCanvas()
end


function sprint(n)
	t = t..tostring(n).."\n"
end

function love.update(dt)
	time = time + dt
	for i,v in ipairs(array) do

		v.lx = v.x
		v.ly = v.y

		--GRAVITY
		for o,b in ipairs(array) do
			if o ~= i then
				local d = distance(v.x, v.y, b.x, b.y)
				local a = angle(v.x, v.y, b.x, b.y)
				if d < maxDistance then
					v.xVel = v.xVel + -((v.x - b.x) * ((v.mass * b.mass) * gravity))
					v.yVel = v.yVel + -((v.y - b.y) * ((v.mass * b.mass) * gravity))
				end
			end
		end

		v.x = v.x + v.xVel * dt
		v.y = v.y + v.yVel * dt

		--Screen wrap
		if v.x > screen.width then
			v.x = 0
		elseif v.x < 0 then
			v.x = screen.width
		end

		if v.y > screen.height then
			v.y = 0
		elseif v.y < 0 then
			v.y = screen.height
		end
	end
end

function love.draw()
	love.graphics.setCanvas(canvas)
	love.graphics.clear()
	for i,v in ipairs(array) do
		love.graphics.setColor(255, 255, 255, 255)
		local dist = 0
		local ox = 0
		local oy = 0
		for o,b in ipairs(array) do
			if o ~= i then
				local d = distance(v.x, v.y, b.x, b.y)
				if d < maxDistance then
					dist = normal(d, 0, maxDistance)
					ox = b.x
					oy = b.y
					if render.line then
						love.graphics.setColor(hsl(100 * dist, 255, 126, 150 - (150 * dist)))
						if v.special and b.special then
							love.graphics.setColor(specialColor[1], specialColor[2], specialColor[3], 255 - (255 * dist))
						end
						love.graphics.line(v.x, v.y, ox, oy)
					end
				end
			end
		end

		if render.trail then
			love.graphics.setCanvas(trail)
			love.graphics.setColor(hsl(150 * dist, 255, 126, 30))
			love.graphics.line(v.x, v.y, v.lx, v.ly)
			love.graphics.setCanvas(canvas)
		end

		if render.point then
			love.graphics.setColor(hsl(100 * dist, 255, 126, 255))
			if v.mass > 2 then
				love.graphics.setColor(0, 0, 0, 200)
			end
			if v.special then
				love.graphics.setColor(specialColor)
			end
			love.graphics.circle("fill", v.x, v.y, v.radius)
		end

		if render.cloud then
			love.graphics.setColor(255, 255, 255, 2)
			love.graphics.circle("fill", v.x, v.y, maxDistance)
		end
	end
	love.graphics.setCanvas()

	love.graphics.setColor(255, 255, 255, 255)
	love.graphics.draw(canvas)

	love.graphics.setColor(255, 255, 255, 255)
	love.graphics.draw(trail)

	love.graphics.print(t, 12, 12)
	local ti = math.floor(time) 
	
	if render.info then
		love.graphics.setColor(headColor)
		love.graphics.printf("objects: "..count.."\nfps: "..love.timer.getFPS().."\ntime: "..ti, -24, 24, screen.width, "right")		

		local s = {headColor, "[ RENDER ]\n"}
		for i,v in ipairs(toggles) do
			local color = textColor
			if render[v] then
				color = specialColor
			end
			s[#s + 1] = color
			s[#s + 1] = "[ "..i.." ]".."[ "..v.." ]\n"
		end

		love.graphics.setColor(255, 255, 255, 255)
		love.graphics.print(s, 24, 24)
	end

	if render.controls then
		love.graphics.setColor(headColor)
		local s = "1-6 - Toggle render | space - reset | q - screenshot | escape - close | scroll - Change object count"
		love.graphics.printf(s, 12, screen.height - 24, screen.width, "center")
	end
end

function love.keypressed(key)
	if key == "escape" then love.event.push("quit") end

	if key == "space" then
		reset()
	elseif key == "q" then
		local s = love.graphics.newScreenshot()
		s:encode("png", os.time()..".png")
	elseif key == "1" then
		render.point = not render.point
	elseif key == "2" then
		render.line = not render.line
	elseif key == "3" then
		render.cloud = not render.cloud
	elseif key == "4" then
		render.trail = not render.trail
		if not render.trail then
			trail = love.graphics.newCanvas()
		end
	elseif key == "5" then
		render.info = not render.info
	elseif key == "6" then
		render.controls = not render.controls
	end
end

function love.wheelmoved(x, y)
	if y > 0 then
		count = count + 1
	elseif y < 0 then
		count = count - 1 
	end
end

function normal(val, min, max)
	return (val - min) / (max - min)
end

function hsl(h, s, l, a)
	if s<=0 then return l,l,l,a end
	h, s, l = h/256*6, s/255, l/255
	local c = (1-math.abs(2*l-1))*s
	local x = (1-math.abs(h%2-1))*c
	local m,r,g,b = (l-.5*c), 0,0,0
	if h < 1     then r,g,b = c,x,0
	elseif h < 2 then r,g,b = x,c,0
	elseif h < 3 then r,g,b = 0,c,x
	elseif h < 4 then r,g,b = 0,x,c
	elseif h < 5 then r,g,b = x,0,c
	else              r,g,b = c,0,x
	end return (r+m)*255,(g+m)*255,(b+m)*255,a
end

function distance(x1, y1, x2, y2)
	return math.sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1)))
end

function angle(x1, y1, x2, y2)
	return math.atan2(y2-y1, x2-x1)
end
User avatar
HugoBDesigner
Party member
Posts: 403
Joined: Mon Feb 24, 2014 6:54 pm
Location: Above the Pocket Dimension
Contact:

Re: Code Doodles!

Post by HugoBDesigner »

Hey veethree! I saw your doodle and thought it was pretty cool, so I decided to tweak it, by adding line world wrap and mouse click gravity - hope you don't mind!

Code: Select all

screen = {
	width = love.graphics.getWidth(),
	height = love.graphics.getHeight()
}

function love.load()
	t = ""
	love.graphics.setBackgroundColor(10, 10, 30)

	array = {}
	canvas = love.graphics.newCanvas()
	trail = love.graphics.newCanvas()
	time = 0

	--Settings
	count = 64
	gravity = 0.05
	maxDistance = 100
	radius = 4
	
	--Changed it so that adding toggles is as simple as adding items to this array only
	toggles = {"point", "line", "cloud", "trail", "info", "controls", "linewrap", "mousegravity"}
	render = {}
	for i, v in ipairs(toggles) do
		render[v] = true
	end
	render.trail = false
	
	gradimg = love.image.newImageData(512, 512)
	for x = 1, 512 do
		for y = 1, 512 do
			if distance(x, y, 256, 256) <= 256 then
				local a = math.floor(256-distance(x, y, 256, 256))
				gradimg:setPixel(x-1, y-1, 255, 255, 255, math.max(0, math.min(255, a)))
			end
		end
	end
	gradimg = love.graphics.newImage(gradimg)

	textColor = {150, 150, 150, 255}
	specialColor = {255, 126, 255, 255}
	headColor = {255, 255, 255, 255}

	reset()
end

function reset()
	array = {}
	time = 0
	local space = 100
	local spec = 5

	for i=1, count do
		local x = (screen.width / 2) + math.sin(i) * 200 + math.random(-space, space)
		local y = (screen.height / 2) + math.cos(i) * 200 + math.random(-space, space)

		local m = -math.random() * 0.5
		local s = true
		spec = spec - 1
		if spec < 0 then
			s = false
		end

		array[i] = {
			x = x,
			y = y,
			lx = x,
			ly = y,
			xVel = 0,
			yVel = 0,
			mass = m,
			radius = radius * m,
			d = 0,
			special = s

		}
	end
	trail = love.graphics.newCanvas()
end


function sprint(n)
	t = t..tostring(n).."\n"
end

function love.update(dt)
	time = time + dt
	for i,v in ipairs(array) do

		v.lx = v.x
		v.ly = v.y

		--GRAVITY
		for o,b in ipairs(array) do
			if o ~= i then
				local d = distance(v.x, v.y, b.x, b.y)
				local a = angle(v.x, v.y, b.x, b.y)
				if d < maxDistance then
					v.xVel = v.xVel + -((v.x - b.x) * ((v.mass * b.mass) * gravity))
					v.yVel = v.yVel + -((v.y - b.y) * ((v.mass * b.mass) * gravity))
				elseif toggles.linewrap then
					
				end
			elseif render.mousegravity then
				local MX, MY = love.mouse.getPosition()
				local MM = v.mass * (love.mouse.isDown(1) and 4 or love.mouse.isDown(2) and 16 or 0)
				local d = distance(v.x, v.y, MX, MY)
				local a = angle(v.x, v.y, MX, MY)
				if d < maxDistance then
					v.xVel = v.xVel + -((v.x - MX) * ((v.mass * MM) * gravity))
					v.yVel = v.yVel + -((v.y - MY) * ((v.mass * MM) * gravity))
				end
			end
		end

		v.x = v.x + v.xVel * dt
		v.y = v.y + v.yVel * dt

		--Screen wrap
		if v.x > screen.width then
			v.x = 0
		elseif v.x < 0 then
			v.x = screen.width
		end

		if v.y > screen.height then
			v.y = 0
		elseif v.y < 0 then
			v.y = screen.height
		end
	end
end

function love.draw()
	love.graphics.setCanvas(canvas)
	love.graphics.clear()
	for i,v in ipairs(array) do
		love.graphics.setColor(255, 255, 255, 255)
		local dist = 0
		for o = i, #array do --Saves computing by not drawing lines twice: you had "ab" and "ba" cases
			local b = array[o]
			if o ~= i then
				local d = distance(v.x, v.y, b.x, b.y)
				if d < maxDistance then
					dist = normal(d, 0, maxDistance)
					if render.line then
						love.graphics.setColor(hsl(100 * dist, 255, 126, 150 - (150 * dist)))
						if v.special and b.special then
							love.graphics.setColor(specialColor[1], specialColor[2], specialColor[3], 255 - (255 * dist))
						end
						love.graphics.line(v.x, v.y, b.x, b.y)
					end
				elseif render.linewrap then --Check for screen wrap
					local newbx, newby = b.x, b.y
					local newvx, newvy = v.x, v.y
					if v.x < b.x then
						newbx = b.x - screen.width
						newvx = v.x + screen.width
						if v.x - newbx > b.x - v.x then --Distance was originally shorter than via wrapping
							newbx = b.x
							newvx = v.x
						end
					end
					if v.y < b.y then
						newby = b.y - screen.height
						newvy = b.y + screen.height
						if v.y - newby > b.y - v.y then --Same as above
							newby = b.y
							newvy = v.y
						end
					end
					
					local newd = distance(v.x, v.y, newbx, newby)
					if newd < maxDistance then --Same as before, but around corners
						dist = normal(newd, 0, maxDistance)
						if render.line then
							love.graphics.setColor(hsl(100 * dist, 255, 126, 150 - (150 * dist)))
							if v.special and b.special then
								love.graphics.setColor(specialColor[1], specialColor[2], specialColor[3], 255 - (255 * dist))
							end
							love.graphics.line(newvx, newvy, b.x, b.y)
							love.graphics.line(v.x, v.y, newbx, newby)
						end
					end
				end
			end
		end

		if render.trail then
			love.graphics.setCanvas(trail)
			love.graphics.setColor(hsl(150 * dist, 255, 126, 30))
			love.graphics.line(v.x, v.y, v.lx, v.ly)
			love.graphics.setCanvas(canvas)
		end

		if render.point then
			love.graphics.setColor(hsl(100 * dist, 255, 126, 255))
			if v.mass > 2 then
				love.graphics.setColor(0, 0, 0, 200)
			end
			if v.special then
				love.graphics.setColor(specialColor)
			end
			love.graphics.circle("fill", v.x, v.y, v.radius)
		end

		if render.cloud then
			love.graphics.setColor(255, 255, 255, 2)
			love.graphics.circle("fill", v.x, v.y, maxDistance)
		end
	end
	love.graphics.setCanvas()

	love.graphics.setColor(255, 255, 255, 255)
	love.graphics.draw(canvas)

	love.graphics.setColor(255, 255, 255, 255)
	love.graphics.draw(trail)

	love.graphics.print(t, 12, 12)
	local ti = math.floor(time) 
	
	if render.mousegravity and (love.mouse.isDown(1) or love.mouse.isDown(2)) then
		love.graphics.setColor(205, 155, 55, 55)
		local loop = 1
		if love.mouse.isDown(2) then
			loop = 3
			love.graphics.setColor(255, 55, 0, 55)
		end
		for a = 1, loop do
			love.graphics.draw(gradimg, love.mouse.getX()-maxDistance, love.mouse.getY()-maxDistance, 0,
			maxDistance*2/gradimg:getWidth(), maxDistance*2/gradimg:getHeight())
		end
	end
	
	if render.info then
		love.graphics.setColor(headColor)
		love.graphics.printf("objects: "..count.."\nfps: "..love.timer.getFPS().."\ntime: "..ti, -24, 24, screen.width, "right")		

		local s = {headColor, "[ RENDER ]\n"}
		for i,v in ipairs(toggles) do
			local color = textColor
			if render[v] then
				color = specialColor
			end
			s[#s + 1] = color
			s[#s + 1] = "[ "..i.." ]".."[ "..v.." ]\n"
		end

		love.graphics.setColor(255, 255, 255, 255)
		love.graphics.print(s, 24, 24)
	end

	if render.controls then
		love.graphics.setColor(headColor)
		local s = "1-" .. #toggles .. " - Toggle render | space - reset | q - screenshot | escape - close | scroll - Change object count | hold mouse to activate mouse gravity - right click is stronger"
		love.graphics.printf(s, 0, screen.height - 48, screen.width, "center")
	end
end

function love.keypressed(key)
	if key == "escape" then love.event.push("quit") end

	if key == "space" then
		reset()
	elseif key == "q" then
		local s = love.graphics.newScreenshot()
		s:encode("png", os.time()..".png")
	elseif key == "4" then
		render.trail = not render.trail
		if not render.trail then
			trail = love.graphics.newCanvas()
		end
	elseif tonumber(key) and tonumber(key) <= #toggles then
		render[ toggles[tonumber(key)] ] = not render[ toggles[tonumber(key)] ]
	end
end

function love.wheelmoved(x, y)
	if y > 0 then
		count = count + 1
	elseif y < 0 then
		count = count - 1 
	end
end

function normal(val, min, max)
	return (val - min) / (max - min)
end

function hsl(h, s, l, a)
	if s<=0 then return l,l,l,a end
	h, s, l = h/256*6, s/255, l/255
	local c = (1-math.abs(2*l-1))*s
	local x = (1-math.abs(h%2-1))*c
	local m,r,g,b = (l-.5*c), 0,0,0
	if h < 1     then r,g,b = c,x,0
	elseif h < 2 then r,g,b = x,c,0
	elseif h < 3 then r,g,b = 0,c,x
	elseif h < 4 then r,g,b = 0,x,c
	elseif h < 5 then r,g,b = x,0,c
	else              r,g,b = c,0,x
	end return (r+m)*255,(g+m)*255,(b+m)*255,a
end

function distance(x1, y1, x2, y2)
	return math.sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1)))
end

function angle(x1, y1, x2, y2)
	return math.atan2(y2-y1, x2-x1)
end
@HugoBDesigner - Twitter
HugoBDesigner - Blog
Post Reply

Who is online

Users browsing this forum: No registered users and 52 guests