How to remove underlying

P

Phemus

Guest
I made game you can place blocks and you can place wallpapers to behind of the block. But when I press to break, wallpaper and block get broken. But I want to 1 press break block then if I press again break wallpaper. Help :/ <3
 

Jaqueta

Member
On the wallpaper script, you can check if there's a block above it, if true, then it won't break the wallpaper, if false, it'll break.

Another option, is cycle through the instances that are hovered by the mouse, and destroy the one with smaller depth. This way, you can have multiple blocks on top of each other, but it will use more CPU.
 
P

Phemus

Guest
On the wallpaper script, you can check if there's a block above it, if true, then it won't break the wallpaper, if false, it'll break.

Another option, is cycle through the instances that are hovered by the mouse, and destroy the one with smaller depth. This way, you can have multiple blocks on top of each other, but it will use more CPU.
Im pretty newbie :D How can I do that?
 
P

Phemus

Guest
That really depends on the code you're using, please show us, so we can give you an more accurate answer ^^
That really depends on the code you're using, please show us, so we can give you an more accurate answer ^^
Code:
if (!place_free(x+hspeed,y))
{
     if (hspeed<=0) {move_contact_solid(180,abs(hspeed));}
     if (hspeed>0) {move_contact_solid(0,abs(hspeed));}
     hspeed = 0;
}

if (!place_free(x,y+vspeed))
{
     if (vspeed<=0) {move_contact_solid(90,abs(vspeed));}
     if (vspeed>0) {move_contact_solid(270,abs(vspeed));}
     vspeed = 0;
}

if (!place_free(x+hspeed,y+vspeed))
{
    hspeed=0;
}
 

Yal

🍋 *lemon noises*
GMC Elder
Nonono, the code you use to break things, not the movement code....
 
P

Phemus

Guest
Nonono, the code you use to break things, not the movement code....
Ugh Yeah I realized after posting. That's im using:
Code:
instance_change(dropped,yes)
dropped is nothing.
 

Jaqueta

Member
Nonono, the code you use to check if you can break things or not.

Is it a mouse event? Or is something like
if mouse_check_button(mb_left)
if distanc..... blablabla...
.................
{
instance_change............
}
 
P

Phemus

Guest
Nonono, the code you use to check if you can break things or not.

Is it a mouse event? Or is something like
if mouse_check_button(mb_left)
if distanc..... blablabla...
.................
{
instance_change............
}
I'm using GM 8.1 Pro and not needed to codes I just converted. But I try to convert as I know:

if mouse_check_button_pressed (mb_left)
{
instance_change(dropped, yes)
}

^^Not so professional code but I think I need code with depths.
 

Jaqueta

Member
Ok, so, I suppose that you have two separated object types for Blocks and Wallpapers, so, fortunatelly, you won't need a depth based system, which is not very optimal (CPU usage wise).

I also suppose that you have this code, inside every object, delete it, every block/wallpaper checking for an mouse_event is an waste of CPU, also, not very friendly when you need to change the code later.

Alright, now the real code, you can put this at a Controller Object, or even the player.

First we need to check if there's Block Object on the mouse position, since we need to know which block we are clicking on, we'll need to use instance_position, unlike place_meeting that returns either true, or false, instance_place will return the unique instance ID of that object.
With that, we'll be able to check if there's an block at the mouse position, if there's, we destroy that block, if there's not, we check if there's an wallpaper, if there's, we destroy that wallpaper, if there's not, nothing happens.

Before copying and pasting the code, try to see what each function does and learn what the code does exactly, if you got any questions, feel free to ask and I'll respond the fast as I can.
I commented each line of the code, to help you figure that out.
Code:
if mouse_check_button_pressed(mb_left) //If we clicked with the Mouse
{
    var block=instance_position(mouse_x,mouse_y,obj_block)
    //As said before, this function will return the unique instance ID, of the block object that is at the mouse position
    //If there's no block, it will return noone.
    if block!=noone //If it doesn't return noone, We will execute the action
    {
        with (block) {instance_destroy()} //We destroy our block
    }
    else //If it DOES return noone, we check if there's an Wallpaper now
    {
        var wallpaper=instance_position(mouse_x,mouse_y,obj_wallpaper)
        //Now we do the same thing as above, but with the wallpaper
        if wallpaper!=noone //If there's one there
        {
            with (wallpaper) {instance_destroy()} //We destroy it
        }
    }

}
EDIT: My bad, you should use instance_position instead of instance_place, or else, it'll use the object mask, and it may destroy an object that is not under the mouse.
 
Last edited:
P

Phemus

Guest
Ok, so, I suppose that you have two separated object types for Blocks and Wallpapers, so, fortunatelly, you won't need a depth based system, which is not very optimal (CPU usage wise).

I also suppose that you have this code, inside every object, delete it, every block/wallpaper checking for an mouse_event is an waste of CPU, also, not very friendly when you need to change the code later.

Alright, now the real code, you can put this at a Controller Object, or even the player.

First we need to check if there's Block Object on the mouse position, since we need to know which block we are clicking on, we'll need to use instance_position, unlike place_meeting that returns either true, or false, instance_place will return the unique instance ID of that object.
With that, we'll be able to check if there's an block at the mouse position, if there's, we destroy that block, if there's not, we check if there's an wallpaper, if there's, we destroy that wallpaper, if there's not, nothing happens.

Before copying and pasting the code, try to see what each function does and learn what the code does exactly, if you got any questions, feel free to ask and I'll respond the fast as I can.
I commented each line of the code, to help you figure that out.
Code:
if mouse_check_button_pressed(mb_left) //If we clicked with the Mouse
{
    var block=instance_position(mouse_x,mouse_y,obj_block)
    //As said before, this function will return the unique instance ID, of the block object that is at the mouse position
    //If there's no block, it will return noone.
    if block!=noone //If it doesn't return noone, We will execute the action
    {
        with (block) {instance_destroy()} //We destroy our block
    }
    else //If it DOES return noone, we check if there's an Wallpaper now
    {
        var wallpaper=instance_position(mouse_x,mouse_y,obj_wallpaper)
        //Now we do the same thing as above, but with the wallpaper
        if wallpaper!=noone //If there's one there
        {
            with (wallpaper) {instance_destroy()} //We destroy it
        }
    }

}
EDIT: My bad, you should use instance_position instead of instance_place, or else, it'll use the object mask, and it may destroy an object that is not under the mouse.
Will I do copy paste it for each block and wallpaper? Cause there is many blocks and wallpapers in game. Or is GM has a function you can create a group of blocks and wallpapers?
 

Jaqueta

Member
I also suppose that you have this code, inside every object, delete it, every block/wallpaper checking for an mouse_event is an waste of CPU, also, not very friendly when you need to change the code later.

Alright, now the real code, you can put this at a Controller Object, or even the player.
=)
 

GMWolf

aka fel666
Don't copy paste the code to every object.
Use parenting instead.
A tutorial on parenting:
 
P

Phemus

Guest
It doesn't work I create object name called controller, I placed this code into step event and game crashes.
Code:
if mouse_check_button_pressed(mb_left) //If we clicked with the Mouse
{
    var block=instance_position(mouse_x,mouse_y,block)
    //As said before, this function will return the unique instance ID, of the block object that is at the mouse position
    //If there's no block, it will return noone.
    if block!=noone //If it doesn't return noone, We will execute the action
    {
        with (block) {instance_destroy()} //We destroy our block
    }
    else //If it DOES return noone, we check if there's an Wallpaper now
    {
        var wallpaper=instance_position(mouse_x,mouse_y,wallpaper)
        //Now we do the same thing as above, but with the wallpaper
        if wallpaper!=noone //If there's one there
        {
            with (wallpaper) {instance_destroy()} //We destroy it
        }
    }

}
I used this parenting way.
 

Jaqueta

Member
The problem is that your object have the same name as the local variable.

wallpaper=instance_position(mouse_x,mouse_y,wallpaper)
see?

When creating an resource, I recommend using an prefix before them, like spr_ for sprites, obj_ for objects.

So, here's your solution: change the name of your objects, and try using a prefix, like this: obj_wallpaper and obj_block

Also, be aware that with this code, I suggest parenting all your wallpapers to the "Father" wallpaper, and all Blocks to your "Father" blocks.
This way you'll still have the destruction in the correct order.
 
P

Phemus

Guest
Eh, I did now game not crashing but I can't break anything. I made two object obj_wallpaper and obj_block and set parent for every blocks and wallpapers. Not work plus there is error with code. It's wrong:

var block=instance_position...

There is must not "=". It says unknown script code.
 
Top