9Patch

General discussion about LÖVE, Lua, game development, puns, and unicorns.
User avatar
notcl4y
Citizen
Posts: 85
Joined: Fri Nov 25, 2022 12:23 pm

9Patch

Post by notcl4y »

What 9patch libraries are there? I know there's patchy and slicy (the fixed version of patchy). But they work different. You need to place pixels in the borders of the image.

Are there any other libraries or how to write own with quads?

Code: Select all

loves_lua = "not so",
wants_to = true
User avatar
darkfrei
Party member
Posts: 1181
Joined: Sat Feb 08, 2020 11:09 pm

Re: 9Patch

Post by darkfrei »

notcl4y wrote: Tue Jun 27, 2023 7:13 am What 9patch libraries are there? I know there's patchy and slicy (the fixed version of patchy). But they work different. You need to place pixels in the borders of the image.

Are there any other libraries or how to write own with quads?

Code: Select all

local function newQuadPatch (image, edgeW, edgeH, x, y)
	local imageW, imageH = image:getDimensions ()
	local middleW, middleH = imageW - 2*edgeW, imageH - 2*edgeH
	
	-- quads:
	-- 1 2 3
	-- 4 5 6
	-- 7 8 9
	
	local quad1 = love.graphics.newQuad(0,0, edgeW, edgeH, image)
	local quad2 = love.graphics.newQuad(edgeW, 0, middleW, edgeH, image)
	local quad3 = love.graphics.newQuad(edgeW+middleW,0, edgeW, edgeH, image)
	
	local quad4 = love.graphics.newQuad(0,edgeH, edgeW, middleH, image)
	local quad5 = love.graphics.newQuad(edgeW,edgeH, middleW, middleH, image)
	local quad6 = love.graphics.newQuad(edgeW+middleW,edgeH, edgeW, middleH, image)
	
	local quad7 = love.graphics.newQuad(0,edgeH+middleH, edgeW, edgeH, image)
	local quad8 = love.graphics.newQuad(edgeW,edgeH+middleH, middleW, edgeH, image)
	local quad9 = love.graphics.newQuad(edgeW+middleW,edgeH+middleH, edgeW, edgeH, image)
	
	local quadPatch = {
		x = x or 0,
		y = y or 0,
		w = imageW,
		h = imageH,
		edgeW = edgeW,
		edgeH = edgeH,
		scaleW = 1,
		scaleH = 1,
		quads = {quad1, quad2, quad3, quad4, quad5, quad6, quad7, quad8, quad9},
		image = image,
	}
	return quadPatch
end

Code: Select all

local function updateQuadPatch (quadPatch, w, h) -- new w and h
	if not (w == quadPatch.w) or not (h == quadPatch.h) then
		local qp = quadPatch
		local imageW, imageH = qp.image:getDimensions ()
		local scaleW = (w-2*qp.edgeW)/(imageW-2*qp.edgeW)
		local scaleH = (h-2*qp.edgeH)/(imageH-2*qp.edgeH)
		quadPatch.w = w
		quadPatch.h = h
		quadPatch.scaleW = scaleW
		quadPatch.scaleH = scaleH
	end
end

Code: Select all

local function drawQuadPatch (qp)
	local x1, x2, x3 = qp.x, qp.x+qp.edgeW, qp.x+qp.w-qp.edgeW
	local y1, y2, y3 = qp.y, qp.y+qp.edgeH, qp.y+qp.h-qp.edgeH
	love.graphics.draw(qp.image, qp.quads[1], x1, y1)
	love.graphics.draw(qp.image, qp.quads[2], x2, y1, 0, qp.scaleW, 1)
	love.graphics.draw(qp.image, qp.quads[3], x3, y1)
	
	love.graphics.draw(qp.image, qp.quads[4], x1, y2, 0, 1, qp.scaleH)
	love.graphics.draw(qp.image, qp.quads[5], x2, y2, 0, qp.scaleW, qp.scaleH)
	love.graphics.draw(qp.image, qp.quads[6], x3, y2, 0, 1, qp.scaleH)
	
	love.graphics.draw(qp.image, qp.quads[7], x1, y3)
	love.graphics.draw(qp.image, qp.quads[8], x2, y3, 0, qp.scaleW, 1)
	love.graphics.draw(qp.image, qp.quads[9], x3, y3)
end
(not tested)
Last edited by darkfrei on Wed Jun 28, 2023 8:24 am, edited 1 time in total.
:awesome: in Lua we Löve
:awesome: Platformer Guide
:awesome: freebies
User avatar
notcl4y
Citizen
Posts: 85
Joined: Fri Nov 25, 2022 12:23 pm

Re: 9Patch

Post by notcl4y »

darkfrei wrote: Tue Jun 27, 2023 8:47 pm
notcl4y wrote: Tue Jun 27, 2023 7:13 am What 9patch libraries are there? I know there's patchy and slicy (the fixed version of patchy). But they work different. You need to place pixels in the borders of the image.

Are there any other libraries or how to write own with quads?

Code: Select all

local function newQuadPatch (image, edgeW, edgeH, x, y)
	local imageW, imageH = image:getDimensions ()
	local middleW, middleH = imageW - 2*edgeW, imageH - 2*edgeH
	
	-- quads:
	-- 1 2 3
	-- 4 5 6
	-- 7 8 9
	
	local quad1 = love.graphics.newQuad(0,0, edgeW, edgeH, image)
	local quad2 = love.graphics.newQuad(edgeW, 0, middleW, edgeH, image)
	local quad3 = love.graphics.newQuad(edgeW+middleW,0, edgeW, edgeH, image)
	
	local quad4 = love.graphics.newQuad(0,edgeH, edgeW, middleH, image)
	local quad5 = love.graphics.newQuad(edgeW,edgeH, middleW, middleH, image)
	local quad6 = love.graphics.newQuad(edgeW+middleW,edgeH, edgeW, middleH, image)
	
	local quad7 = love.graphics.newQuad(0,edgeH+middleH, edgeW, edgeH, image)
	local quad8 = love.graphics.newQuad(edgeW,edgeH+middleH, middleW, edgeH, image)
	local quad9 = love.graphics.newQuad(edgeW+middleW,edgeH+middleH, edgeW, edgeH, image)
	
	local quadPatch = {
		x = x or 0,
		y = y or 0,
		w = imageW,
		h = imageH,
		edgeW = edgeW,
		edgeH = edgeH,
		scaleW = 1,
		scaleH = 1,
		quads = {quad1, quad2, quad3, quad4, quad5, quad6, quad7, quad8, quad9},
		image = image,
	}
	return quadPatch
end

Code: Select all

local function updateQuadPatch (quadPatch, w, h) -- new w and h
	if not (w == quadPatch.w) or not (h == quadPatch.h) then
		local qp = quadPatch
		local imageW, imageH = qp.image:getDimensions ()
		local scaleW = (w-2*qp.edgeW)/(imageW-2*qp.edgeW)
		local scaleH = (h-2*qp.edgeH)/(imageH-2*qp.edgeH)
		quadPatch.w = w
		quadPatch.h = h
		quadPatch.scaleW = scaleW
		quadPatch.scaleH = scaleH
	end
end

Code: Select all

local function drawQuadPatch (qp)
	local x1, x2, x3 = qp.x, qp.x+qp.edgeW, qp.x+qp.w-qp.edgeW
	local y1, y2, y3 = qp.y, qp.y+qp.edgeH, qp.y+qp.h-qp.edgeH
	love.graphics.draw(qp.image, qp.quads[1], x1, y1)
	love.graphics.draw(qp.image, qp.quads[2], x2, y1, 0, qp.scaleW, 1)
	love.graphics.draw(qp.image, qp.quads[3], x3, y1)
	
	love.graphics.draw(qp.image, qp.quads[4], x1, y2, 0, 1, qp.scaleH)
	love.graphics.draw(qp.image, qp.quads[5], x2, y2, 0, qp.scaleW, qp.scaleH)
	love.graphics.draw(qp.image, qp.quads[6], x3, y2, 0, 1, qp.scaleH)
	
	love.graphics.draw(qp.image, qp.quads[7], x1, y3)
	love.graphics.draw(qp.image, qp.quads[8], x2, y3, 0, qp.scaleW, q)
	love.graphics.draw(qp.image, qp.quads[9], x3, y3)
end
(not tested)
Ok, thanks

Code: Select all

loves_lua = "not so",
wants_to = true
User avatar
notcl4y
Citizen
Posts: 85
Joined: Fri Nov 25, 2022 12:23 pm

Re: 9Patch

Post by notcl4y »

darkfrei wrote: Tue Jun 27, 2023 8:47 pm (not tested)
Just tested it, it works the same as the way I tried to write. Of course I've changed something in your code to fit with mine. But still either the quads are broken, they work the different way or we wrote it the wrong way.
Screenshot_2.png
Screenshot_2.png (6.65 KiB) Viewed 1469 times

Code: Select all

loves_lua = "not so",
wants_to = true
User avatar
darkfrei
Party member
Posts: 1181
Joined: Sat Feb 08, 2020 11:09 pm

Re: 9Patch

Post by darkfrei »

notcl4y wrote: Thu Jun 29, 2023 3:04 pm
darkfrei wrote: Tue Jun 27, 2023 8:47 pm (not tested)
Just tested it, it works the same as the way I tried to write. Of course I've changed something in your code to fit with mine. But still either the quads are broken, they work the different way or we wrote it the wrong way.

Screenshot_2.png

Code: Select all

local function newQuadPatch (image, edgeW, edgeH, x, y)
	local imageW, imageH = image:getDimensions ()
	local middleW, middleH = imageW - 2*edgeW, imageH - 2*edgeH
	
	-- quads:
	-- 1 2 3
	-- 4 5 6
	-- 7 8 9
	
	local quad1 = love.graphics.newQuad(0,0, edgeW, edgeH, image)
	local quad2 = love.graphics.newQuad(edgeW, 0, middleW, edgeH, image)
	local quad3 = love.graphics.newQuad(edgeW+middleW,0, edgeW, edgeH, image)
	
	local quad4 = love.graphics.newQuad(0,edgeH, edgeW, middleH, image)
	local quad5 = love.graphics.newQuad(edgeW,edgeH, middleW, middleH, image)
	local quad6 = love.graphics.newQuad(edgeW+middleW,edgeH, edgeW, middleH, image)
	
	local quad7 = love.graphics.newQuad(0,edgeH+middleH, edgeW, edgeH, image)
	local quad8 = love.graphics.newQuad(edgeW,edgeH+middleH, middleW, edgeH, image)
	local quad9 = love.graphics.newQuad(edgeW+middleW,edgeH+middleH, edgeW, edgeH, image)
	
	local quadPatch = {
		x = x or 0,
		y = y or 0,
		w = imageW,
		h = imageH,
		edgeW = edgeW,
		edgeH = edgeH,
		scaleW = 1,
		scaleH = 1,
		quads = {quad1, quad2, quad3, quad4, quad5, quad6, quad7, quad8, quad9},
		image = image,
	}
	return quadPatch
end

local function updateQuadPatch (quadPatch, w, h) -- new w and h
	if not (w == quadPatch.w) or not (h == quadPatch.h) then
		local qp = quadPatch
		local imageW, imageH = qp.image:getDimensions ()
		local scaleW = (w-2*qp.edgeW)/(imageW-2*qp.edgeW)
		local scaleH = (h-2*qp.edgeH)/(imageH-2*qp.edgeH)
		quadPatch.w = w
		quadPatch.h = h
		quadPatch.scaleW = scaleW
		quadPatch.scaleH = scaleH
	end
end


local function drawQuadPatch (qp)
	local x, y = qp.x, qp.y 
	local x1, x2, x3 = x+qp.x, x+qp.x+qp.edgeW, x+qp.x+qp.w-qp.edgeW
	local y1, y2, y3 = y+qp.y, y+qp.y+qp.edgeH, y+qp.y+qp.h-qp.edgeH
	
	love.graphics.draw(qp.image, qp.quads[1], x1, y1)
	love.graphics.draw(qp.image, qp.quads[2], x2, y1, 0, qp.scaleW, 1)
	love.graphics.draw(qp.image, qp.quads[3], x3, y1)
	
	love.graphics.draw(qp.image, qp.quads[4], x1, y2, 0, 1, qp.scaleH)
	love.graphics.draw(qp.image, qp.quads[5], x2, y2, 0, qp.scaleW, qp.scaleH)
	love.graphics.draw(qp.image, qp.quads[6], x3, y2, 0, 1, qp.scaleH)
	
	love.graphics.draw(qp.image, qp.quads[7], x1, y3)
	love.graphics.draw(qp.image, qp.quads[8], x2, y3, 0, qp.scaleW, 1)
	love.graphics.draw(qp.image, qp.quads[9], x3, y3)
end

function love.load()
	QP = newQuadPatch (love.graphics.newImage('image.png'), 32, 32, 32, 32)
end

function love.update(dt)
end

function love.draw()
	drawQuadPatch (QP)
end

function love.keypressed(key, scancode, isrepeat)
   if key == "escape" then
      love.event.quit()
   end
end


function love.mousemoved(mx, my)
   updateQuadPatch (QP, mx, my)
end
Attachments
main.lua
(2.69 KiB) Downloaded 42 times
image.png
image.png (6.53 KiB) Viewed 1430 times
Screenshot 2023-06-29 200909.png
Screenshot 2023-06-29 200909.png (49.51 KiB) Viewed 1431 times
Screenshot 2023-06-29 200915.png
Screenshot 2023-06-29 200915.png (71.26 KiB) Viewed 1431 times
:awesome: in Lua we Löve
:awesome: Platformer Guide
:awesome: freebies
User avatar
notcl4y
Citizen
Posts: 85
Joined: Fri Nov 25, 2022 12:23 pm

Re: 9Patch

Post by notcl4y »

Ok, thanks

Code: Select all

loves_lua = "not so",
wants_to = true
User avatar
notcl4y
Citizen
Posts: 85
Joined: Fri Nov 25, 2022 12:23 pm

Re: 9Patch

Post by notcl4y »

Looks like I'll have to send the library code again because I couldn't figure everything in your code out to fit mine. :o:

Code: Select all

loves_lua = "not so",
wants_to = true
User avatar
notcl4y
Citizen
Posts: 85
Joined: Fri Nov 25, 2022 12:23 pm

Re: 9Patch

Post by notcl4y »

Here :o:

Code: Select all

local lib = {}

function lib.load(filename, edgeW, edgeH)
	local image = love.graphics.newImage(filename)
	local imageW, imageH = image:getDimensions()
	local middleW, middleH = imageW - 2*edgeW, imageH - 2*edgeH
	
	-- quads:
	-- 1 2 3
	-- 4 5 6
	-- 7 8 9
	
	local quad1 = love.graphics.newQuad(0,0, edgeW, edgeH, image)
	local quad2 = love.graphics.newQuad(edgeW, 0, middleW, edgeH, image)
	local quad3 = love.graphics.newQuad(edgeW+middleW,0, edgeW, edgeH, image)
	
	local quad4 = love.graphics.newQuad(0,edgeH, edgeW, middleH, image)
	local quad5 = love.graphics.newQuad(edgeW,edgeH, middleW, middleH, image)
	local quad6 = love.graphics.newQuad(edgeW+middleW,edgeH, edgeW, middleH, image)
	
	local quad7 = love.graphics.newQuad(0,edgeH+middleH, edgeW, edgeH, image)
	local quad8 = love.graphics.newQuad(edgeW,edgeH+middleH, middleW, edgeH, image)
	local quad9 = love.graphics.newQuad(edgeW+middleW,edgeH+middleH, edgeW, edgeH, image)
	
	local quadPatch = {
		w = imageW,
		h = imageH,
		edgeW = edgeW,
		edgeH = edgeH,
		quads = {quad1, quad2, quad3, quad4, quad5, quad6, quad7, quad8, quad9},
		image = image,
	}
	return quadPatch
end

function lib.draw(patch, x, y, scaleX, scaleY)
	local x1, x2, x3 = x, x+patch.edgeW, x+patch.w-patch.edgeW
	local y1, y2, y3 = y, y+patch.edgeH, y+patch.h-patch.edgeH

	love.graphics.draw(patch.image, patch.quads[1], x1, y1)
	love.graphics.draw(patch.image, patch.quads[2], x2, y1, 0, scaleX, 1)
	love.graphics.draw(patch.image, patch.quads[3], x3, y1)
	
	love.graphics.draw(patch.image, patch.quads[4], x1, y2, 0, 1, scaleY)
	love.graphics.draw(patch.image, patch.quads[5], x2, y2, 0, scaleX, scaleY)
	love.graphics.draw(patch.image, patch.quads[6], x3, y2, 0, 1, scaleY)
	
	love.graphics.draw(patch.image, patch.quads[7], x1, y3)
	love.graphics.draw(patch.image, patch.quads[8], x2, y3, 0, scaleX, 1)
	love.graphics.draw(patch.image, patch.quads[9], x3, y3)
end

return lib

Code: Select all

loves_lua = "not so",
wants_to = true
User avatar
darkfrei
Party member
Posts: 1181
Joined: Sat Feb 08, 2020 11:09 pm

Re: 9Patch

Post by darkfrei »

notcl4y wrote: Thu Jun 29, 2023 6:47 pm Here :o:

Code: Select all

function lib.draw(patch, x, y, scaleX, scaleY)
You set new scales, but where are you calculates new middleW and middleH after rescaling? Also update the w and h in the object.
:awesome: in Lua we Löve
:awesome: Platformer Guide
:awesome: freebies
User avatar
notcl4y
Citizen
Posts: 85
Joined: Fri Nov 25, 2022 12:23 pm

Re: 9Patch

Post by notcl4y »

darkfrei wrote: Fri Jun 30, 2023 4:55 am where are you calculates new middleW and middleH after rescaling?
Maybe turn those into getMiddle() function?

Code: Select all

loves_lua = "not so",
wants_to = true
Post Reply

Who is online

Users browsing this forum: No registered users and 46 guests