Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

AppGameKit Studio Chat / [SOLVED] Get all stacked sprites?

Author
Message
Ron2019
4
Years of Service
User Offline
Joined: 27th Jul 2019
Location:
Posted: 12th Feb 2020 17:27
I am developing a game that uses stacked sprites. GetSpriteHit only returns the top-most sprite ID per Depth, but I need to know the IDs for ALL of the sprites in the Stack, not just the top-most one. Is there some easy way to get a collection of the IDs for all of the stacked sprites? I am unable to identify a command to do so, but may not be looking for the right term? Functionality like that provided by GetSpriteFirstContact & GetSpriteNextContact would be my second choice, but neither GetSpriteHitNext nor GetSpriteNextHit appear to exist?

I am currently either moving each of the stacked sprites off-screen or to the bottom of the stack before issuing additional GetSpriteHit calls to obtain the list of sprites. Both of these work-arounds then require resetting either position or depth, which is a PITA for the number of sprites concerned. And I'd really like to avoid GetSpriteHitTest, because I don't want to have to iterate through every sprite in the game just to figure out which ones were hit.

Has anybody developed a better way to do this?

The author of this post has marked a post as an answer.

Go to answer

Ron2019
4
Years of Service
User Offline
Joined: 27th Jul 2019
Location:
Posted: 13th Feb 2020 15:57
Evidently not.
JosephB
17
Years of Service
User Offline
Joined: 12th Sep 2006
Location:
Posted: 13th Feb 2020 17:14
I have not yet had a need to develop code to determine the sprite IDs within a stack of sprites, but I have tried to imagine how to do this, but really need more information about the sprites and what is happening on the screen to try to help, if possible. Are the sprites moving or static? Is there a maximum number of sprites that are stacked? Do the sprites have a uniform shape and size? Do you have a picture and/or partial code you could provide? Not sure I am able to help, but willing to give it a try.
hendron
8
Years of Service
User Offline
Joined: 20th Dec 2015
Location:
Posted: 13th Feb 2020 18:36
You would think AppGameKit would provide this kind of functionality built in and I'm surprised it doesn't. I believe moving them off the screen or changing their depth like you said you're doing now is pretty much the simplest way to do it. I would just put it in a function.

Ron2019
4
Years of Service
User Offline
Joined: 27th Jul 2019
Location:
Posted: 14th Feb 2020 17:47 Edited at: 14th Feb 2020 17:50
Stacks may currently be as deep as 10 sprites, but I can easily envision a need for more. All use transparent backgrounds to construct composite graphics on the fly, consisting of:
* 1 to 3 sprites used to construct a basic playing piece;
* Overlaid sprites indicating valid and invalid moves, which are added to the top of a stack during play validation;
* Underlying sprites to apply a background color for an entire stack, also added during validation;
* Sprites inserted between layers of the stack to highlight specific sprites in the stack when played;
* And there are also board sprites at the deepest level, which I need to identify as the sprite stack is moved around, in order to validate play.
IOW, I need the ID for every sprite in the stack as well as those in adjacent board positions to validate movement.

Only one stack of sprites is in motion at any time, controlled by the pointer. Pieces may be rotated before play. When successfully played, an entire stack remains on the board and the player picks up another stack. Moving a stack from one board position to another invokes move validation, which requires:
* Identifying adjacent board positions;
* Identifying all of the sprites in previously played stacks in those adjacent positions;
* Determining whether the move is valid based on the contents of all of the sprite stacks involved;
* Applying many of the same sprite modifications listed above to effected sprite stacks played previously in adjacent board positions;
* And then removing all those modifications every time the stack is moved.
IOW, I need the ID for every sprite in adjacent board positions, including the board itself, to validate movement.

Successfully playing a stack tallies the score for a move, which requires:
* Checking the stacks and board positions of many other previously played stacks in non-adjacent board positions because of a cascading effect (of sorts) highlighting all of the stacks used to calculate the score;
* Changing the depths of the three sprites used to create the playing piece, to move the most relevant sprite to the top of its stack;
* Making many of the same sprite stack changes listed above to any effected sprite stacks;
* And then removing all of these changes when the player selects a new sprite stack to play.

So although only one stack is in motion at any time, changes occur all over the board whenever the player moves or places a stack. Moving or changing the depths of sprites in order to get the IDs of underlying sprites is a major effort when the stacks are constantly changing. And building an array to avoid moving sprites seems almost as cumbersome. As you can see, the process is complex and highly repetitive.

I doubt there's an elegant solution.
JosephB
17
Years of Service
User Offline
Joined: 12th Sep 2006
Location:
Posted: 14th Feb 2020 22:38
Thanks for the detailed information. I am not aware of any AppGameKit commands that would provide the IDs of stacked sprites. As you mentioned and hendron suggested, arrays should help track what is happening each move. If you are not already doing so, I believe it could be helpful to use a type for your game pieces and then make that type an array, possibly an array for the piece number, sprite ID and the sprite depth. You might be able to eliminate the sprite board position from the stack if you are able to develop a grid array for your board positions, something akin to a breakout game grid design based on columns and rows and the pixel size of the grid segment. This would hopefully prevent having to move or change the depth of sprites in stacks to identify all sprites in the stack.

Example code for type and array:
Ron2019
4
Years of Service
User Offline
Joined: 27th Jul 2019
Location:
Posted: 15th Feb 2020 17:04 Edited at: 15th Feb 2020 17:19
Thanks for your suggestion! I'm already using a typed array to store the board to piece relationships and the challenge is identifying the array position using the pointer's screen location because I need to search the array for either piece or board ID, which I can only determine with GetSpriteHit. Adding sprite bounds in the array would simplify things considerably if the pieces weren't hexagonal.

I'd explore Tier 2 but don't want to rewrite the whole thing in C. It sounds like the best approach for now is shuffling sprites around.

Thanks again for listening!
hendron
8
Years of Service
User Offline
Joined: 20th Dec 2015
Location:
Posted: 15th Feb 2020 17:24
This post has been marked by the post author as the answer.
Quote: "If nobody has already created something akin to GetAllSpritesHit, perhaps I can?"


If you're wanting a function that is the same as GetSpriteHit(), but returns all of the sprites that are hit at the given coordinate instead of only the top-most, that's exactly what the function I provided in my previous post does. It takes a coordinate and returns an array of all of the sprites hit at that coordinate. Apologies if I'm misunderstanding and this isn't what you're after.

Here's a quick demo snippet using the function.

janbo
15
Years of Service
User Offline
Joined: 10th Nov 2008
Location: Germany
Posted: 16th Feb 2020 16:15
If you have many sprites, a collision system using QuadTrees should be predestined for those kind of tasks as it wouldn't need to iterate through all sprites but only down a few knots of the Tree.
Not sure how AppGameKit did the hit test or if it is overpowered and maybe even have a bigger overhead for your task than actally run through all your sprites, just one option.

QuadTree Code I had lying around.
blink0k
Moderator
11
Years of Service
User Offline
Joined: 22nd Feb 2013
Location: the land of oz
Posted: 16th Feb 2020 18:46
Would 2dPhysics help?
It has functions like GetFirstContact()/GetNextContact()
Ron2019
4
Years of Service
User Offline
Joined: 27th Jul 2019
Location:
Posted: 16th Feb 2020 18:53
Thanks, Hendron! Temporarily re-positioning sprites as they are hit certainly avoids the issue with changing sprite depths and iterating through an array is ideal for my processing.

Thanks for responding, Janbo, but Hendron's solution uses the physics engine to determine hits against non-rectangular sprites, which is closer to what I need and I think somewhat easier to implement with my existing code. But thank you very much for your suggestion!
Ron2019
4
Years of Service
User Offline
Joined: 27th Jul 2019
Location:
Posted: 16th Feb 2020 19:32 Edited at: 16th Feb 2020 19:40
blinkOk: I've been unable to find a working example using GetFirstContact or GetNextContact in the Help pages. I do note, though, that the Description for GetNextContact says "Returns 1 if a contact exists, you can get the sprites involved in this contact using GetContactSpriteID1 and GetContactSpriteID2..." which suggests these commands only capture collisions between sprites, not an overlap between sprites and the pointer?

To be sure, I've tried creating a test but GetFirstContact returns 0 when the mouse is hovered over or clicked on any sprite in the scene. Can you provide or point me to a working example that captures a list of hexes under the pointer?

Thanks for your response!
Virtual Nomad
Moderator
18
Years of Service
Recently Online
Joined: 14th Dec 2005
Location: SF Bay Area, USA
Posted: 16th Feb 2020 20:19
is collision necessary?

IE, put the sprites into a stack (typed array?), then place the stack into the grid (another typed array?), record it all & retrieve the sprite IDs when you need them?

IE, determine which hex you're in:
https://www.redblobgames.com/grids/hexagons/#pixel-to-hex

pull the stack(s?) that lay in the space from the grid array, and do what you need to with the sprites in the stack.

if you need to be able to determine which sprite in the stack was clicked specifically, at least you'd have much fewer hits to detect (that's assuming there is no uniform alignment of the sprites that you could otherwise use math to determine which sprite in the stack is selected).

if you wanted to use collision to determine which hex you're hovering over, you could do similar. give each hex a background sprite that you could use as a reference to look up stacks, then sprites, etc.

hope that makes sense.

but, it sounds like you need some "real" sprite/data handling so i would take a "divide and conquer" approach and make sure everything is well organized so you can reference what you need (vs any notion of mass collision checks).
Bengismo
6
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 17th Feb 2020 13:22 Edited at: 17th Feb 2020 13:24
You could use the sprites group functionality that is built in...



In the example above it gets a list of sprites under the cursor and they are ordered by depth.

The GetSpriteHitGroup() command can be used to get only certain sprites under the mouse position depending on what group you want.

You can also use the category bits too and GetSpriteHitCategory().
Ron2019
4
Years of Service
User Offline
Joined: 27th Jul 2019
Location:
Posted: 17th Feb 2020 16:53
Thanks for all of the responses! I have marked Hendron's response as the one I am adopting, as it seems to simplest to implement. I have also entered a request for such a function in GitHub.

Thanks, again, everybody!
smerf
19
Years of Service
User Offline
Joined: 24th Feb 2005
Location: nm usa
Posted: 18th Feb 2020 00:49
hmm i woulda just done a for loop
spr as integer[100]
startrange= whatever num to starton
x=getrawmousex():y=getrawmousey()

for i=1 to max
spritehit=getspritehit(x,y)
if spritehit=>startrange
spr[i]=spritehit
hidesprite spritehit
inc max,1
endif
next
if background image returned or hiy=0 end is reached then show all the sprites peviously hidden.
can sort a thousand sprites deep no problem

hendron
8
Years of Service
User Offline
Joined: 20th Dec 2015
Location:
Posted: 18th Feb 2020 01:56 Edited at: 18th Feb 2020 01:56
GetSpriteHit() still detects sprites when they're hidden (and even when they're deactivated, which is odd)
smerf
19
Years of Service
User Offline
Joined: 24th Feb 2005
Location: nm usa
Posted: 18th Feb 2020 04:59
yes very odd id imagine something hidden would be excluded from all checks except existence and property requests. could always move the sprite left or right a few pixes then move back when done it would all happen before a refresh so not visible to a user.

Login to post a reply

Server time is: 2024-04-18 17:29:45
Your offset time is: 2024-04-18 17:29:45