• 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!

Legacy GM Constructor for objects

M

Makai Post

Guest
Is there a way to use constructors for objects? I need to have each instance of the same object have different values. I need to be able to put these variables in before it is created so that other variables below it can use them as the object is being created.
instance_create(16, 25, objEnemy(125, c_red, true))​
-->
///objEnemy(max_health, body_color, can_run)
max_health = argument0
health = max_health
body_color = argument1
can_run = argument2

if (can_run) {
//do stuff...​
}​
right now the only way I can think to do it is create the instance, change the values, and have it do an alarm that then adds the rest of the values, but that is really messy.
 
J

Jaqueta

Guest
The instance_create function returns the Object ID, you can store this value into a var and use it to change the vars, for instance:

Code:
vEnemy=instance_create(x,y,objEnemy)

with(vEnemy)
{
max_health=125
health=max_health
body_color=c_red
can_run=true
}
Alternatively, you can also do this, but I'm afraid it's slower (not sure, if someone could confirm this, I appreciate)
Code:
vEnemy=instance_create(x,y,objEnemy)
vEnemy.max_health=125
vEnemy.health=max_health
vEnemy.body_color=c_red
vEnemy.can_run=true
 
M

Makai Post

Guest
The instance_create function returns the Object ID, you can store this value into a var and use it to change the vars, for instance:

Code:
vEnemy=instance_create(x,y,objEnemy)

with(vEnemy)
{
max_health=123
health=max_health
body_color=c_red
can_run=true
}
I think this would run the create instance first then change the values. I need to set the values before creating the instance. Is that possible?
 
J

Jaqueta

Guest
Unfortunately, I'm afraid not. Alarms are the easiest solution really.

MAYBE, you could put the code inside an Script, and execute the script from the with to make is "Less messy"?
 
L

L0v3

Guest
You would create the object, send over the variables, then run an user_defined event for a custom create event afterwards instead of the create event. 1 step alarm is another approach but this delays everything and can cause inconsistencies and blinking effects depending on circumstances. Here's a random example:

Code:
//Creats variables.
var new_room = argument0;
var steps = argument1;
var spd = 1 / steps;
var colour = argument2;

//Creates fade object.
var obj = instance_create(x, y, eng_room_cfade);

//Sends over variables.
with obj
{
    self.new_room = new_room;
    self.colour = colour;
    self.spd = spd;
}

//Runs custom create event.
event_user_ext(obj, 0);
 
M

Makai Post

Guest
Unfortunately, I'm afraid not. Alarms are the easiest solution really.

MAYBE, you could put the code inside an Script, and execute the script from the with to make is "Less messy"?
That's not a bad idea. Not the ideal method but it might be better than the alarm method. I will try it out. Thanks.
 
M

Makai Post

Guest
The instance_create function returns the Object ID, you can store this value into a var and use it to change the vars, for instance:

Code:
vEnemy=instance_create(x,y,objEnemy)

with(vEnemy)
{
max_health=125
health=max_health
body_color=c_red
can_run=true
}
Alternatively, you can also do this, but I'm afraid it's slower (not sure, if someone could confirm this, I appreciate)
Code:
vEnemy=instance_create(x,y,objEnemy)
vEnemy.max_health=125
vEnemy.health=max_health
vEnemy.body_color=c_red
vEnemy.can_run=true
The instance_create function creates the instance THEN returns the ID. I need to change the variables before the instance is created. In other object oriented programming languages, there is always a ways to add arguments to the object before it is created. (e.g. Car myCar = new Car("red", 2007, "FORD");)
 
For issues like this, I always create a constructor script and leave the "create event" empty. They look something like this:4

Code:
/// enemy_create(x, y, max_hp, move_speed, sprite_index) = enemy_id;

var x1 = argument[0],
    y1 = argument[1],
    mhp = argument[2],
    mvsp = argument[3],
    spr = argument[4];

var enemy_id = instance_create(x1, y1, obj_enemy);

with (enemy_id)
{
    max_hp = mhp;
    move_sp = mvsp;
    sprite_index = spr;

    enemy_init(); // Simulates the Create Event
}

return (enemy_id);
 
A

Annoyed Grunt

Guest
The instance_create function creates the instance THEN returns the ID. I need to change the variables before the instance is created. In other object oriented programming languages, there is always a ways to add arguments to the object before it is created. (e.g. Car myCar = new Car("red", 2007, "FORD");)
What difference does it make, practically?
 
J

Jaqueta

Guest
What difference does it make, practically?
Basically, it's for when you need to use a code into the Create event, and this code uses a previously defined variable.

For instance:
Code:
team=0

switch(team)
{
case 0:
enemy_color=c_red
break

case 1:
enemy_color=c_blue
break
}
However, if you need to create an instance and set the TEAM on the instance creation. The code won't be executed properly.
 
S

seanm

Guest
As I have just recently learned:

When you call
Code:
With instance_create
{
    x=100
}
x will be set to 100 at the end of that objects create event.

Which means if you need to access those variables before the step event, you have to call a user event

Create event
Code:
x=5
event_user(0)
so what will happen if you create the object using (with instance_create) is:

- create event starts -
  • x=5
  • tell GM to run event_user after the create event
  • x=100
-create event ends -
  • event_user starts
 

FrostyCat

Redemption Seeker
As I have just recently learned:

When you call
Code:
With instance_create
{
    x=100
}
x will be set to 100 at the end of that objects create event.

Which means if you need to access those variables before the step event, you have to call a user event

Create event
Code:
x=5
event_user(0)
so what will happen if you create the object using (with instance_create) is:

- create event starts -
  • x=5
  • tell GM to run event_user after the create event
  • x=100
-create event ends -
  • event_user starts
Are you absolutely sure about that? As far as I'm concerned, event_user() is instantaneous, so your execution flow would be more like this:
  • Create event starts
  • x = 5
  • Run user event 0
  • x = 100
  • Create event ends without doing anything else afterwards
If I'm right about this, you would need more rigorous handling.
 
S

seanm

Guest
Are you absolutely sure about that? As far as I'm concerned, event_user() is instantaneous, so your execution flow would be more like this:
  • Create event starts
  • x = 5
  • Run user event 0
  • x = 100
  • Create event ends without doing anything else afterwards
If I'm right about this, you would need more rigorous handling.
god damnit gamemaker.

Yeah event_user does call immediately. I don't know why I thought it waited.

So what you have to do then, is call even_user from within the constructor

Code:
with instance_create(..)
{  
    x=20
    event_user(0)
}
 
J

Jaqueta

Guest
I tested here, as FrostyCat said, it doesn't work.
However, using this works perfectly:
Code:
With instance_create
{
    x=100
    event_user(0)
}
EDIT: Ninja'd
 

Phil Strahl

Member
Personally I use an do_init flag in my step event because of exactly that reason:

In my Create event, I would initialize all my variables and flags with default values
Code:
  max_health = global.max_health_default;
  health = 0; // will get set in do_init in the step event
  body_color = global.max_color_default;
  can_run = false;
  parent = noone;

  // process variables -------------------------------------------------
  do_init  = true;
  do_destroy  = false;
Then, on top of the step event have a do_init run once, like this
Code:
if (do_init)
{
  // your init stuff here

  // you can rely on this being performed AFTER max_health was set during creation
  health = max_health;


  do_init = false;
}
Now, when you create instances, they will have the default properties but you can override them when you create them elsewhere, e.g.
Code:
  var newInstance = instance_create(x,y,obj_myObject)
  newInstance.max_health = 150;
  newInstance.color = c_red;
  newInstance.parent = id;
So by delaying the initialization from the Create event to the step event, you can always be sure that the values you set when creating an instance through code are properly set.
 
J

Jaqueta

Guest
That's a good idea!
The only drawback is that it will check for do_init every step, ofc, the performance impact is almost null, but still freaks me out a bit because I'm try-harding to make my game run at 60 FPS on a Potato Notebook. xD
 

Phil Strahl

Member
That's a good idea!
The only drawback is that it will check for do_init every step, ofc, the performance impact is almost null, but still freaks me out a bit because I'm try-harding to make my game run at 60 FPS on a Potato Notebook. xD
I can relate to that ;) I've run tests once with about 1000 instances checking the do_init flag 60 times a second and effectively it was a non-issue. If you want to optimize, drawing/surfaces are a much more lower hanging fruit.
 
M

mariospants

Guest
Basically, it's for when you need to use a code into the Create event, and this code uses a previously defined variable.

For instance:
Code:
team=0

switch(team)
{
case 0:
enemy_color=c_red
break

case 1:
enemy_color=c_blue
break
}
However, if you need to create an instance and set the TEAM on the instance creation. The code won't be executed properly.
So... why not eschew the Create Event entirely and throw all of the create activities into the WITH(newlycreatedinstance) statement and you're done? Leave the object's create events blank and do all of your creation jiggery pokery in the WITH statement...
 
So... why not eschew the Create Event entirely and throw all of the create activities into the WITH(newlycreatedinstance) statement and you're done? Leave the object's create events blank and do all of your creation jiggery pokery in the WITH statement...
... Just like I said! :D
 
Top