Destroying one of five of the same instances [SOLVED]

Afternoon people,

I have five instances of obj_ball in a room, and one of obj_en_cat. When the player fails at an in game matching task, a scene is triggered where obj_en_cat destroys one instance of obj_ball by moving towards it and colliding with it (bursting it) leaving the rest intact. This can happen until there are no obj_ball left, so five times.

Conceptually, if someone could help me with the most elegant code to do this I would appreciate it. I think the best way would be a for loop with a degrees of freedom element but I am not sure how to write this (just a novice). I could use paths and multiple if statements to cover every stipulation but this seems too long.

Any help appreciated and don't forget the Nintendo Direct at 5pm! (Stealth direct post)
 

CloseRange

Member
well getting the random ball is pretty simple. Create a script that returns one of the random balls:

Code:
/// rand_ball();
temp_ball[0] = noone;
var i = 0;
with(obj_ball) {
     temp_ball[i++] = id;
}
if(i != 0) return temp_ball[irandom(i-1)];
if you simply want to just do instance_destroy on a random ball you could now simply do:
Code:
var ball = rand_ball();
instance_destroy(ball);
if you want to make the cat first move to the target then destroy it have the cat store a variable called target = noone in the create event
then when you fail the task do:
Code:
target = rand_ball();
and in the step event you just make it move to the target:
Code:
if(target != noone) {
     var dir = point_direction(x, y, target.x, target.y);
     x += lengthdir_x(5, dir);
     y += lengthdir_y(5, dir);
}
// where 5 is the speed the cat moves
 
/// rand_ball();
temp_ball[0] = noone; //Here you store temp_ball into the variable no one and assign it a value of 0?
var i = 0; //variable i=0
with(obj_ball)
{ temp_ball[i++] = id; } //What are you doing here with object ball? Incrementing i, but why store it in id?
if(i != 0) return temp_ball[irandom(i-1)];//If i doesn't equal 0, return value temp ball which does what?
Thanks for the reply. I'm a complete noob at this (just basic if statements, paths etc) so reams of code is hard for me to follow. I've commented on the lines to see if I am following correctly? As I said, pretty much a novice.
 

CloseRange

Member
@Mr Awesome
ah let me explain.
First off you might not know what an array is huh?
an array is a type of variable.
Instead of storing one number or value it stores mutiple in a list.
Code:
array[0] = 5;
array[1] = 25;
array[2] = 101;
that makes an array with 3 values. To get the value simply do this:
Code:
var i = 2;
show_debug_message(array[i]); // this will log array[2] so 101 because that's what we stored
so looking back at the script:

Code:
/// rand_ball();
temp_ball[0] = noone; // start a basic array where the first value is empty (the first value will change later)
var i = 0; // i will represent how many balls there are currently (it starts out at 0 because we don't know how many there are)
with(obj_ball) { // this line lets us performe the code on every single obj_ball in the room
     temp_ball[i++] = id;
     // i increases by 1 for every ball in existstance, this is why i stores how many balls there are
     /* we use the temp_ball because this will fill the array with all the balls:
     temp_ball[0] is the first ball
     temp_ball[1] is the second ball
     ect....

     we store id because that is how you store the object in a variable
     */
}
if(i != 0) return temp_ball[irandom(i-1)]; // if i = 0 that means there are no balls in existance
// irandom(i-1) gets a random number from 0 to however many balls exist
// so temp_ball[irandom(i-1)] will return whatever ball we randomly chose.
 
@Mr Awesome
ah let me explain.
First off you might not know what an array is huh?
an array is a type of variable.
Instead of storing one number or value it stores mutiple in a list.
Code:
array[0] = 5;
array[1] = 25;
array[2] = 101;
that makes an array with 3 values. To get the value simply do this:
Code:
var i = 2;
show_debug_message(array[i]); // this will log array[2] so 101 because that's what we stored
so looking back at the script:

Code:
/// rand_ball();
temp_ball[0] = noone; // start a basic array where the first value is empty (the first value will change later)
var i = 0; // i will represent how many balls there are currently (it starts out at 0 because we don't know how many there are)
with(obj_ball) { // this line lets us performe the code on every single obj_ball in the room
     temp_ball[i++] = id;
     // i increases by 1 for every ball in existstance, this is why i stores how many balls there are
     /* we use the temp_ball because this will fill the array with all the balls:
     temp_ball[0] is the first ball
     temp_ball[1] is the second ball
     ect....

     we store id because that is how you store the object in a variable
     */
}
if(i != 0) return temp_ball[irandom(i-1)]; // if i = 0 that means there are no balls in existance
// irandom(i-1) gets a random number from 0 to however many balls exist
// so temp_ball[irandom(i-1)] will return whatever ball we randomly chose.
Thanks for the details, makes it a lot easier for someone with my skill level. The rest I can figure out. I'm intrigued....why do you like penguins? Do you make games about penguins?
 

CloseRange

Member
Thanks for the details, makes it a lot easier for someone with my skill level. The rest I can figure out. I'm intrigued....why do you like penguins? Do you make games about penguins?
I don't think I've ever made a game about penguins but that's because I suck at drawing. They just happen to be my favorite animal and I have about 7 penguin dolls sitting on my desk. Just a great animal
 

Bentley

Member
have five instances of obj_ball in a room, and one of obj_en_cat. When the player fails at an in game matching task, a scene is triggered where obj_en_cat destroys one instance of obj_ball
I'm assuming the ball you want to destroy is random:
Code:
var total, inst;
total = instance_number(o_ball) - 1;
inst = instance_find(o_ball, irandom(total));
instance_destroy(inst);
 
I'm assuming the ball you want to destroy is random:
Code:
var total, inst;
total = instance_number(o_ball) - 1;
inst = instance_find(o_ball, irandom(total));
instance_destroy(inst);
Nice code! Thank you. Bit late following up, but, how would I make obj_cat jump to the position (or next to) where the random ball was destroyed?
 

Yal

🐧 *penguin noises*
GMC Elder
You could have an even more elegant solution using with loops:
Code:
with(instance_nearest(random(room_width),random(room_height),obj_ball)){
  instance_destroy()
}
This also has the side effect that nothing happens if there's 0 balls left (this usually is what you want, since accessing non-existant objects can cause weird errors).

To also make the cat move there, you could do this:
Code:
with(instance_nearest(random(room_width),random(room_height),obj_ball)){
  with(obj_cat){
    x = other.x
    y = other.y
  }
  instance_destroy()
}

With loops are really useful, I strongly recommend checking them out~
(note how "other" inside a with loop refers to the object whose scope you are in before the loop starts, so in this case it refers to the randomly picked ball when we move the cat).
 
You could have an even more elegant solution using with loops:
Code:
with(instance_nearest(random(room_width),random(room_height),obj_ball)){
  instance_destroy()
}
This also has the side effect that nothing happens if there's 0 balls left (this usually is what you want, since accessing non-existant objects can cause weird errors).

To also make the cat move there, you could do this:
Code:
with(instance_nearest(random(room_width),random(room_height),obj_ball)){
  with(obj_cat){
    x = other.x
    y = other.y
  }
  instance_destroy()
}

With loops are really useful, I strongly recommend checking them out~
(note how "other" inside a with loop refers to the object whose scope you are in before the loop starts, so in this case it refers to the randomly picked ball when we move the cat).
Thanks Elder! I will try this out. To make sure I understand, the first part of the code just chooses a random ball within the room(defined by width and height) and destroys it. Although will it always choose the ball nearest the cat (who is stationary at this point) so therefore it won't be random right?

In the second part, why does other refer to the obj_ball that has just been destroyed? How does it know to refer to that one? Also, if the object I am in is actually the cat, what would I need to change in the second part?
 

Yal

🐧 *penguin noises*
GMC Elder
Thanks Elder! I will try this out. To make sure I understand, the first part of the code just chooses a random ball within the room(defined by width and height) and destroys it. Although will it always choose the ball nearest the cat (who is stationary at this point) so therefore it won't be random right?

In the second part, why does other refer to the obj_ball that has just been destroyed? How does it know to refer to that one? Also, if the object I am in is actually the cat, what would I need to change in the second part?
The code selects the ball that's the closest to a random point in the room. (This means it selects a random ball).

The loop scope changes goes like this:
Code:
> cat is current scope, other is undefined
with(random ball){
  > ball is current scope, cat is other
  with(cat){
    > cat is current scope, ball is other
  }
}
Since instance_nearest returns an ID, we will with-loop over a single object. With-loops change scope to another object (either an object type or the keyword "all" to deal with multiple instances, or a single instance ID), they're useful when you want to run code relative to an object. E.g. to move all balls up, you'd write
Code:
with(obj_ball){
  y -= 1000
}
It's also useful to access an instance's local variables, like saving their current position to a file when saving the game.
 
The code selects the ball that's the closest to a random point in the room. (This means it selects a random ball).

The loop scope changes goes like this:
Code:
> cat is current scope, other is undefined
with(random ball){
  > ball is current scope, cat is other
  with(cat){
    > cat is current scope, ball is other
  }
}
Since instance_nearest returns an ID, we will with-loop over a single object. With-loops change scope to another object (either an object type or the keyword "all" to deal with multiple instances, or a single instance ID), they're useful when you want to run code relative to an object. E.g. to move all balls up, you'd write
Code:
with(obj_ball){
  y -= 1000
}
It's also useful to access an instance's local variables, like saving their current position to a file when saving the game.
Thanks for the explanations. This is working so marking as solved.
 
  • Like
Reactions: Yal
You could have an even more elegant solution using with loops:
Code:
with(instance_nearest(random(room_width),random(room_height),obj_ball)){
  instance_destroy()
}
This also has the side effect that nothing happens if there's 0 balls left (this usually is what you want, since accessing non-existant objects can cause weird errors).

To also make the cat move there, you could do this:
Code:
with(instance_nearest(random(room_width),random(room_height),obj_ball)){
  with(obj_cat){
    x = other.x
    y = other.y
  }
  instance_destroy()
}

With loops are really useful, I strongly recommend checking them out~
(note how "other" inside a with loop refers to the object whose scope you are in before the loop starts, so in this case it refers to the randomly picked ball when we move the cat).
Realise this thread is old, but I wanted to replace the ball I destroyed with another one of the same object in the same position. There are five balls and I have their coordinates stored. If you know how to do this, it would be appreciated. Thanks!
 
Top