firing code once for multiple instances

Pfap

Member
Lets say you have like 10 rpg characters on a map and after each turn you need to run a script to update each instances position within a grid. Maybe a better way to phrase it is that I have 10 instances doing the same thing and after there done with that thing, I want to run 1 script globally for all instances. But I don't want to call it 10 times, because it only needs to run once.

Are global.flags a good way to handle the above?

Code:
//10 instances will be running this at the same time
if active_opp{
   if point_distance(x, y, targetX, targetY) > 5{
 
   move_towards_point(targetX, targetY, 3);
   } 
   else{
  speed = 0;
 
     active_opp = false;

  //this will get fired 10 times unless I do something
     with(update_obj){
 
  event_user(0);
   }
    }
}



With global flag:


Code:
if active_opp{
   if point_distance(x, y, targetX, targetY) > 5{
 
   move_towards_point(targetX, targetY, 3);
   } 
   else{
  speed = 0;
 
     active_opp = false;
  //this will get fired 10 times unless I do something

if global.call_control{
      global.call_control = false;
     with(update_obj){
 
  event_user(0);
   }
}
    }
}
Is the above a good way to handle my situation?
 
C

CreatorAtNight

Guest
Can't you run the code from another object using:
Code:
with(obj_rpgcharacter){
    //code you want to run
}
This will run that code on every obj_rpgcharacter.
Or isn't this what you ment?
 
If you want something to run on multiple instances it's going to have to be called multiple times. No matter how you phrase it, it's going to have to run the movement code, or update code, or whatever, for each instance. There's no way to get it to run 'once' but have each instance magically get changed from that one execution (you can make it LOOK like it's only running once from your end, like using the above with() statement example, but no matter what, it's going to have to be run for each instance). I'm not entirely sure if that's what you're asking for, but there ya go.
 

Pfap

Member
@CreatorAtNight @RefresherTowel

I'm having a script that gets called set active_opp to true. The above way you mentioned would work if scripts had step events. My code is probably confusing and my explanation is not the greatest... I'm sure there has got to be some design pattern to achieve what I'm trying to do. Maybe a chess board would be a better example, there are instances of pawns, knights, rooks etc... But, there is also a board which would need to be updated after every turn. My problem is that instead of getting one move per turn, my game has multiple things that could be viewed as chess pieces doing multiple things per turn, but I still only need it to update at the end of the turn and not for each piece. I may have to pass the data from the script to a control object... just thought of that while typing that might work, then I could use the step event of the single control object instead of the multiple other instances.
 
C

CreatorAtNight

Guest
If we take the chess board game, what exactly would you want to be able to do with it? I don't really understand what your problem is. If I understand correctly you would want to be able to do a different movement for 10 chess pieces but all at 'the same time'?
 
Yeah, it's a much better solution to store what's going to happen in something (I would personally use a data structure, like a ds_queue or something) and then just execute through that data structure at the end of the turn. I have a game where you have interactions all throughout the day, but the results of those interactions (and the relationship changes) are only executed at the end of the day, and that is exactly how I am doing it.
 

Pfap

Member
If we take the chess board game, what exactly would you want to be able to do with it? I don't really understand what your problem is. If I understand correctly you would want to be able to do a different movement for 10 chess pieces but all at 'the same time'?
I'm having trouble explaining it, but I am trying to update a grid once for 36 instances instead of having each instance update its position singly. And I want it to fire once after all 36 pieces have reached the end of their move. So what I currently have is the grid updates each position 36 times per instance so 36x36 if that makes any sense.
 
C

CreatorAtNight

Guest
I'm not sure if I understand what you mean, I think @RefresherTowel already had a good explaination on how to do it. There is not really a way to do it all at once, literally. Code will always be run one by one. Even if you use with() it will cycle through the instances of the object and run the code. But it will appear as if it all runs at the same time because it will all run in the same step. I think that's what you are trying to do, make it all happen in one step?
 

Bentley

Member
y. And I want it to fire once after all 36 pieces have reached the end of their move.
When you move the pieces, are you moving their x and y? If so, I know what you mean by upgrading the grid all at once.

[Example code]

Step event of every instance
// Change x and y

End step event of obj control
Code:
var grid_x, grid_y;
with (obj_piece)
{
    grid_x = x div SQUARE_SIZE;
    grid_y = y div SQUARE_SIZE;
  
    global.grid[# grid_x, grid_y] = id;
}
 

Pfap

Member
When you move the pieces, are you moving their x and y? If so, I know what you mean by upgrading the grid all at once.

[Example code]

Step event of every instance
// Change x and y

End step event of obj control
Code:
var grid_x, grid_y;
with (obj_piece)
{
    grid_x = x div SQUARE_SIZE;
    grid_y = y div SQUARE_SIZE;
 
    global.grid[# grid_x, grid_y] = id;
}
Yes, that is exactly what I mean. Accept I don't have a set point in time where I can call the above from a control object. Because I want it to happen when the last of the pieces moves. So for instance there are 36 pieces and the player can move piece 1 first or he could move piece 36 first or any in between. How could I call code like what you posted only when the last piece has been moved? I could always force the player to move pieces in a specific order, that way when piece 36 is moved I know the turn is over, but I want to give them options. I think it just came to me... I could run a tally, something like moves_left = 36 and subtract from it each move, then order doesn't matter.
 

Bentley

Member
Yes, that is exactly what I mean. Accept I don't have a set point in time where I can call the above from a control object. Because I want it to happen when the last of the pieces moves. So for instance there are 36 pieces and the player can move piece 1 first or he could move piece 36 first or any in between. How could I call code like what you posted only when the last piece has been moved? I could always force the player to move pieces in a specific order, that way when piece 36 is moved I know the turn is over, but I want to give them options. I think it just came to me... I could run a tally, something like moves_left = 36 and subtract from it each move, then order doesn't matter.
I think you are right. If you want the player to move 36 pieces before updating the board, a variable that tracks the moves sounds good.
Example code:

obj_piece
[step event]
Code:
if (i_am_trying_to_move_this_piece && global.moves_remaining > 0)
{
    // Convert room coordinates to grid coordinates
    var grid_x, grid_y;
    grid_x = x div SQUARE_SIZE;
    grid_y = y div SQUARE_SIZE;
 
    // Ensure the target square is on the grid
    if (point_in_rectangle(grid_x, grid_y, 0, 0, ds_grid_width(global.grid) - 1, ds_grid_height(global.grid) - 1)
    {
        x = somewhere;
        y = somewhere;
        global.moves_remaining -= 1;
        // You could update grid here. It seems easier. But I wrote it the way you were talking about below
    }
}
obj_control
[end step event]
Code:
if (global.moves_remaining <= 0)
{
    // Update grid
    var grid_x, grid_y;
    with (obj_piece)
    {
        // Get the pieces grid coordinates
        grid_x = x div SQUARE_SIZE;
        grid_y = y div SQUARE_SIZE;         
        global.grid[# grid_x, grid_y] = id;
                
    }
    
    turn = someone_else;
    global.moves_remaining = 36;   
}
 
Last edited:

Pfap

Member
I think you are right. If you want the player to move 36 pieces before updating the board, a variable that tracks the moves sounds good.
Example code:

obj_piece
[step event]
Code:
if (i_am_trying_to_move_this_piece && global.moves_remaining > 0)
{
    // Convert room coordinates to grid coordinates
    var grid_x, grid_y;
    grid_x = x div SQUARE_SIZE;
    grid_y = y div SQUARE_SIZE;
 
    // Ensure the target square is on the grid
    if (point_in_rectangle(grid_x, grid_y, 0, 0, ds_grid_width(global.grid) - 1, ds_grid_height(global.grid) - 1)
    {
        x = somewhere;
        y = somewhere;
        global.moves_remaining -= 1;
        // You could update grid here. It seems easier. But I wrote it the way you were talking about below
    }
}
obj_control
[end step event]
Code:
if (global.moves_remaining <= 0)
{
    // Update grid
    var grid_x, grid_y;
    with (obj_piece)
    {
        // Get the pieces grid coordinates
        grid_x = x div SQUARE_SIZE;
        grid_y = y div SQUARE_SIZE;        
        global.grid[# grid_x, grid_y] = id;
               
    }
   
    turn = someone_else;
    global.moves_remaining = 36;  
}
Yea, I can definitely do something with this. I find it kind of amusing that your avatar is a final fantasy mage, because those games are turn based. It seems that each genre has its own design challenges.

Thanks!
 
Top