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

Trouble with parent and child objects

A

AutoLiMax

Guest
Hi, I'm stuck on a little bit of script.

What I'm trying to create is a script that says something along the lines of:
"if the object at this location is not obj_ocean then do something".
I have a parent object named "obj_parentTerrain" and the obj_ocean object is a child of the parent.

This is a section of the script from the destroy event:
Code:
spriteSize = 32;

instUp = instance_place(x, y-spriteSize, obj_parentTerrain);

if instUp != obj_ocean
            {
                with (instUp)
                    {
                        image_index = scr_autoTile();
                    }
            }
For some reason the line "if instUp != obj_ocean" isn't working. scr_autoTile(); runs on the obj_ocean object when it shouldn't. :(

Does anyone have any insight?

Thanks!
 
A

AutoLiMax

Guest
Ahhh that's it. I knew it would be something like that. I just needed to specify what I want from the variable. Such as instRight.x.

Thanks for that
 
A

AutoLiMax

Guest
Ahh I've noticed an issue.

For some reason the "with (instUP)" is running the script on all the instances with the same name. Not the specific instance at that location.
Any obvious reason this could be happening?

Thanks
 

jo-thijs

Member
In the code you've given with my fix applied, that should not be the case.
instance_place only returns 1 instance id, so only 1 instance can get referenced.
Have you redefined instUp or do you have any other code that might cause this?
 
P

ParodyKnaveBob

Guest
Btw, a quick gotcha, instance_place() can return noone when there's no collision, meaning instUp.object_index would err.

if (instUp != noone && instUp.object_index) {

is just one way to fix it.

I hope this helps!
Bob $:^ ]
 
A

AutoLiMax

Guest
Hi, I've only just had a chance to give this a shot after getting home.
I know this should only be working on the one instance. That is the purpose of instance place. It's crazy.
It is deffinatley colliding as I've used show_debug_message to confirm.
I've also tried if (instUp != noone && instUp.object_index) but that makes the script run on every obj_ocean tile.

This is the whole destroy script.
Code:
if hp <= 0
    {
        instance_deactivate_object(id);
        
        spriteSize = 32;
        
        instUp = instance_place(x, y-spriteSize, obj_parentTerrain);
        instDown = instance_place(x, y+spriteSize, obj_parentTerrain);
        instLeft = instance_place(x-spriteSize, y, obj_parentTerrain);
        instRight = instance_place(x+spriteSize, y, obj_parentTerrain);
        instUpRight = instance_place(x+spriteSize, y-spriteSize, obj_parentTerrain);
        instUpLeft = instance_place(x-spriteSize, y-spriteSize, obj_parentTerrain);
        instDownRight = instance_place(x+spriteSize, y+spriteSize, obj_parentTerrain);
        instDownLeft = instance_place(x-spriteSize, y+spriteSize, obj_parentTerrain);
        
        instance_create(x, y, terrainSpawn)
        with (terrainSpawn)
            {
                image_xscale = 2;
                image_yscale = 2;
                image_index = scr_autoTile();
            }           
        if instUp.object_index != obj_ocean
            {
                with (instUp.object_index)
                    {
                        image_index = scr_autoTile();
                    }
            }
        if instDown.object_index != obj_ocean
            {
                with (instDown.object_index)
                    {
                        image_index = scr_autoTile();
                    }
            }
        if instLeft.object_index != obj_ocean
            {
                with (instLeft.object_index)
                    {
                        image_index = scr_autoTile();
                    }
            }
        if instRight.object_index != obj_ocean
            {
                with (instRight.object_index)
                    {
                        image_index = scr_autoTile();
                    }
            }
        if instUpRight.object_index != obj_ocean
            {
                with (instUpRight.object_index)
                    {
                        image_index = scr_autoTile();
                    }
            }
        if instUpLeft.object_index != obj_ocean
            {
                with (instUpLeft.object_index)
                    {
                        image_index = scr_autoTile();
                    }
            }
        if instDownRight.object_index != obj_ocean
            {
                with (instDownRight.object_index)
                    {
                        image_index = scr_autoTile();
                    }
            }
        if instDownLeft.object_index != obj_ocean
            {
                with (instDownLeft.object_index)
                    {
                        image_index = scr_autoTile();
                    }
            }

            
        instance_activate_object(id);
}
I know the script is running on every instance with the same name because I have everything that's not visible (off screen) deactivated.
So when it comes in to view I can see seams between the instances that were on screen when the script was run and the instances that weren't on screen when the script was run.

It's a bit of a strange one. Anything else that could be causing this odd behaviour?

Thanks
 
A

AutoLiMax

Guest
It was origionally this:
Code:
if instUp.object_index != obj_ocean
            {
                with (instUp)
                    {
                        image_index = scr_autoTile();
                    }
            }
Which still executes the script for each instance with the same name. I can still see the seams. :s I only added .object_index as a ditch attempt. :p
 

jo-thijs

Member
Well, then I don't see anything wrong with that code.
Perhaps some other code might be causing it?
What does scr_autoTile do for instance?
 
A

AutoLiMax

Guest
I'm pretty sure nothing else could be affecting it.

This is the autotile script. It just checks the surrounding instances and changes the image index.
Code:
var tile,iw,w_left,w_right,w_up,w_down,w_upleft,w_downleft,w_upright,w_downright;
//object_index
iw          = sprite_width;
w_left      = place_meeting(x-iw,y,object_index);
w_right     = place_meeting(x+iw,y,object_index);
w_up        = place_meeting(x,y-iw,object_index);
w_down      = place_meeting(x,y+iw,object_index);
w_upleft    = place_meeting(x-iw,y-iw,object_index);
w_downleft  = place_meeting(x-iw,y+iw,object_index);
w_upright   = place_meeting(x+iw,y-iw,object_index);
w_downright = place_meeting(x+iw,y+iw,object_index);

if (x-iw < 0            ) {w_left = 1; w_upleft = 1; w_downleft = 1;}
if (x+iw > room_width   ) {w_right = 1; w_upright = 1; w_downright = 1;}
if (y-iw < 0            ) {w_up = 1; w_upright = 1; w_upleft = 1;}
if (y+iw > room_height  ) {w_down = 1; w_downright = 1; w_downleft = 1;}

tile=44
if(w_up)
{
 tile=0
 if(w_right)
 {
  tile=4
  if(w_down)
  {
   tile=12
   if(w_left)
   {
    tile=28
    if(w_upright)
    {
     tile=29
     if(w_downright)
     {
      tile=33
      if(w_downleft)
      {
       tile=39
       if(w_upleft)tile=43
      }
      else if(w_upleft)tile=40
     }
     else if(w_downleft)
     {
      tile=37
      if(w_upleft)tile=41
     }
     else if(w_upleft)tile=36
    }
    else if(w_downright)
    {
     tile=30
     if(w_downleft)
     {
      tile=34
      if(w_upleft)tile=42
     }
     else if(w_upleft)tile=38
    }
    else if(w_downleft)
    {
     tile=31
     if(w_upleft)tile=35
    }
    else if(w_upleft)tile=32
   }
   else if(w_upright)
   {
    tile=16
    if(w_downright)tile=18
   }
   else if(w_downright)tile=17
  }
  else if(w_left)
  {
   tile=15
   if(w_upright)
   {
    tile=25
    if(w_upleft)tile=27
   }
   else if(w_upleft)tile=26
  }
  else if(w_upright)tile=8
 }
 else if(w_down)
 {
  tile=45
  if(w_left)
  {
   tile=14
   if(w_downleft)
   {
    tile=22
    if(w_upleft)tile=24
   }
   else if(w_upleft)tile=23
  }
 }
 else if(w_left)
 {
  tile=7
  if(w_upleft)tile=11
 }
}
else if(w_right)
{
 tile=1
 if(w_down)
 {
  tile=5
  if(w_left)
  {
   tile=13
   if(w_downright)
   {
   tile=19
    if(w_downleft)tile=21
   }
   else if(w_downleft)tile=20
  }
  else if(w_downright)tile=9
 }
 else if(w_left)
 {
  tile=46
 }
}
else if(w_down)
{
 tile=2
 if(w_left)
 {
  tile=6
  if(w_downleft)tile=10
 }
}
else if(w_left)
{
 tile=3
}

return tile;
 
A

AutoLiMax

Guest
Ok, it would appear that it only seams to happen when obj_sand gets destroyed. which is odd becuase it's pretty much exactly the same as all the other terrain objects. The only difference being the sprite and the name.

Could it have something to do with the fact that pretty much all the sand instances are next to the ocean instances? It's a far stretch but I'm just trying to rule things out at this stage.


** EDIT**

I think it has something to do with this:
Code:
instance_create(x, y, terrainSpawn)
        with (terrainSpawn)
            {
                image_xscale = 2;
                image_yscale = 2;
                image_index = scr_autoTile();
            }
Which replaces the destroyed instance with a new instance . I've commented it out and now the script runs on the instances it's supposed to but I don't see why it would affect anything.......

This is in the create event of obj_sand
Code:
terrainSpawn = choose(obj_sand, obj_sand, obj_sand, obj_sand, obj_clay);
........Slowly making progressss



** EDIT 2 **

It's the scr_autoTile script when executing with terrainSpawn. I commented just that line and it worked. But the newly created instance doesn't have that script run on it.... which is an issue. :(
 
Last edited by a moderator:
A

AutoLiMax

Guest
Ok so I think I have fixed it...... for now
Code:
        instance_create(x, y, terrainSpawn)
        with (terrainSpawn)
            {
                image_xscale = 2;
                image_yscale = 2;
            }
        instCent = instance_place(x, y, obj_parentTerrain);     
        if instCent.object_index != obj_ocean
            {
                with (instCent)
                    {
                        image_index = scr_autoTile();
                    }
            }
I just ran the autoTile script the same as the other instances. Rather than on the instance as it is created I've stored the object at the location in a variable name instCent. I'm not sure why it was acting the way it was. But it's sorted for now.

Thanks
 
P

ParodyKnaveBob

Guest
if (instUp != noone && instUp.object_index) {
I've also tried if (instUp != noone && instUp.object_index)
Ugh, sorry, typo for being tired and rushing. There's no way I would actually intend to suggest using if (instUp.object_index) as a Boolean (true/false) check. I meant:

Code:
if (instUp != noone  &&  instUp.object_index != obj_ocean) {
As long as you haven't unticked "Short-circuit evaluations," this'll stop at noone before object_index can throw an error. That's all I was trying to help with, sorry.

Regards,
Bob
 
Last edited by a moderator:

jo-thijs

Member
So terrainSpawn is a variable rather than an object?
Then this here:
Code:
       instance_create(x, y, terrainSpawn)
        with (terrainSpawn)
            {
                image_xscale = 2;
                image_yscale = 2;
                image_index = scr_autoTile();
            }
will be executed for every instance of type terrainSpawn, not just for the newly created nstance, which might be causing your issue.
 
Top