Hey, I'm currently working on a card game. On the screen, each player's hand is drawn as a fan of cards (image below), where cards may slightly overlap each other, this means that by simply checking if the mouse is within each card's rectangle sometimes returns more than one card. I figured I could check which one of them has the bigger index and make this one the "hovered" card, but I thought there might be a better way of doing this?
The cards are all kept on a table, each one has `x` and `y` coordinates and a `rotation`. They're drawn in order (from 1 to ...).
Layered mouse collision
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
Re: Layered mouse collision
You are correct, this is by far the simplest technique.I figured I could check which one of them has the bigger index and make this one the "hovered" card
Suppose you have a numerically indexed table of cards - you are drawing them in order so cards with a higher index are drawn on top.
Next, you want something to "query" those cards:
Code: Select all
cards = {}
function query(cards, x, y)
-- NOTE: iterate in reverse so that the top card is selected first
for i = #cards, 1, -1 do
if testCard(cards[i], x, y) then
return cards[i], i
end
end
end
function testCard(card, x, y)
-- WARNING: assumes the top left corner of the card is the origin (0, 0)
-- convert to local coords
local lx, ly = x - card.x, y - card.y
-- rotate so that we are axis aligned
local c = math.cos(card.angle)
local s = math.sin(card.angle)
local rx = c*lx - s*ly
local ry = s*lx + c*ly
-- axis aligned test
return rx >= 0 and rx <= card.width and ry >= 0 and ry <= card.height
end
It's easier if you rotate cards around their center but then your "axis aligned test" needs to be modified slightly.
Good luck!
Re: Layered mouse collision
Thanks! By the way, how would I go about doing those calculations when the origin is the bottom-center (0.5, 1)?
Re: Layered mouse collision
Believe me, the math is much simpler and more scalable if use the "center" option and it makes drawing easier too.
You only need to change the last line:
Top left corner:
Center:
Bottom-center:
Assuming that:
0,0 is the to-left corner of the window
card.x, card.y = origin point of the card (window coordinates)
card.angle = angle of the card in radians (objects rotate counter-clockwise as this value increases)
edit: the rotation might be reversed if your y-axis increases down (or South) which is customary when drawing with Love2d
Personally I take it one step further and program my games with the Y axis increasing up (North) and I assume that 0,0 is the center of the window - it makes the trigonometry calculations even simpler.
You only need to change the last line:
Top left corner:
Code: Select all
return rx >= 0 and rx <= w and ry >= 0 and ry <= h
Code: Select all
return rx >= -w/2 and rx <= w/2 and ry >= h/2 and ry <= h/2
Code: Select all
return rx >= -w/2 and rx <= w/2 and ry >= -h and ry <= 0
0,0 is the to-left corner of the window
card.x, card.y = origin point of the card (window coordinates)
card.angle = angle of the card in radians (objects rotate counter-clockwise as this value increases)
edit: the rotation might be reversed if your y-axis increases down (or South) which is customary when drawing with Love2d
Personally I take it one step further and program my games with the Y axis increasing up (North) and I assume that 0,0 is the center of the window - it makes the trigonometry calculations even simpler.
Last edited by ivan on Wed Apr 25, 2018 8:03 pm, edited 4 times in total.
Re: Layered mouse collision
I tried your code and this happens:
It only seems to detect a collision correctly when there's a single card (with almost no rotation):
It seems to depend on the angle of the card.Re: Layered mouse collision
Nevermind, your code assumes that the card rotates counter-clockwise with the angle, but they rotate clockwise. So I just changed the instances of rotation to -rotation!
Re: Layered mouse collision
I'm pretty sure that the technique I posted works...
It might not work using copy/paste - additional work may be required, depending on how you draw the cards.
You need to include a .love file if you expect me to help you any further.
It might not work using copy/paste - additional work may be required, depending on how you draw the cards.
You need to include a .love file if you expect me to help you any further.
Re: Layered mouse collision
That's a standard assumption in trigonometry (math.cos/math.sin) it's just a question of how you decide to draw the cards.
Again, it's very important to distinguish between your logic/math code and your rendering/drawing code.
PS. Actually, if your Y-axis increases down like in love2d, that might flip the angle.
Who is online
Users browsing this forum: No registered users and 5 guests