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

why does instance_create_layer make two instances

ETHC33

Member
this has happended in multiple places, one when you shoot the pistol(not the rifle) and when you use the shield(it creates two arms on the left side) why is this happening and how do i solve it? ill post the gunstate free(); code
function gunstate_free()
{






image_angle = point_direction(x,y,mouse_x,mouse_y);




#region animation
if (!mouse_check_button(mb_left))
{image_index = 0;
}

if mouse_check_button(mb_left) and (ammo > 0)
{ image_speed = 1;}
else
{
image_speed = 0;
}

#endregion
if (reloadkey)
{

gunstate = GUNSTATE.RELOADING
}


if hasrifle == true
{
if keyboard_check_pressed(ord("1"))
{
prev_gun = Spr_gun;
firingdelay = 5;


}}

if (current_gun == Spr_pistol)
{
current_gun_ammo_maximum = 12;
current_reload = Spr_pistol_reload;
x = obj_player.x -9;
y = obj_player.y -21;

}

if (current_gun == Spr_gun)
{current_reload = Spr_reload;
current_gun_ammo_maximum = 25;
x = obj_player.x -9;
y = obj_player.y -21;
}
#region shield

if (mouse_check_button(mb_right))
{
current_gun = Spr_bullet_shield;
layer = layer_get_id("ladders");
x = obj_player.x + 4;
y = obj_player.y + - 18;
var arm = instance_create_layer(x,y,"gun", Obj_arm); // creates two here
}
else{ current_gun = prev_gun;
layer = layer_get_id("gun")



};

#endregion



recoil = max(0,recoil - 0.5);

firingdelay = firingdelay - 1;

if (mouse_check_button(mb_left)) and (firingdelay < 0) and (current_gun = Spr_gun) and (ammo > 0)

{

image_speed = 0;
recoil = 4;
firingdelay = 5
screenshake(2,10);
audio_play_sound(sn_gunshot,5,false);
ammo -=1;
effect_create_below(ef_smoke, x = lengthdir_x + 25, y, 0, c_gray);
with (instance_create_layer(x,y,"bullet",Obj_bullet))
{
spd = 25;
direction = other.image_angle + random_range(-4,4);
image_angle = direction;


}

x = x - lengthdir_x(recoil,image_angle);
y=y - lengthdir_y(recoil,image_angle);
}
#region pistol

if keyboard_check_pressed(ord("2"))
{
prev_gun = Spr_pistol;

}


if (mouse_check_button(mb_left)) and (firingdelay < 0) and (current_gun = Spr_pistol) and (pistol_ammo >0)
{


recoil = 4;
firingdelay = 8;
screenshake(2,10);
audio_play_sound(sn_gunshot,5,false);
pistol_ammo -=1;




with (instance_create_layer(x,y,"bullet",Obj_pistol_bullet)) //creates two bullets here

{

spd = 25;
direction = other.image_angle + random_range(-4,4);
image_angle = direction;
}

#endregion


x = x - lengthdir_x(recoil,image_angle);
y=y - lengthdir_y(recoil,image_angle);


}

if (image_angle > 90) and (image_angle < 270)
{

image_yscale = -1;
x = obj_player.x +14;
y = obj_player.y - 21;
}
else
{
image_yscale = 1;
}
}
//excuse my ignorance and messy code i'm new to this
 

chamaeleon

Member
An single instance create call does not create two instances. I'm going to guess the same line of code executes more than once. Use the debugger, use show_debug_message(). All tools that will help you determine what runs when, and by what instance (while keeping in mind you might have more than one that could execute the same code).
GML:
show_debug_message("Count before = " + string(instance_number(Obj_arm)));
var arm = instance_create_layer(x,y,"gun", Obj_arm); // creates two here
show_debug_message("Count after = " + string(instance_number(Obj_arm)));
If you see the two messages displayed more than once each, you'll also know your code is executed more than once. If you only see an increment by one but later you observe having two, you have another instance creation call somewhere else in your code. If you do see an increment of two, you have an instance create call in the Create event of Obj_arm.
 
Last edited:

Vusur

Member
I picked one of the problems (it looked like you used the same method everywhere).

GML:
if (mouse_check_button(mb_right)) //<- THIS IS THE PROBLEM
{
    current_gun = Spr_bullet_shield;
    layer = layer_get_id("ladders");
    x = obj_player.x + 4;
    y = obj_player.y + - 18;
    var arm = instance_create_layer(x,y,"gun", Obj_arm); // creates two here
}
The manual about mouse_check_button(..)
This function will return true if the mouse button being checked is held down or false if it is not.
A simple human click is slower than the step event cycle. I also assume, you create even more than two. Try it out, hold mb_right down.

If you want one instance for one click, regardless how fast or slow you are, you'll need mouse_check_button_pressed(..) or mouse_check_button_released(..)
Manual about mouse_check_button_pressed(..)
This function will return true if the mouse button being checked has been pressed or false if it has not. This function will only be triggered once for any mouse button when it is first pressed and to trigger it again the button will need to have been released and pressed again. Note that it will be considered triggered for the duration of the step, and for all instances that have any mouse events or that use this same function.
This should be the problem, unless there is something else going on in different places. But the code was hard to read. Tip for next time (or edit your post): How to properly put your code in a Thread ;)
 

TheouAegis

Member
As vusur pointed out, your are creating multiple arms because there is no delay associated with the arm. You are only creating one bullet because you have a firing_delay varaible which prevents multiple bullets from being created more than once every 8 steps. There is no such delay for the arm code, so one mouse click is likely lasting 2 to 4 steps, thus creating multiple arms. The solution is NOT to add a firing delay to the arm, by the way. Maybe you have it in the code, but where do you destroy the arm after it has been created? If the idea is to show the arm holding a gun only when the mouse button is pressed, then you would use mouse_check_button_pressed() to create the arm and mouse_check_button_released() to destroy the arm.
 

ETHC33

Member
okay, i thought var took care of that but i'll definitely look into it. Really sorry about the messy code.

another wierd thing is that when i change the sprite index for (obj_pistol_bullet) it creates two but when it is the same sprite as the rifle bullet it only creates one.
 

ETHC33

Member
i destroy the arm in the arm in the step event with

if (mouse_check_button_released(mb_right))
{
instance_destroy();
}
 

TheouAegis

Member
okay, i thought var took care of that but i'll definitely look into it. Really sorry about the messy code.

another wierd thing is that when i change the sprite index for (obj_pistol_bullet) it creates two but when it is the same sprite as the rifle bullet it only creates one.
You are getting 2 bullets even though you have 1 arm, now? Are you sure you didn't accidentally put code to create the bullet inside another object? Did you check your instance count in the Debugger to make sure you don't also have 2 of the instance running this code?

Also, are you sure obj_pistol_bullet's sprite isn't messed up and it just looks like 2 bullets?
 

GarbageHaus

Member
Yeah that's gotten me too. Another way to quickly get around this is to just check to see if the instance already exists using something like:
GML:
if !instance_exists(Obj_arm) /*Optional && condition here*/ {
//Your code here
}
 

TheouAegis

Member
You shouldn't have needed to use the Pressed Junction, though. You're told that you posted originally required firing delay to be zero or less oh, and as soon as you created a bullet you said it 2/8, which would have prevented any more bullets from being created for eight steps.
 
Top