AUTOMATIC QUAD DETECTOR
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
-
- Prole
- Posts: 17
- Joined: Fri Nov 26, 2021 5:15 am
AUTOMATIC QUAD DETECTOR
can someone please help with love2d function which can detect a quad from RPG sprite automatically. currently I am guessing the quad dimension and generating it with love.graphics.newQuad(). Please help me in this regard.
- EngineerSmith
- Prole
- Posts: 38
- Joined: Thu Dec 02, 2021 11:38 am
- Contact:
Re: AUTOMATIC QUAD DETECTOR
Why would you need to guess the size of your quads? They should all be equal in size to allow easy animation. Just count the width and height of the first frame and that's the size of that quad for that animation. You could write a meta file which holds this information for each file and have a system that reads that meta file to find how the size (You'd have to write the file though).
Unless your sprites are separate pngs then you can use a texture atlas packer like mine https://github.com/EngineerSmith/Export-TextureAtlas then you can add it to your build pipeline which packs all the sprites together and outputs a file with all the quad data to read in
Unless your sprites are separate pngs then you can use a texture atlas packer like mine https://github.com/EngineerSmith/Export-TextureAtlas then you can add it to your build pipeline which packs all the sprites together and outputs a file with all the quad data to read in
-
- Prole
- Posts: 17
- Joined: Fri Nov 26, 2021 5:15 am
Re: AUTOMATIC QUAD DETECTOR
EngineerSmith , sorry to say , but I am not particularly clear with your explanation. For example, from your first picture how would you know what will be the size of the fist quad so that the figure of first cat fits in exactly.
- EngineerSmith
- Prole
- Posts: 38
- Joined: Thu Dec 02, 2021 11:38 am
- Contact:
Re: AUTOMATIC QUAD DETECTOR
I'd open it in my picture editing software of choice and draw a shape over it or you can just make an educated guess: if the sprite sheet only contains one animation like those cats in top most picture each frame would be (10 frames / 380 pixels width)X(60 pixels height) : 38x60
Re: AUTOMATIC QUAD DETECTOR
That depends entirely on how you index your quads. Personally, I index them as a one-dimensional table that I create when I load the image. You can index them differently, but you'll need to adapt my code to fit your style. Note that all code I'm about to post assumes there's a 1 pixel border between sprites, as recommended on the wiki to prevent bleeding when things get rotated or scaled.DebasishDatta wrote: ↑Sun Dec 19, 2021 4:52 am can someone please help with love2d function which can detect a quad from RPG sprite automatically. currently I am guessing the quad dimension and generating it with love.graphics.newQuad(). Please help me in this regard.
This is the function I use to create quads for a given image:
Code: Select all
function newQuadsList(tileSize, width, height)
local tilesX = (width - 1) / (tileSize + 1)
local tilesY = (height - 1) / (tileSize + 1)
local quadsList = {}
for y = 1, tilesY do
for x = 1, tilesX do
quadsList[(y - 1) * tilesX + x] = love.graphics.newQuad((x - 1) * (tileSize + 1) + 1, (y - 1) * (tileSize + 1) + 1, tileSize, tileSize, width, height)
end
end
return quadsList
end
I also wrote a tool to help me with exactly this same problem - finding the quad index number for a given sprite. Here it is! It assumes sprites are 32x32 pixels, but you can change that before running it. Just run it, then drag & drop your picture on it and mouse over the quad you want to know about. Use arrow keys to scroll the image and ESC to quit.
Code: Select all
-- Quad Finder
-- Helps determine a tile's position & quad number within its image
-- Assumes a 1px border between each tile!
-- User Input
local tiles = {w=32, h=32} -- Size in pixels of tiles in image
-- Initialize
love.keyboard.setKeyRepeat(true)
image, mouse, screen = {}, {}, {}
screen.w, screen.h = love.graphics.getDimensions()
love.window.setMode(screen.w, screen.h, {resizable=true})
image.x, image.y, mouse.x, mouse.y = 0, 0, 0, 0
mouse.tile, mouse.tileX, mouse.tileY, image.file = "na", "na", "na", "na"
screen.foot = 35
function updateFooter()
if image.img then
screen.text = "Quad:"..mouse.tile.." tile:"..mouse.tileX..","..mouse.tileY.." mouse:"..mouse.x..","..mouse.y.."\nsize:"..image.w.."x"..image.h.." file:"..image.file
else
screen.text = "Drag & drop a picture here!"
end
end
function love.resize(w, h)
screen.w, screen.h = w, h
end
function love.load()
updateFooter()
end
function love.keypressed(key)
if key == "left" or key == "a" and image.x < 0 then image.x = image.x + 10
elseif key == "right" or key == "d" and image.x + image.w > screen.w then image.x = image.x - 10
elseif key == "up" or key == "w" and image.y < 0 then image.y = image.y + 10
elseif key == "down" or key == "s" and image.y + image.h > screen.h - screen.foot then image.y = image.y - 10
elseif key == "escape" then love.event.quit()
end
end
function love.filedropped(file)
image.x, image.y = 0, 0
if image.img then image.img:release(); image.img = nil end
image.img = love.graphics.newImage(file)
image.w, image.h = image.img:getDimensions()
if type(file) ~= "string" then file = file:getFilename() end
image.file = file
image.tilesX = (image.w - 1) / (tiles.w + 1)
image.tilesY = (image.h - 1) / (tiles.h + 1)
assert(image.tilesX == math.floor(image.tilesX), "Incorrect image or tile size supplied!\nImage is "..image.w.."x"..image.h.."\nExpected tile size was "..tiles.w.."x"..tiles.h.."\nResulting image tile size: "..image.tilesX.." x "..image.tilesY)
updateFooter()
end
function love.mousemoved(x, y, dx, dy)
if not image.img then return end
-- update x-axis
mouse.x = x - image.x
if mouse.x > image.w then
mouse.tileX = "na"
else
mouse.tileX = mouse.x / (tiles.w + 1)
if mouse.tileX == math.floor(mouse.tileX) then
mouse.tileX = "na"
else
mouse.tileX = math.floor(mouse.tileX) + 1
end
end
-- update y-axis
mouse.y = y - image.y
if mouse.y > image.h then
mouse.tileY = "na"
else
mouse.tileY = mouse.y / (tiles.h + 1)
if mouse.tileY == math.floor(mouse.tileY) then
mouse.tileY = "na"
else
mouse.tileY = math.floor(mouse.tileY) + 1
end
end
-- update hover tile
if mouse.tileX == "na" or mouse.tileY == "na" then
mouse.tile = "na"
else
mouse.tile = (mouse.tileY - 1) * image.tilesX + mouse.tileX
end
updateFooter()
end
function love.draw()
if image.img then love.graphics.draw(image.img, image.x, image.y) end
love.graphics.setColor(0, 0, 0)
love.graphics.rectangle("fill", 0, screen.h - screen.foot, screen.w, screen.foot)
love.graphics.setColor(1, 1, 1)
love.graphics.print(screen.text, 10, screen.h - screen.foot + 3)
end
Any code samples/ideas by me should be considered Public Domain (no attribution needed) license unless otherwise stated.
-
- Prole
- Posts: 17
- Joined: Fri Nov 26, 2021 5:15 am
Re: AUTOMATIC QUAD DETECTOR
That's very nice. Your code is a god one too. But if you know any function in love2d which can detect an optimum quad from an image file , that would be better, otherwise we have to manually fixed the image file first , then able to perform our operations e.g extracting quads etc.milon wrote: ↑Mon Dec 20, 2021 6:26 pmThat depends entirely on how you index your quads. Personally, I index them as a one-dimensional table that I create when I load the image. You can index them differently, but you'll need to adapt my code to fit your style. Note that all code I'm about to post assumes there's a 1 pixel border between sprites, as recommended on the wiki to prevent bleeding when things get rotated or scaled.DebasishDatta wrote: ↑Sun Dec 19, 2021 4:52 am can someone please help with love2d function which can detect a quad from RPG sprite automatically. currently I am guessing the quad dimension and generating it with love.graphics.newQuad(). Please help me in this regard.
This is the function I use to create quads for a given image:Code: Select all
function newQuadsList(tileSize, width, height) local tilesX = (width - 1) / (tileSize + 1) local tilesY = (height - 1) / (tileSize + 1) local quadsList = {} for y = 1, tilesY do for x = 1, tilesX do quadsList[(y - 1) * tilesX + x] = love.graphics.newQuad((x - 1) * (tileSize + 1) + 1, (y - 1) * (tileSize + 1) + 1, tileSize, tileSize, width, height) end end return quadsList end
I also wrote a tool to help me with exactly this same problem - finding the quad index number for a given sprite. Here it is! It assumes sprites are 32x32 pixels, but you can change that before running it. Just run it, then drag & drop your picture on it and mouse over the quad you want to know about. Use arrow keys to scroll the image and ESC to quit.
Code: Select all
-- Quad Finder -- Helps determine a tile's position & quad number within its image -- Assumes a 1px border between each tile! -- User Input local tiles = {w=32, h=32} -- Size in pixels of tiles in image -- Initialize love.keyboard.setKeyRepeat(true) image, mouse, screen = {}, {}, {} screen.w, screen.h = love.graphics.getDimensions() love.window.setMode(screen.w, screen.h, {resizable=true}) image.x, image.y, mouse.x, mouse.y = 0, 0, 0, 0 mouse.tile, mouse.tileX, mouse.tileY, image.file = "na", "na", "na", "na" screen.foot = 35 function updateFooter() if image.img then screen.text = "Quad:"..mouse.tile.." tile:"..mouse.tileX..","..mouse.tileY.." mouse:"..mouse.x..","..mouse.y.."\nsize:"..image.w.."x"..image.h.." file:"..image.file else screen.text = "Drag & drop a picture here!" end end function love.resize(w, h) screen.w, screen.h = w, h end function love.load() updateFooter() end function love.keypressed(key) if key == "left" or key == "a" and image.x < 0 then image.x = image.x + 10 elseif key == "right" or key == "d" and image.x + image.w > screen.w then image.x = image.x - 10 elseif key == "up" or key == "w" and image.y < 0 then image.y = image.y + 10 elseif key == "down" or key == "s" and image.y + image.h > screen.h - screen.foot then image.y = image.y - 10 elseif key == "escape" then love.event.quit() end end function love.filedropped(file) image.x, image.y = 0, 0 if image.img then image.img:release(); image.img = nil end image.img = love.graphics.newImage(file) image.w, image.h = image.img:getDimensions() if type(file) ~= "string" then file = file:getFilename() end image.file = file image.tilesX = (image.w - 1) / (tiles.w + 1) image.tilesY = (image.h - 1) / (tiles.h + 1) assert(image.tilesX == math.floor(image.tilesX), "Incorrect image or tile size supplied!\nImage is "..image.w.."x"..image.h.."\nExpected tile size was "..tiles.w.."x"..tiles.h.."\nResulting image tile size: "..image.tilesX.." x "..image.tilesY) updateFooter() end function love.mousemoved(x, y, dx, dy) if not image.img then return end -- update x-axis mouse.x = x - image.x if mouse.x > image.w then mouse.tileX = "na" else mouse.tileX = mouse.x / (tiles.w + 1) if mouse.tileX == math.floor(mouse.tileX) then mouse.tileX = "na" else mouse.tileX = math.floor(mouse.tileX) + 1 end end -- update y-axis mouse.y = y - image.y if mouse.y > image.h then mouse.tileY = "na" else mouse.tileY = mouse.y / (tiles.h + 1) if mouse.tileY == math.floor(mouse.tileY) then mouse.tileY = "na" else mouse.tileY = math.floor(mouse.tileY) + 1 end end -- update hover tile if mouse.tileX == "na" or mouse.tileY == "na" then mouse.tile = "na" else mouse.tile = (mouse.tileY - 1) * image.tilesX + mouse.tileX end updateFooter() end function love.draw() if image.img then love.graphics.draw(image.img, image.x, image.y) end love.graphics.setColor(0, 0, 0) love.graphics.rectangle("fill", 0, screen.h - screen.foot, screen.w, screen.foot) love.graphics.setColor(1, 1, 1) love.graphics.print(screen.text, 10, screen.h - screen.foot + 3) end
Re: AUTOMATIC QUAD DETECTOR
There is nothing like that as previously said. You could however do background color pixel detection between quads, e.g. iterating over X axis and looking (approximating) for space between images. Once you find a pattern of repeated background color over certain intervals (e.g. each 33px is white, while 32px and 34px are colored and same applies for 65px etc.), you could split quads based on that. This requires some fuzzy detection work.DebasishDatta wrote: ↑Tue Dec 21, 2021 4:18 am That's very nice. Your code is a god one too. But if you know any function in love2d which can detect an optimum quad from an image file , that would be better, otherwise we have to manually fixed the image file first , then able to perform our operations e.g extracting quads etc.
My boat driving game demo: https://dusoft.itch.io/captain-bradley- ... itius-demo
Re: AUTOMATIC QUAD DETECTOR
What are the tiles you are looking at? could you post an example?
-
- Prole
- Posts: 17
- Joined: Fri Nov 26, 2021 5:15 am
Re: AUTOMATIC QUAD DETECTOR
Ok, thank you for your suggestion.dusoft wrote: ↑Tue Dec 21, 2021 10:36 amThere is nothing like that as previously said. You could however do background color pixel detection between quads, e.g. iterating over X axis and looking (approximating) for space between images. Once you find a pattern of repeated background color over certain intervals (e.g. each 33px is white, while 32px and 34px are colored and same applies for 65px etc.), you could split quads based on that. This requires some fuzzy detection work.DebasishDatta wrote: ↑Tue Dec 21, 2021 4:18 am That's very nice. Your code is a god one too. But if you know any function in love2d which can detect an optimum quad from an image file , that would be better, otherwise we have to manually fixed the image file first , then able to perform our operations e.g extracting quads etc.
Who is online
Users browsing this forum: Google [Bot] and 2 guests