Loop over each object, but in a particular order

I have a bunch of blocks placed randomly on my scene. I want to loop through and delete them all (with a timer, so you can see them disappear one-by-one). But I want to start in the bottom-right and work my way to the top-left of the scene. What’s the best way to do this?

I thought about adding each block to a structure variable and including its X and Y position, then sorting the structure by Y then by X, but there’s no way to do this currently that I know of, so I’d have to write my own algorithm (in JS most likely, which I’m not too familiar with).

Then I thought about just using nested ‘while’ loops (since my blocks are placed in a 64x64 grid) and looping over each X and Y value that are multiples of 64. I’d check if there’s a block at that position and, if so, delete it (decrementing X and Y with each iteration).

I’ll probably use the ‘while’ loop idea if nothing better presents itself. But interested to hear if there’s a better way…

I would probably recommend using some combination of an Inverted Raycast condition and an Inverted Pick nearest condition, having their “start point” being the upper left of the screen.

Inverted Raycasts will pick the furthest instance of an object within the distance you select. Inverted pick nearest will pick the furthest object regardless of distance.

You’ll need to evaluate your logic to ensure it’s picking in the order you want, but that’d likely be the best place to start.

I’d be tempted to use the raycast too, but starting at the middle of the bottom right poisiton, casting it up at a 45 degree angle towards the right (-45 degrees in GDevelop world), and delete the first block it hits. When there are no more blocks hit by the raycast, move it’s starting point left by 64 pixels.

So effectively it’s a 45 degree line sweep from right to left.

1 Like

I’ve not used raycast before, so I’ll have to play with it. But if it works the way I imagine, I think I’ll try setting it to start on the right side of the screen on the bottom grid row and direct it horizontally to the left. Then it’ll find all blocks on the bottom row starting on the right. Once that’s done I’ll move it up 64 pixels to repeat with the grid row just above that, then repeat going up the screen.

Thanks for the suggestions!

If you’re add some type of ID to the blocks you could use that to determine which one is next on the chopping block.

Example:

  1. Set a variable as the first block ID (eg: 1)
  2. Loop through all blocks on the scene, if their ID matches the variable, remove the block and increase the variable by one.
  3. Keep looping through until there are no blocks left on the scene.

Not sure how much better/worse the performance of something like the above would be vs raycasting.

1 Like

The raycasting idea worked, thanks! Here’re my events for those interested:

Now I have a slightly different problem…

I now want to do a similar thing with my Squibbles objects (go through each one; bottom row to top, and right side to left). But this time, instead of deleting them as I go, I just want to change their state. This will mean that some will move down, but some will stay in-place.

As a result, I don’t think raycasting will work here as it’ll always stop at the first Squibble it encounters, right? There’s no way to make it skip an object and find the next…? I know you can invert the raycast, but that’ll still only find the one on the other side of the row, not in the middle…

For example:

The raycast is represented by the red arrow. The two Squibbles sitting on the dirt blocks won’t move. But the two highlighted by the blue box need to fall down (one at a time). Unless I’m missing something, raycasting won’t work here as it’ll hit and return the Squibble on the right. Then my other conditions will ignore it since it’s sitting on a block. But then the raycast isn’t going to return the next Squibble along (in the blue box), is it?

I considered changing the raycast from starting on the right and pointing left, to starting at the bottom and pointing up (with a maximum distance set to the current row), then moving it left after each step. But that still doesn’t work as my Squibbles are in a grid, so there will be ones that need to move sitting higher than ones that don’t move. So same problem, just in a different dimension.

So how would I go about looping over each Squibble in a set order (right-to-left, bottom-to-top), without raycasting?

You could still raycast, starting the first raycast from the bottom right. But fire the next raycast from the left side of the last squibble the raycast had hit. Once no more squibbles are hit for a row, start again from the right, and the next row up.

1 Like

Genius! I’ll give it a try.