Overlapping Object Selection

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
User avatar
vynom
Prole
Posts: 28
Joined: Sat Oct 05, 2013 4:42 pm
Location: Teh Interwebz
Contact:

Overlapping Object Selection

Post by vynom » Sun Nov 16, 2014 12:24 pm

Hello everyone!

I have been working on a very small gui implementation, and for the life of me cannot come up with a way to do something(in theory seems very straightforward).

If 2 frames with an x, y, width, and height, are overlapping, how can you set the top-most window to "active" or "selected?" Everything I start to come up with becomes incredibly verbose for something that will be called every frame update, so I'm hoping someone out there might have a better idea(that works of course :megagrin: ). I thought a push/pop might work, but determining the top window to move to the top still selects multiple, almost like I need to filter through the table backwards.

Any help would be appreciated

User avatar
lost_RD
Prole
Posts: 23
Joined: Sun Nov 24, 2013 9:16 am
Location: Australia

Re: Overlapping Object Selection

Post by lost_RD » Mon Nov 17, 2014 3:20 am

Have you tried using z-levels?

User avatar
micha
Inner party member
Posts: 1083
Joined: Wed Sep 26, 2012 5:13 pm

Re: Overlapping Object Selection

Post by micha » Mon Nov 17, 2014 7:01 am

Could you please post a .love file and explain how to reproduce the problem?

User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: Overlapping Object Selection

Post by s-ol » Mon Nov 17, 2014 9:45 am

micha wrote:Could you please post a .love file and explain how to reproduce the problem?
lost_RD wrote:Have you tried using z-levels?
OP is kil

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end

User avatar
vynom
Prole
Posts: 28
Joined: Sat Oct 05, 2013 4:42 pm
Location: Teh Interwebz
Contact:

Re: Overlapping Object Selection

Post by vynom » Mon Nov 17, 2014 6:21 pm

A z-list would seem beneficial for draw order, the problem I have come across was how to get the top-most selected window.

I used the example from Nova-fusion to throw a quick example up(so you can see what I mean, if I had a way to demonstrate it any better... it would be fixed lol :D )

When the objects overlap, and you try to move only one, they both move. I need to be able to set the "top" one to current, so only it will be moveable.

I also need to be able to select another rect as the top or current by clicking the other where they dont overlap to set it on top.

Using the boundaries to determine another window is selected is fine, until they overlap, then I run into a problem with it returning multiple true statements for the collision check to set the rect on top.

Hopefully this clears it up

EDIT>>
OP is kil
I have no idea what that means.
Attachments
Drag.love
(616 Bytes) Downloaded 61 times

User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: Overlapping Object Selection

Post by s-ol » Mon Nov 17, 2014 7:11 pm

vynom wrote:A z-list would seem beneficial for draw order, the problem I have come across was how to get the top-most selected window.
Just stop when you get the first one!
vynom wrote:
OP is kil
I have no idea what that means.
It's a joke and slang for "OP died", you didn't respond for a while so I assumed you were gone.

Anyway,

Code: Select all

function love.draw()
	for i=#Rect.list,1,-1 do -- opposite order
		Rect.list[i]:draw()
	end
end

function love.mousepressed(x, y, button)
	if button == "l" then
		for i,v in ipairs(Rect.list) do -- assuming Rect.list is sorted so that first windows are higher
			if x > v.x and x < v.x + v.width
			and y > v.y and y < v.y + v.height
			then
			v.dragging.active = true
			v.dragging.diffX = x - v.x
			v.dragging.diffY = y - v.y
			return -- stop here!
			end
		end
	end
end
If keeping the list ordered is too much of a hassle then add a z attribute to each rect and select them like this: (note that drawing them like this gets even messier):

Code: Select all

local top, z = nil, -1
for _,v in ipairs(Rect.list) do
	if v.z > z and <...check hit...> then
		z = v.z
		top = v
	end
end
if not top then return end -- none hit
Last edited by s-ol on Tue Nov 18, 2014 10:53 pm, edited 1 time in total.

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end

Muris
Party member
Posts: 131
Joined: Fri May 23, 2014 9:18 am

Re: Overlapping Object Selection

Post by Muris » Tue Nov 18, 2014 7:43 pm

As far as I understand the topmost object is the one that is last drawn. So if you draw objects like from 1 to n, then the nth indexed object will always be topmost regardless where the object resides on the window. So to figure out which object it hits, just go it through in reverse order ( from n to 1 ), until it hits one, or if none of the boxes are within boundaries then pick none.

Edit: Also to point out the post on top of mine, never use pairs() if you want to be sure to have defined order. Atleast according to lua tutorial there is no guarantee in which order pairs() returns, unlike ipairs always goes from 1 to n. http://lua-users.org/wiki/ForTutorial

Altho according to this http://coronalabs.com/blog/2013/03/12/p ... mizations/ in lua using ipairs is not recommended, because apparently it generates some overhead, but to just use for loop.

Code: Select all

for i = 1, #table do
   print( table[i] )
end

User avatar
vynom
Prole
Posts: 28
Joined: Sat Oct 05, 2013 4:42 pm
Location: Teh Interwebz
Contact:

Re: Overlapping Object Selection

Post by vynom » Tue Nov 18, 2014 7:55 pm

Both were what I was looking for, along with removing and readding to the table to move it to the end, thanks!

User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: Overlapping Object Selection

Post by s-ol » Tue Nov 18, 2014 10:52 pm

Muris wrote:As far as I understand the topmost object is the one that is last drawn. So if you draw objects like from 1 to n, then the nth indexed object will always be topmost regardless where the object resides on the window. So to figure out which object it hits, just go it through in reverse order ( from n to 1 ), until it hits one, or if none of the boxes are within boundaries then pick none.

Edit: Also to point out the post on top of mine, never use pairs() if you want to be sure to have defined order. Atleast according to lua tutorial there is no guarantee in which order pairs() returns, unlike ipairs always goes from 1 to n. http://lua-users.org/wiki/ForTutorial

Altho according to this http://coronalabs.com/blog/2013/03/12/p ... mizations/ in lua using ipairs is not recommended, because apparently it generates some overhead, but to just use for loop.

Code: Select all

for i = 1, #table do
   print( table[i] )
end
whoops, I meant to use ipairs there aswell.

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end

Post Reply

Who is online

Users browsing this forum: drfractal and 7 guests