As indicated in the section Addressing Variables in Other
Instances, it is possible to read and change the value of
variables in other instances. But in a number of cases you want to
do a lot more than just change a single variable with those other
instances. For example, imagine that you want to move all the ball
objects in your game 8 pixels. You may think that this is achieved
simply by the following piece of code:
obj_ball.y = obj_ball.y + 8;
But this is not correct, as the right side of the assignment gets
the value of the y-coordinate of the first ball and adds 8 to it.
Next this new value is set as y-coordinate of all balls, so the
result is that all balls get the same y-coordinate, and even if you
use the following:
obj_ball.y += 8;
it will have exactly the same effect because it is simply an
abbreviation of the first statement. So how do we achieve
this? For this purpose there exists the with statement in
GML. Its global form is:
with (<expression>) <statement>
<Expression> indicates one or more instances, and for this
you can use an instance id, the name of an object (which indicates
all instances of this object are to run the code block) or
one of the special keywords (all, self,
other). <Statement> is now executed for each of the
indicated instances, as if that instance is the current (self)
instance. So, to move all instances of the ball object 8 pixels
down, you can type:
with (obj_ball) y += 8;
If you want to execute multiple statements, put curly brackets
around them, the same as you would around any other program. So for
example, to move all balls to a random position, you can use:
with (obj_ball)
{
x = random(room_width);
y = random(room_height);
}
Note that, within the statement(s), the indicated instance has
become the target (self) instance that runs the code block, which
means that the statements the original instance (that contains the
"with" and the code block) has become the other instance. So
for example, to move all balls to the position of the current
instance, you can type this:
with (obj_ball) { x = other.x; y = other.y; }
The with statement is an extremely powerful tool and is useful in
many, many circumstances so it is important that you understand
fully how it can be used. To help there are a few more examples of
use below:
with (instance_create(x, y, obj_Ball))
{
speed = other.speed;
direction = other.direction;
}
The above code will create an instance of obj_Ball and assign it
the speed and direction of the instance that runs the whole code
block.
with (instance_nearest(x, y, obj_Ball))
{
instance_destroy();
}
The above code will destroy the instance of obj_Ball nearest to the
instance running the code.
var inst;
inst = noone;
with (obj_ball)
{
if str > other.str inst = id;
}
if inst != noone target = inst;
The above code is slightly more complex than previous ones due to
it using a local variable. This variable is local to the
script and not to the instance and so can be used and
accessed by all instances that are referenced within the code
block. So, in the code we have set it to the special keyword
noone and then use the "with" construction to have every
instance of obj_Ball check their "str" variable against that of the
instance running the code block. If the value of the variable is
larger, then they store their unique id in the "inst" local
variable, meaning that at the end of the code, only the instance
with a value greater than the calling instance (or the
keyword noone if none are larger) will be stored in
the local variable inst. For more information on local variables
see the section Variables And
variable Scope.