More about objects
When you create an object in advanced mode, you can change some
more advanced settings.
Depth
First of all, you can set the Depth of the instances of the
object. When the instances are drawn on the screen they are drawn
in order of depth. Instances with the largest depth are drawn
first. Instances with the smallest depth are drawn last. When
instances have the same depth, they are drawn in the order in which
they were created. If you want to guarantee that an object lies in
front of the others give it a negative depth. If you want to make
sure it lies below other instances, give it a large positive depth.
You can also change the depth of an instance during the game using
the variable called depth.
Persistent objects
Secondly, you can make an object persistent. A persistent object
will continue existing when you move from one room to the next. It
only disappears when you explicitly destroy it. So you only need to
put an instance of the object in the first room and then it will
remain available in all rooms. This is great when you have a main
character that moves from room to room. Using persistent objects is
a powerful mechanism but also one that easily leads to errors.
Parents
Every object can have a parent object. When an object has a parent,
it inherits the behavior of the parent. Stated differently, the
object is a sort of special case of the parent object. For example,
if you have 4 different balls, named ball1, ball2, ball3 and ball4,
which all behave the same but have a different sprite, you can make
ball1 the parent of the other three. Now you only need to specify
events for ball1. The others will inherit the events and behave
exactly the same way. Also, when you apply actions to instances of
the parent object they will also be applied to the children. So,
for example, if you destroy all ball1 instances the ball2, ball3,
and ball4 instances will also be destroyed. This saves a lot of
work.
Often, objects should behave almost identically but there will
be some small differences. For example, one monster might move up
and down and the other left and right. For the rest they have
exactly the same behavior. In this case almost all events should
have the same actions but one or two might be different. Again we
can make one object the parent of the other. But in this case we
also define certain events for the child object. These events
"override" the parent events. So whenever an event for the child
object contains actions, these are executed instead of the event of
the parent. If you also want to execute the parent event you can
call the so-called "inherited" event using the appropriate
action.
It is actually good practice in such cases to create one base
object. This base object contains all the default behavior but is
never used in the game. All actual objects have this base object as
parent. Parent objects can again have parents, and so on.
(Obviously you are not allowed to create cycles.) In this way you
can create an object hierarchy. This is extremely useful to keep
your game structured and you are strongly advised to learn to use
this mechanism.
There is also a second use of the parent object. It also
inherits the collision behavior for other objects. Let us explain
this with an example. Assume you have four different floor objects.
When a ball hits the floor it must change direction. This has to be
specified in the collision event of the ball with the floor.
Because there are four different floors we need to put the code on
four different collision events of the ball. But when you make one
base floor object and make this one the parent of the four actual
floor objects, you only need to specify the collision event with
this base floor. The other collisions will perform the same event.
Again, this saves a lot of copying.
As indicated, wherever you use an object, this also implies the
descendants. This happens when, in an action, you indicate that the
action must be applied to instances of a certain object. It also
happens when you use the with() statement in code (see
below). And it works when you call functions like
instance_position, instance_number, etc. Finally,
it works when you refer to variables in other objects. In the
example above when you set ball1.speed to 10 this also
applies to ball2, ball3 and ball4.
Masks
When two instances collide a collision event occurs. To decide
whether two instances intersect, the sprites are used. This is fine
in most cases, but sometimes you want to base collisions on a
different shape. For example, if you make an isometric game,
objects typically have a height (to give them a 3D view). But for
collisions you only want to use the ground part of the sprite. This
can be achieved by creating a separate sprite that is used as
collision mask for the object.
Information
The button Show Information gives an overview of all
information for the object that can also be printed. This is
particularly useful when you loose overview of all your actions and
events.