Creating each object from a group in a random location

So I have 3 objects (red, green and blue) in a group (Group) and I’d like to add them all to the scene in random locations. I’ve attached my example, but it’s not working… Suggestions?

I’ve seen other tips that mention naming the objects with numbers and then iterating through them (creating object by name), but I’d rather not change the names of my objects if possible.
My project.zip (2.58 KB)

If you don’t want to change the object name, the only thing I can suggest is to store the object names inside a structure variable where each structure name is a number.

color.1 = "red" color.2 = "green" color.3 = "blue"

And then with a Repeat event, create the objects from their names

[code]counter = 1

Repeat 3 times
Create object from name VariableString(color[ToString(Variable(counter))]) at position random X random Y
Do + 1 to counter[/code]

Here is the solution:
solution.zip (3.03 KB)

1 Like

This is such a huge coincidence, I came to the forums today for a solution to a similar problem, only problem that made me do this the rest I could figure out, but this one is really frustrating me, I’m reading ddabrahim’s solution but there’s something else I want to try

How does one utilize the “Pick a random object” and “Pick all objects” options, all it allows you to do is select these options for both conditions and actions, but nothing in the program or anything online hints on how to utilize this function. I thought it would be straight forward, so far the program has been, but this problem is angering me at this point :smiley:

Here’s what I want to do, lets say I have multiple objects in a group, each object has a set of object variables.

Lets say the 2 variables (Length and Width) and they are all different sized 2d objects (and for some reason instead of using in program functions to derive the length and width I manually store them as object variables per object in a group)

I want to set a condition to filter through a group of objects and only create an object which object variables match specific criteria

Lets say values are Length = 300 and Width = 500 are the conditions

I want to simply select and create objects, utilizing object variables as filters

I even tried using the “For each object” event type and it did nothing, its like the software cannot identify object variables within a group, or even the groups themselves maybe (I know I have to be missing something here)

I’ve added an attachment with an example of the attempts made, really hope you or someone else can help out with this problem and I won’t have to take a convoluted solution like the one listed here: i.imgur.com/61XyXdH.png

That would require basically renaming around 100+ objects to establish a naming convention utilizing numbers and then creating 10’s of groups and subgroups to house the various categories, just so I can use the ToString() and Random() functions to create objects.

That’s the only solution I can think of so far, rather than the objects having variables, I’d abstractly create those variables using groups and use the naming convention to filter through them. That would be disheartening and ridiculous for a software that I thought was the best thing I’ve come across in a while, I have to be missing something and its something obvious, how can a “Pick a random Object” function not just allow you to create objects from based on said random selections? (I’m losing my mind, what am I missing!)
Example.zip (3.45 KB)

You are not missing anything, but misunderstanding one thing: The conditions/actions to pick all the objects or a random object work on instances already created (i.e. living in the scene), they don’t work on the object templates.

If you can’t rename to follow an easy convention you can do two things, at least I can think on two things right now:

1 - Use structures as ddabrahim does above, in your case the structure would look like:

Shapes 300 500 Shape_ABC 500 500 Shape_XYZ
You can order and nest them as you want, for example here there could be a single “500” child representing the Width with two childs 300 and 500 representing the Length. Continue the example you can create the object using the action to create by name, and using this name to get the first shape object:

VariableString(Shapes["300"]["500"])

2 - Create one instance of every object, and delete all the new instances that don’t fulfill the conditions, finally work with the surviving instance:


All the conditions/actions you were using will work here too, as the instances already exist. For example, you can get a random one flagging a random instance to survive and deleting all the others:
GetRandomObject.png
Note that this solution is not suited for fast/action games, creating 100 objects every frame to delete 99 of them, 60 times per second, is not cool. This one works better for puzzles :wink:

Hope that help :slight_smile:

I’ll try the structure one but I think I may end up doing the renaming thing, because as convoluted as it is, once I get everything in place it will be a lot simpler to manage and find errors that the other solutions, a structure to house multiple variables just seems like it would be complicated, i’d also have to create a structure for every single object by the looks of it, its much simpler to just rename them and just use ToString to select the object like in the link I posted.

Actually while typing this out I think I just thought of a funny convoluted way that doesn’t involve me renaming anything, I create a bunch of text variables which names are just integer numbers, and I set these text variables to be the names of the objects. Then I use the Random() function to refer to the text objects when selecting the name of the object to create as seen in the method of this image - i.imgur.com/61XyXdH.png

So instead of “Enemy” + ToString(Random(3)) it will be

ToString(Variable(Random(N)))

Would that work, it sure looks like it would

But that solves the creation problem, not the filter problem, can I only refer to the instance variables of an object that is “alive” (present on screen)?

If so that means I’m going to have to create a good bit of sub groups for these text variables :smiley:

I’m really surprised though that the “pick random object” function can’t be used like one would expect it to be at face value of its description, kinda ruined my day lol.

@Lizard-13

Yeah I did a small test and my method works in theory but not in practice

Condition: At the beginning of the scene

Action: Do = “Shape_ABC” to text of global variable 0
Do = “Shape_XYZ” to text of global variable 1

Direct Test Works (no randomization):
Action: Among objects Shapes, create object named GlobalVariableString(1) at position 0;0

However when I attempt to implement the randomization effect (to imitate selecting from a group) I can’t get it to work, which is weird, it seemed obvious to me that this code would work

Action: Among objects Shapes, create object named GlobalVariableString(Random(1)) at position 0;0

After that I assumed that the error might be that it recognizes the number generated by the Random() function as a “number type” so it isn’t accepted as a variable name, so I do this

Action: Among objects Shapes, create object named GlobalVariableString(ToString(Random(1))) at position 0;0

So now its converted the random number generated into a string, which is now in the brackets to be referred to as a variable name, but it doesn’t work like when I simply put GlobalVariableString(0) or GlobalVariableString(1)

Why is that?, is there a limit to “nested functions”, is there some kind of error I’m not seeing, the logic makes sense, I’m so confused.

Do you have a work around or a correction on what I did wrong?

You can’t access a variable dynamically (using an expression as name) unless it’s a child variable, do this instead:

Conditions: At the beginning of the scene Actions: Do = "Shape_ABC" to text of global variable shapes.0 Do = "Shape_XYZ" to text of global variable shapes.1
And then:

Among objects Shapes, create object named GlobalVariableString(shapes[ToString(Random(N))]) at position 0;0

In short, when you access a variable, if you don’t see a [] you can’t use expressions :slight_smile:

Btw what you’ve made here (a structure mapping integer > object name) is the simplest way to get a random object if there is not a simple pattern in the objects names. But it doesn’t work to filter the object by other properties (variables for example) :wink:

Yeah I kinda expected I would not be able to filter since instance variables are only accessible on active objects that are on the screen, so I planned on creating groups of these text variables and based on a condition the text values the numeral variables hold would can change by accessing said group (so I can reuse numbers instead of going all the way up to 100+ to contain all object names separately, also if I did that I’d have to use custom ranges on the Random() function to simulate the grouping, would get complicated quick)

This page confirms exactly what you’re saying, I’d never have thought to look into it without your info though
wiki.compilgames.net/doku.php/gd … renotation

Lol so are structures just the Gods of the coding realm, it always comes back to structures you can’t escape their reach, thanks for everything, i’ll give it a try

How did you build your core programming knowledge?, I’m obviously missing even fundamentals that would allow me to recognize such mistakes

At this point I might as well just use structures like I was hoping to avoid if I’m going to have to use structures anyways, might as well just go all in.

Ok, so once I understood this then I decided the simplest solution would be to simply add all objects to the scene, then move them all to a random location. That works nicely as seen in my updated example.

Thanks for the tip @ddabrahim, but I didn’t want to have to create additional variables either.
My project.zip (2.69 KB)

I was going to do that too but based on the kind of game and size (amount of objects) that could create performance issues, also once you utilize an object on the screen, and you delete it, its no longer there, so you’d have to have code that recreates a deleted object at the position you placed it originally for use every-time you delete an object (assuming you have to delete anything).

Here’s something I want to ask viper though, can the Timer function of gdevelop only be used for counting up, it only allows you to test for values “greater than” a specified number of seconds, but now you can’t test for a range, so that means its better to use the TimeDelta() function right? (since you can manipulate it as you please)