# Thread: Non-rectangular partially visible sprite selection

1. ## Non-rectangular partially visible sprite selection

Hi!

I'm trying to make a puzzle game, and I'd like it to be as real as possible. The pieces of the puzzle are covering each other randomly, and the user can freely select any piece, not only the topmost. A sole condition - as in the real life - he must see the piece.

Now how can I find out which piece was selected (where was the mouse when the mouse pointer when the mouse button was pressed)?

Please note that the pieces are not rectangular, but as in a real puzzle.
Maybe only a few pixels can be seen from a given piece, as the other are covering it...

I have to determine somehow, whether the mouse is over the visible part of the mask (and not the rectangular sprite irtself!) for the given piece (sprite).

Is there any DirectX API for that? Any ideas? Any help would be welcome! (I'll mention your name in the source and "Greetingz" section )

2. You could lock the surface and do a per-pixel check and return true at the first instance that the mouse is over a non-transparent color. Of course, surface locking/unlocking can really slow you down a lot. Depending on how large the bitmaps are, you might now see too much of a hit though.

3. My problem is, that even if the mouse is over a non-transparent color, how would I know which sprite owns the given pixel? (see attached picture).
Supposing I've got three sprites, and I blit them to the primary surface, they will cover each other (the user can freely move the pieces, as in the real game). Now how can I bring to front the selected sprite, that's my problem.

I have searched for a solution, none found yet...

Any ideas? Thank you in advance!

4. Well here is one solution possibly. This is all theory so keep that in mind.

Lets limit our discussion to two sprites for simplicity. Now when the user clicks you check point in rect collision and notice that the user has clicked within both rects. Here lies the problem, which sprite did he want. Well he probably wants the top-most. This may be terribly slow but I would lock the back-buffer or primary display ( whatever ) and find the color at that pixel. Then you will need the x,y locations into each of the given source rects. Index into the rects and check the color at that location with the color you obtained from the main display. Remember you don't have to lock the whole back buffer!! Just lock the portion important to you. Hopefully this will help.

5. Good idea!
I struggled with something similar idea, but ran into problems, as I approached the problem through region-border compare.
Yes, I think this will work!

Thank you very much!

P.s.
However, still not the best solution, as there is a relative high probability that two sprites have the same pixel at a given location...

6. How about Z-Ordering? Give them a depth value and then when you find the "click" has intersected multiple sprites ( rects ) check their z-values to determine which was selected.

7. Not speaking of this situation, where even checking the neighbour points won't help... :°(

8. Z-ordering? I store the sprites in DIRECTDRAWSURFACE7 objects, and have no idea how to do that...

P.s.
I'm not a DirectX-guru (yet :°)).

9. Well I'm not sure exactly how you structure your game or code but the basic idea is simple. Whenever you are drawing the sprites to the back buffer you draw them furthest to nearest. You can do this by sorting your sprites by their Z-Value. How do you do it now? How would one sprite get behind another one? I'm not sure of some of the finer details of your game but I think this would be the way to go. I'll explain it further tomorrow if necessary.

10. Thanks, in the meantime I try to figure out how to implement this by my own.

11. Instead of checking at the final (main) surface, check at every object's own surface.
Code:
```FOR (Every object you want to test at) LOOP

IF ((Mouse position) INSIDE (Current objects rectangular bounds)) THEN

IF ((Colour at (Mouse.X - Object.X), (Mouse.Y - Object.Y) in Object's surface) != Transparent) THEN

ClickedObject = Object;
BREAK LOOP;

END IF;

END IF

END LOOP```

12. Thanks for your suggestion, Magos!

But what if e.g. two or more overlapped sprites have the same color on the same location?

I guess I have to check for Z-order -as MrWizard proposed - as well to avoid this problem, what do you think?

13. Originally posted by Carlos

But what if e.g. two or more overlapped sprites have the same color on the same location?

I guess I have to check for Z-order -as MrWizard proposed - as well to avoid this problem, what do you think?
I forgot to mention, when traversing all the objects you start with the one in front (ie: Reverse rendering order). If two have a non-transparent pixel at the mouse position, the one in front will be selected since it is tested first (the rest is skipped when one is found).

14. Hi!

Finally I found a good approach of the puzzle game
here.
However, there is - in my opinion - a little bug, as the pieces have a given Z-order, which can not be modified. Check out when you try to select one of the overlapped pieces, not the topmost will be selected, and when moving a piece, it will move on it's Z-plane.
In my project I want the selected piece to be above all others, as "in real life".

I'd like to write something similar, however a bit more complex:
- different levels (100 / 500 / 1000 / user configurable number of pieces)
- configurable keys
- multiplayer mode
- scoreboard + hall of fame
- optional sound effects + music

All I need is some time, as the idea is given .

Thanks in advance for (further) ideas and help!

15. What i'd do:

What you need to do when the user clicks (or selects a piece) is:
Find all sprites with which the mouse pointer intersects. Sort each sprite and ascend down the list (from topmost first) and check each sprite at mouse X, Y for a non-transparent pixel. The first sprite to have a non-transparent pixel at mouse X, Y is the sprite they selected.