I click the mouse hope to select the sprite(image,animation) on the program.
Method 1,get the location of the mouse , the sprite(image) location and the width and height,to judge whether the mouse's postion is in the image.OK!
Continue,the image is rectangle,but the sprite is not the rectangle,some part is transparent in the image,when I click on the transparent's part,it is in the image,but it is not in the sprite.It seems I need prepare the table to store the image info,which grid is transparent?When I use the animation,it is too complexity.
Method 2,get the color of the mouse click,judge whether the color is same as backgroud, that I do not need to store the image info.
OK,is there a function to get the color when click the mouse.or get the color on the special location on the image?
Method 3,Is there a more effect mode which I do not know?
OK thanks very much.
『QT』about click mouse to select the sprite(image)
-
- Prole
- Posts: 47
- Joined: Thu Sep 24, 2009 1:49 pm
Re: 『QT』about click mouse to select the sprite(image)
Till you get a better answer since i'm not an expert on this but I think one theoretical solution is use ImageData:getPixel to check the alpha of the clicked point in that image. If is transparent then you advance in Z-order of stack of objects sharing same location/pixel (drawing order). Continue to check the alpha in next object till you get an object that alpha not transparent and so you select then that object as draggable. (https://love2d.org/wiki/ImageData:getPixel).
-
- Prole
- Posts: 47
- Joined: Thu Sep 24, 2009 1:49 pm
Re: 『QT』about click mouse to select the sprite(image)
OK,thks!I'll try it
- ston
- Prole
- Posts: 21
- Joined: Fri Jan 27, 2012 9:53 am
- Location: Holt, a small village in Wiltshire. We have cider!
Re: 『QT』about click mouse to select the sprite(image)
To add to what coffee said, I think that you need to use a frame buffer to get at the image data, i.e. render your sprite into a frame buffer.
Just tested this using a simple 40x40 .png image, which was a small black square inside a transparent border:
If you click outside the image area entirely, "OUTSIDE" is displayed, "ALPHA: 255" is displayed if you have clicked in a part which is not transparent and "ALPHA: 0" if it is a transparent part of the image.
Things probably get more complicated if you have a stack of images and you have to navigate through their 'Z order' (I'm not sure how to do that yet, sorry).
HTH :-)
Just tested this using a simple 40x40 .png image, which was a small black square inside a transparent border:
Code: Select all
-- square.png is 40x40
state_string = ""
function love.load()
-- allow our black box image to be seen; pink-ish background
love.graphics.setBackgroundColor(200, 160, 160)
-- create a framebuffer to render the box image into
box_buffer = love.graphics.newFramebuffer(40, 40)
-- the box image
my_square = love.graphics.newImage("square.png")
-- set the render target
love.graphics.setRenderTarget(box_buffer)
-- draw the image into the framebuffer
love.graphics.draw(my_square, 0, 0)
-- clear the render target
love.graphics.setRenderTarget()
-- the box's image data
box_image_data = box_buffer:getImageData()
end
function love.draw()
-- draw the box in the buffer (at 100,100)
love.graphics.draw(box_buffer, 100, 100)
-- display the state string
love.graphics.print(state_string, 200, 200)
end
function love.mousepressed(x, y, button)
local in_area = false
-- is the click in our image area?
if x >= 100 and x < 140 and y >= 100 and y < 140 then
in_area = true
end
if not in_area then
state_string = "OUTSIDE"
end
if in_area then
r, g, b, a = box_image_data:getPixel(x - 100, y - 100)
state_string = "ALPHA: " .. a
end
end
Things probably get more complicated if you have a stack of images and you have to navigate through their 'Z order' (I'm not sure how to do that yet, sorry).
HTH :-)
Re: 『QT』about click mouse to select the sprite(image)
Thank you for your testing my concept but I'm not really sure if your system will work since isn't a demo with multiple objects. Are you thinking check a "flattened" buffer image with all objects? That won't work but however if you thinking do a temporary buffer for each separate image I think will do the trick.ston wrote:Things probably get more complicated if you have a stack of images and you have to navigate through their 'Z order' (I'm not sure how to do that yet, sorry).
HTH :-)
About Z order. Isn't quite hard if you do an object management similar or close to this one
https://love2d.org/wiki/Skip_list:Drawing_Order
The concept of z-order is nothing much more than have a table to keep the order that elements must be draw (sort of layering). Then I think would be enough do a clumsy sweep of all elements to see what is the first element at top that:
1 - is in the mouse position
2 - have that point transparent
EDITED: A possible flaw with the transparent technique is if the image object have inside alpha "holes". In that case would fail get that object even if wanted. Alternative to this would be create a engine that would use a alpha pixel data image (not a good description I know) that would keep if that point is intended to be draggable or not.
- ston
- Prole
- Posts: 21
- Joined: Fri Jan 27, 2012 9:53 am
- Location: Holt, a small village in Wiltshire. We have cider!
Re: 『QT』about click mouse to select the sprite(image)
I was only thinking of one image for the purpose of the little demo I knocked up. I don't see how a 'flattened buffer' could work at all (how would you decode it back to the image/sprite you're interested in?); you'd need to use a stack of frame buffers as you indicate and check though them until finding the uppermost one which isn't transparent where the mouse is clicking.coffee wrote:Are you thinking check a "flattened" buffer image with all objects?
As well as the 'alpha holes' problem, you might also need to take into consideration different levels of alpha-blending (not all images would necessarily have completely transparent regions), but you could quite easily associate an alpha level with any particular image.
Ta, quite useful info that.About Z order. Isn't quite hard if you do an object management similar or close to this one
https://love2d.org/wiki/Skip_list:Drawing_Order
Re: 『QT』about click mouse to select the sprite(image)
Yes, so as I said beforeston wrote: I was only thinking of one image for the purpose of the little demo I knocked up. I don't see how a 'flattened buffer' could work at all (how would you decode it back to the image/sprite you're interested in?)
That won't work
Sorry, I wasn't doubting of your coding abilities but since I saw only one layer/object I wasn't sure if you were distracted/aware/noticed that possible problem dealing with multiple objects.
Well, that could work applying a value of 1 in alpha, but would turn a "dirty" method that actually could provoke some "ghost" image effects with some contrasting colors /large transparent zones or became worse when multiple transparent objects stacked. As coding method we woudn't be doing the right thing but yes could work as turnaround to avoid implement other measures or create "data" images for all draggable objects. Good suggestion.ston wrote:As well as the 'alpha holes' problem, you might also need to take into consideration different levels of alpha-blending (not all images would necessarily have completely transparent regions), but you could quite easily associate an alpha level with any particular image.
- ston
- Prole
- Posts: 21
- Joined: Fri Jan 27, 2012 9:53 am
- Location: Holt, a small village in Wiltshire. We have cider!
Re: 『QT』about click mouse to select the sprite(image)
You got me to thinking about multiple layers earlier on today, so I've knocked up a better demo this evening.
This draws 10 random circles to the screen. Each time one is clicked on, it's brought up to the top of the Z-order and allows you to drag it about with the mouse. That way, you can see that a circle at any z-order can be selected. It uses the same framebuffer/alpha-channel idea as before.
This draws 10 random circles to the screen. Each time one is clicked on, it's brought up to the top of the Z-order and allows you to drag it about with the mouse. That way, you can see that a circle at any z-order can be selected. It uses the same framebuffer/alpha-channel idea as before.
Code: Select all
-- main layers table
t = {}
function love.load()
-- get window size
win_x = love.graphics.getWidth()
win_y = love.graphics.getHeight()
-- set b/g colour
love.graphics.setBackgroundColor(220, 180, 180)
-- the point at which the mouse clicks one of the circles
bound_x = 0
bound_y = 0
-- create our set of circles
for i = 1, 10, 1 do
-- new drawing layer
layer = {}
-- circle's radius
c_radius = math.random(40, 80)
-- circle's colour
r = math.random(50, 255)
g = math.random(50, 255)
b = math.random(50, 255)
-- framebuffer to draw the circle to
f_buff = love.graphics.newFramebuffer(c_radius * 2, c_radius * 2)
-- draw the circle into the framebuffer
love.graphics.setRenderTarget(f_buff)
love.graphics.setColor(r, g, b)
love.graphics.circle("fill", c_radius, c_radius, c_radius, 30)
love.graphics.setRenderTarget()
-- starting position for the framebuffer containing this circles
-- framebufer is within the bounds of the window
buff_x = math.random(0, win_x - c_radius * 2)
buff_y = math.random(0, win_y - c_radius * 2)
-- create this layer's information
-- framebuffer
layer["f_buff"] = f_buff
-- x, y position
layer["buff_x"] = buff_x
layer["buff_y"] = buff_y
-- width and height of framebuffer
layer["buff_w"] = c_radius * 2
layer["buff_h"] = c_radius * 2
-- whether this circle is being held by the mouse
layer["bound"] = false
-- add the new layer to the collection
t[i] = layer
end
end
function love.draw()
-- iterate through the layers and draw each framebuffer
-- this is effectively in reverse Z-order
for i = 1, 10, 1 do
this_layer = t[i]
love.graphics.draw(this_layer["f_buff"], this_layer["buff_x"], this_layer["buff_y"])
end
end
-- checks to see whether the mouse click is inside the circle within the provided framebuffer layer
-- x, y are the mouse-click coordinates
function click_is_inside(the_layer, x, y)
rc = false
within = false
-- get the bounds of the frame buffer; left, right, top, bottom
buff_l = the_layer["buff_x"]
buff_r = buff_l + the_layer["buff_w"]
buff_t = the_layer["buff_y"]
buff_b = buff_t + the_layer["buff_h"]
-- is the mouse click within the bounds of the framebuffer?
if buff_l <= x and x <= buff_r and buff_t <= y and y <= buff_b then
within = true
end
if within then
-- click is within the framebuffer, is it on the circle contained therein?
f_buffer = the_layer["f_buff"]
-- check the alpha of the pixel where the mouse is
img_data = f_buffer:getImageData()
r, g, b, a = img_data:getPixel(x - buff_l, y - buff_t)
if a == 255 then
-- the click is on the circle
rc = true
end
end
return rc
end
function love.update(dt)
-- is the top circle bound?
if t[10]["bound"] then
-- yes; update its framebuffer position according to the relative mouse movement
mouse_x, mouse_y = love.mouse.getPosition()
-- how far has the mouse moved since the last update?
diff_x = mouse_x - bound_x
diff_y = mouse_y - bound_y
-- update our 'capture point' information, otherwise we'll start
-- accelerating the movement of the circle (not what we want)
bound_x = mouse_x
bound_y = mouse_y
-- finally, move the framebuffer to track the mouse movement
t[10]["buff_x"] = t[10]["buff_x"] + diff_x
t[10]["buff_y"] = t[10]["buff_y"] + diff_y
end
end
function love.mousepressed(x, y, button)
-- reverse-traverse the layers (highest Z order first)
for i = 10, 1, -1 do
this_layer = t[i]
if click_is_inside(this_layer, x, y) then
-- 'bound' for dragging
this_layer["bound"] = true
-- record the point where the mouse grabbed the circle
bound_x = x
bound_y = y
-- promote the layer to the top of the Z-order
table.remove(t, i)
table.insert(t, this_layer)
-- job done; only one circle can be clicked
break
end
end
end
function love.mousereleased(x, y, button)
-- clear the 'bound' condition; we only need to do this
-- for the top layer as it's always promoted when clicked on :-)
t[10]["bound"] = false
end
Re: 『QT』about click mouse to select the sprite(image)
Nice, your Z-code works but you probably have something wrong eating memory or infinite looping. I change and move some circles but some time after always crash.ston wrote:You got me to thinking about multiple layers earlier on today, so I've knocked up a better demo this evening.
This draws 10 random circles to the screen. Each time one is clicked on, it's brought up to the top of the Z-order and allows you to drag it about with the mouse. That way, you can see that a circle at any z-order can be selected. It uses the same framebuffer/alpha-channel idea as before.
Is still poorenglish around to enjoy this?
-
- Prole
- Posts: 47
- Joined: Thu Sep 24, 2009 1:49 pm
Re: 『QT』about click mouse to select the sprite(image)
Sorry,late to replay,I enjoy it.
When I use it on animation,it seems need modify on the AnAL.lua?
When I use it on animation,it seems need modify on the AnAL.lua?
Who is online
Users browsing this forum: No registered users and 4 guests