• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GameMaker Text is deleted after new object

J

JND_3004

Guest
Hi Guys,

I have three test objects each with a draw event.
If one of the objects is set, the text is also set, but the text of object 1 is deleted as soon as object 2 is placed.
What is my mistake?

Code:
draw_self();
draw_set_font(fnt_CourierNew_Bold);
// floor name
draw_text(global.lastFloorNameX, global.lastFloorNameY, string(global.lastFloorName));
// elevator floor number
draw_text(global.lastFloorElevatorNumberX, global.lastFloorElevatorNumberY, string(global.lastFloorNumber));


 

nesrocks

Member
Because you create instances in the step event but they are drawn later, in the draw event (all step events happen, then all draw events happen). So you can't use "lastname" for all of them. Aren't the names constants? Set the name when you create the instance and then the instance will draw its own name.

You can get the id of the instance when you create it so you can set its name right after.
Code:
var myinstance = instance_create(etc);
myinstance.name = "floor 1";
 
J

JND_3004

Guest
The floors are created by chance. Since I thought that I always "Save" the last floor as global.last and then use this for the Draw Event.
Thought that the text persists and I can simply save the next floor so global.last and can be output as text again without always the last draw is deleted.

When creating floors, only two scripts are executed and for creating the text there is the draw event in the floor object.

Therefore, I personally would not know how I could solve it best.
 

Relic

Member
If you are updating what global.lastfloor is when a new instance is created, this will be the new variable for all drawn text. Global variables by their nature are accessible to every instance. You first instance won’t keep the “old” value, it will show the new value too.

So every instance you create will be using the same global.x, global.y and global.floornumber things you have. They are all drawing to the same position and have the same text - thus you can’t see any difference between them.

Because you want each instance to have it own unique text and position to draw, do as @nesrocks suggests and assign variable to the instance (not globally).
 
J

JND_3004

Guest
Because you create instances in the step event but they are drawn later, in the draw event (all step events happen, then all draw events happen). So you can't use "lastname" for all of them. Aren't the names constants? Set the name when you create the instance and then the instance will draw its own name.

You can get the id of the instance when you create it so you can set its name right after.
Code:
var myinstance = instance_create(etc);
myinstance.name = "floor 1";
The creation of a new floor is completely via a script.
If I set the new instance there as a variable, I can not use it again in my object of the corresponding floor.

Why does GM have to build something so simple, so complicated? ..

You click with the mouse on a certain object. By clicking the first script "script_getRandomFloor" is triggered, which selects a random floor from the predefined list. If this one has found a floor that does not yet exist, the second script "script_createFloor" is triggered.
This script then creates, for example, the previous, random, selected floor.
The newly created floor object contains the draw event with the global.last content in order to be able to create the necessary texts.

I hope I could now describe the whole thing in more detail how it happens in about.
Therefore, I personally have no solution to my problem, because GameMaker has to do everything so cumbersome.
 

chamaeleon

Member
Why does GM have to build something so simple, so complicated? ..
Therefore, I personally have no solution to my problem, because GameMaker has to do everything so cumbersome.
Take some time to understand the event model and the difference between global, instance, and local variables, and things won't look so bleak. If things worked as you want them to work using your shown code, pray tell us, which global variable would you change if you wanted to change the floor name or position one of floors (not saying it makes sense in your case, but for argument's sake)?
 

nesrocks

Member
If I set the new instance there as a variable, I can not use it again in my object of the corresponding floor.
When you do what I described you're not setting it as a variable, you're merely catching its reference so you can access it amidst all other instances of the same objects that currently exist.

The logic you're trying to apply is flawed independently of how GM works. You're using a single variable (global.last) for several different things. Which can work provided you understand the flow of events. But you perhaps did not throughly read what I mentioned earlier.

Events happen in a certain order. It is not per object. First all "create" events happen. Then all "step". Then all "draw". So if every object sets the "global.last" variable in their step or create events, then by the time the draw events happen they will all see the global.last as having the same value, provided they do not change it themselves. It really is super simple, whenever you're setting global.last don't do it. Set myinstance.last instead. Then on the object's draw event instead of using "global.last" simply use "last".
 
Last edited:

FrostyCat

Redemption Seeker
Your problem is using global scope for individual properties. If you used instance scope the way it's meant to be used, none of this is complicated.
  • Global scope is for one-of-a-kind properties that everything shares one common copy of.
  • Instance scope is for individualized properties that each instance of the given object has their own copy of.
If you want each floor to have its own floor label, the rules above dictate that you should use instance scope, not global scope. The outcome of your abuse of global scope is one instance overwriting the properties of another.

This is what your floor object should look like:

Create:
Code:
floorName = "";
floorNumber = 0;

// Adjust the following as needed
floorNameX = x+32;
floorNameY = y+32;
floorNumberX = x+32;
floorNumberY = y+64;
Draw:
Code:
draw_self();
draw_set_font(fnt_CourierNew_Bold);
// floor name
draw_text(floorNameX, floorNameY, floorName);
// elevator floor number
draw_text(floorNumberX, floorNumberY, string(floorNumber));
Then when you create the instance of the floor object in code:
Code:
with (instance_create_layer(30, 300, "Instances", obj_floor)) {
  floorName = "Ground Floor";
  floorNumber = 1;
}
Or if you're using the room editor, double-click the instance and change its Creation Code (see this screenshot):
Code:
floorName = "Ground Floor";
floorNumber = 1;
 
Last edited:
Top