I don’t think you need the “pick all solid” action. That’s really for simultaneously changing all objects of a type e.g. deleting them all, whereas you are working through them one-by-one with a for loop.
Rather than constantly calculating distances between objects, a completely different approach is to use a tiny invisible object positioned just in front of the enemy object that acts like a cat’s whiskers to detect a solid object just before the enemy object hits it. If you create a new point on your enemy object’s sprite that is on its far right (and not in the hitbox), then you can place the invisible object at that point.
If you call the point “check” and the object ‘checker’, you’d have an event like:
No conditions | Do = enemy.PointX(check); enemy.PointY(check) to position of checker
And then one to detect if the checker object has collided with anything in the Solid group:
checker is in collision with Solid | Stop the object enemy
In this case it just stops the enemy moving forwards, but you could make it rotate, reverse, or whatever else.
This is fine for one enemy only, but if you have many enemy object instances then each checker object instance will need to be linked to the correct enemy instance. You can do this at the start of the scene, using the “Link” action and then in the main game cycle you would need the “Take into account” condition.
Something like this might be the end result:
Take into account all "enemy" linked to checker | Do = enemy.PointX(check); enemy.PointY(check) to position of checker
I’m not sure if those will definitely work as I’ve had difficulty dealing with linked objects when I’ve tried in the past.
The other way of linking things is with object variables. You’d give your enemy object and your checker object a variable called “ID” and then give one enemy instance and one checker instance the same number, before increasing the number and giving it to two more instances - and so on. This could also be done in a for loop, or you could do it manually to each instance placed on the scene.
Then you’d need to check for matching ID numbers in a for loop.
checker.Variable(ID) = enemy.Variable(ID) | Do = enemy.PointX(check); enemy.PointY(check) to position of checker
It gets trickier when doing the collision check as although it will automatically select the colliding checker, the action needs to be communicated to the right enemy instance.
checker is in collision with Solid | Stop the object enemy
Variable ID of enemy = checker.Variable(ID) |
And this may go wrong if two enemy instances collide head-on!