## How can i divide up a map?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
legendman3
Citizen
Posts: 68
Joined: Sun Jan 22, 2012 8:29 pm

### How can i divide up a map?

Say i want to take this map: http://upload.wikimedia.org/wikipedia/c ... States.PNG and divide it up so that each state is its own *clickable* object. How would i go about doing that? (code would be nice to look at...)
Last edited by legendman3 on Wed Feb 08, 2012 1:55 am, edited 1 time in total.

MarekkPie
Inner party member
Posts: 587
Joined: Wed Dec 28, 2011 4:48 pm
Contact:

### Re: How can i divide up a map?

A (relatively) simple way would be to color the map, using a specific color for a specific state, and then when you click on the map, get the pixel data and compare it to a color.

I'm eating right now, so you'll get no code, but I'll come back and add some later.

legendman3
Citizen
Posts: 68
Joined: Sun Jan 22, 2012 8:29 pm

### Re: How can i divide up a map?

MarekkPie wrote:A (relatively) simple way would be to color the map, using a specific color for a specific state, and then when you click on the map, get the pixel data and compare it to a color.

I'm eating right now, so you'll get no code, but I'll come back and add some later.
I will try to code that while you eat.

Using this map because its png so it has no artifacts. http://upload.wikimedia.org/wikipedia/c ... States.PNG

Jasoco
Inner party member
Posts: 3651
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

### Re: How can i divide up a map?

To expand on what MerekkPie said:

You could make a second version of the image where every state is colored a unique solid color. Simple easy colors that you know the RGB values for.

Then when you click on the visible map (Which would be the normal map, not the colored one) you would check the color of the pixel at the coordinates, but on the colored map's imageData instead by taking the X and Y and I believe use r, g, b, a = ImageData:getPixel( x, y )? I never used it myself. So I'm not sure how to put the color map inside imageData.

Then you check the R, G, B against your state table to figure out what color was clicked and what state the color associates with.

legendman3
Citizen
Posts: 68
Joined: Sun Jan 22, 2012 8:29 pm

### Re: How can i divide up a map?

Jasoco wrote:To expand on what MerekkPie said:

You could make a second version of the image where every state is colored a unique solid color. Simple easy colors that you know the RGB values for.

Then when you click on the visible map (Which would be the normal map, not the colored one) you would check the color of the pixel at the coordinates, but on the colored map's imageData instead by taking the X and Y and I believe use r, g, b, a = ImageData:getPixel( x, y )? I never used it myself. So I'm not sure how to put the color map inside imageData.

Then you check the R, G, B against your state table to figure out what color was clicked and what state the color associates with.
This is my code:

Code: Select all

function love.load()
map = love.graphics.newImage("map.png")
love.graphics.setMode(800, 519)
end

function love.draw()
love.graphics.draw(map, 0, 0)
end

function love.mousepressed()
x, y = love.mouse.getPosition()
r, g, b, a = love.graphics.getColor(x,y)
if a == 136 and g == 0 and b == 21 then
love.graphics.print("Why hello there.",0,0)
end
end
I used love.graphics.getColor(x,y) but i will try the ImageData:getPixel( x, y ).

EDIT: and nothing changed. It still didn't print the words.

MarekkPie
Inner party member
Posts: 587
Joined: Wed Dec 28, 2011 4:48 pm
Contact:

### Re: How can i divide up a map?

EDIT: ninja'ed.

https://love2d.org/wiki/love.image.newImageData

Though I was just going to say used the colored map as your viewed map, but Jasoco's method works if you want to keep the monocolored map. You might need to do some world-relative to map-relative conversions, since you aren't actually drawing the colored map, but it would be as simple as:

Code: Select all

function love.load()
colormap = love.graphics.newImageData("PATH/TO/COLOREDMAP")
colors = {...} -- the colors you used to color the colormap
regmap = love.graphics.newImage("PATH/TO/REGULARMAP")
offX = 100 -- the x-coord of your regmap
offY = 100 -- the y-coord of your regmap
end

function love.draw()
love.graphics.draw(regmap, offX, offY)
end

function love.mousepressed(x,y,b)
local r,g,b,a = colormap:getPixel(x - offX, y - offY)
for _,v in pairs(colors) do
if r == v.r and g == v.g and b == v.b and a == v.a then
-- selection code
end
end
end
You may even be able to loop through your imageData and not even need to keep track of your colors (though you might run into a bleed-over affect at the edges (I'm not too familiar with how image compression and whatnot works)):

Code: Select all

local function findColors(id)
local colors = {}
local w = id:getWidth() - 1
local h = id:getHeight() - 1
for x = 0, w do
for y = 0, h do
local r,g,b,a = id:getPixel()
if #colors > 0 then
local same = false
for _,v in pairs(colors) do
if r == v.r and g == v.g and b == v.b and a == v.a then
found = true
break
end
end
if not same then
colors[#colors + 1] = {r = r, g = g, b = b, a = a}
end
else
colors[1] = {r = r, g = g, b = b, a = a}
end
end
end
end
Keep in mind, the above will be VERY, VERY, VERY SLOW. Like, worst case (O(n^4)), if you have every single pixel a different color, and the size of your image is 16x16, then it will take 16^4 = 65536 iterations. Even the best case (Theta(n^2)), where the whole image is one color, will take 16^2 = 256 iterations. Only use that if you are extraordinarily lazy.

legendman3
Citizen
Posts: 68
Joined: Sun Jan 22, 2012 8:29 pm

### Re: How can i divide up a map?

MarekkPie wrote:https://love2d.org/wiki/love.image.newImageData

Though I was just going to say used the colored map as your viewed map, but Jasoco's method works if you want to keep the monocolored map. You might need to do some world-relative to map-relative conversions, since you aren't actually drawing the colored map, but it would be as simple as:

Code: Select all

function love.load()
colormap = love.graphics.newImageData("PATH/TO/COLOREDMAP")
colors = {...} -- the colors you used to color the colormap
regmap = love.graphics.newImage("PATH/TO/REGULARMAP")
offX = 100 -- the x-coord of your regmap
offY = 100 -- the y-coord of your regmap
end
I got some questions:
1. What do you mean by a coloredmap and a non-coloredmap?
2. I add all the different colors one by one into the colors{} array? Like colors[1] = {128,128,128}?

The rest makes sense.
MarekkPie wrote:-snip- Only use that if you are extraordinarily lazy.
Yeah that has too many disadvantages... and im not that lazy...

legendman3
Citizen
Posts: 68
Joined: Sun Jan 22, 2012 8:29 pm

### Re: How can i divide up a map?

By the way what am i doing wrong?

Code: Select all

colormap = love.graphics.newImageData("images/coloredmap.png")

MarekkPie
Inner party member
Posts: 587
Joined: Wed Dec 28, 2011 4:48 pm
Contact:

### Re: How can i divide up a map?

First question: I was going off Jasoco's explanation. If you do not want to give away what you are doing - on the fact that it might look really ugly - you could load a second map (into imageData) and find the appropriate pixel on that map relative to your cursor position. The map that is visible is the mono-chromatic map, but you compare the pixel data of the hidden colored map.

Second question: Yeah, though I would go make a separate file called "mapcolors.lua" (or something), and write it as:

Code: Select all

return {
black = {r =   0, g =   0, b =   0, a =   0},
white = {r = 255, g = 255, b = 255, a = 255},
...
}

Code: Select all

-- in main.lua
colors = require "PATH/TO/colors.lua"
You would have to loop through that table using pairs(), instead of ipairs() or a normal for loop, but pairs() is faster than either of those, so whatever.

Third question: It's love.image.newImageData().

vrld
Party member
Posts: 917
Joined: Sun Apr 04, 2010 9:14 pm
Location: Germany
Contact:

### Re: How can i divide up a map?

legendman3 wrote:

Code: Select all

colormap = love.graphics.newImageData("images/coloredmap.png")
love.image.newImageData
legendman3 wrote:

Code: Select all

function love.mousepressed()
x, y = love.mouse.getPosition()
r, g, b, a = love.graphics.getColor(x,y)
if a == 136 and g == 0 and b == 21 then
love.graphics.print("Why hello there.",0,0)
end
end
EDIT: and nothing changed. It still didn't print the words.
You're calling love.graphics.print() only in the frame where the user pressed the mouse. That cannot work. Even worse, you're calling it outside of love.draw(), which makes two reasons why it does not print anything. A third reason why this doesn't work is that you use an Image instead of ImageData. Do this instead:

Code: Select all

local mouse = {x=0,y=0}
local map
map = love.image.newImageData("map.png")
end

function love.mousepressed(x,y)
mouse.x = x
mouse.y = y
end

function love.draw()
r, g, b = map:getPixel(mouse.x, mouse.y)
if a == 136 and g == 0 and b == 21 then
love.graphics.print("Why hello there.",0,0)
end
end
I have come here to chew bubblegum and kick ass... and I'm all out of bubblegum.

hump | HC | SUIT | moonshine

### Who is online

Users browsing this forum: No registered users and 35 guests