Two types of weapons - and their different behavior

Imiglikos

Member
Hello,

I have a weapon swap system ... but the current behavior of each weapon is the same ...
I would like to change it a bit ...

1.The first primary weapon is the ball that the hero shoots.
I would like to achieve this effect on this weapon ..
when the hero shots once every time, a different ball should come out ... I mean a different color of it ...
each of these balls has the same animation in several sprites ..
when it hits an enemy it destroys and splashes ..
Each weapon should have a distance ... balls should be destroyed on some distance if there is no enemy and obstacles ... the same is weapon lightning / thunder

I described it in the picture below

ball weapon.png


2.The next weapon is lightning / thunder

when the hero fires this weapon, it creates lightning /thunder at some distance .. And if there is an enemy or several enemies at this distance, each of them will receive damage

I also described it in the picture below


thunder.png


This is what my weapon swap system looks like in the code

obj_game

create

GML:
enum e_wep { have,ammo,firerate,dmg_min,dmg_max,ammo_type,name,ammo_sound }
enum e_gun   { ball,thunder,shotgun,blue_laser,ice }



weapons_total = 5;
current_weapon = 0;




var i = 0;


//basic weapon
global.wep[0 ,e_wep.ammo_type] = obj_ball;
global.wep[0, e_wep.have] = true;
global.wep[0 ,e_wep.ammo] = -1; //endless ammo
global.wep[0 ,e_wep.firerate] = 5;
global.wep[0 ,e_wep.dmg_min] = 3;
global.wep[0 ,e_wep.dmg_max] = 5;
global.wep[0 ,e_wep.name] = "ball";


//second weapon
global.wep[1 ,e_wep.ammo_type] = obj_thunder;
global.wep[1, e_wep.have] = false;
global.wep[1 ,e_wep.ammo] = 30;
global.wep[1 ,e_wep.firerate] = 10;
global.wep[1 ,e_wep.dmg_min] = 3;
global.wep[1 ,e_wep.dmg_max] = 5;
global.wep[1 ,e_wep.name] = "thunder";


//third weapon
global.wep[2 ,e_wep.ammo_type] = obj_shotgun;
global.wep[2, e_wep.have] = false;
global.wep[2 ,e_wep.ammo] = 20;
global.wep[2 ,e_wep.firerate] = 15;
global.wep[2 ,e_wep.dmg_min] = 3;
global.wep[2 ,e_wep.dmg_max] = 5;
global.wep[2 ,e_wep.name] = "shotgun";


//fourth weapon
global.wep[3 ,e_wep.ammo_type] = obj_blue_laser;
global.wep[3, e_wep.have] = false;
global.wep[3 ,e_wep.ammo] = 10;
global.wep[3 ,e_wep.firerate] = 20;
global.wep[3 ,e_wep.dmg_min] = 3;
global.wep[3 ,e_wep.dmg_max] = 5;
global.wep[3 ,e_wep.name] = "blue_laser";


//fifth weapon
global.wep[4 ,e_wep.ammo_type] = obj_ice;
global.wep[4, e_wep.have] = false;
global.wep[4 ,e_wep.ammo] = 5;
global.wep[4 ,e_wep.firerate] = 25;
global.wep[4 ,e_wep.dmg_min] = 3;
global.wep[4 ,e_wep.dmg_max] = 5;
global.wep[4 ,e_wep.name] = "ice";

obj_hero

create

GML:
//variables for weapons
have = true;
ammo = 10;
firerate = 15;
dmg_min = 3;
dmg_max = 5;

damageClock = 0;
timeAttack = 0;
current_attack = 0;



step

GML:
var cur = obj_game.current_weapon; //the control object has the index of the current weapon, so we need to get it first

if keyboard_check_pressed(ord('X')) && timeAttack <= 0 && in_air=false &&
(global.wep[cur,e_wep.ammo] > 0 || global.wep[cur,e_wep.ammo] == -1) {
timeAttack = global.wep[cur,e_wep.firerate];

timeAttack = _attackClock;
current_attack =1;

with instance_create(x,y,par_attack) {

sprite_index = spr_hero_attack;
image_xscale = other.image_xscale;


}

    var box, ins;
    if image_xscale == -1
        box = bbox_left;
    else
        box = bbox_right;


if (global.wep[cur,e_wep.ammo] >= 1) // if not infinite ammo
{
global.wep[cur,e_wep.ammo]-=1;
}



var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
ins.hspeed = image_xscale * 15;
ins.dmg = irandom_range(global.wep[cur,e_wep.dmg_min],global.wep[cur,e_wep.dmg_max]);


   audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)
}

The code of the first weapon
for the second weapon the code is the same


obj_ball

create

GML:
owner = noone;
g = 0; //gravitation
f = 0; //flight parabola

step


GML:
image_angle=direction

draw

GML:
draw_sprite_ext(sprite_index, image_index, round(x), round(y), image_xscale, image_yscale, image_angle, image_blend, image_alpha);

enemy collision with weapon


GML:
 if damageClock == 0 {

  hp -= 3;
  damageClock = room_speed/2;

}
 
Last edited:

Nidoking

Member
Do you have some specific questions? How much of what you're talking about have you thought out and planned, and which parts are you having trouble with?
 

Imiglikos

Member
Do you have some specific questions? How much of what you're talking about have you thought out and planned, and which parts are you having trouble with?
I described everything in my post exactly what I mean ..

yes .... read my post carefully ... I wrote that I want to change the behavior of two types of weapons ..

My weapons work ... I have no problems with their operation ... they just each behave the same ...
And therefore 2 types chosen of weapons that behave the same want to change their behavior ...
 

TheouAegis

Member
var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
ins.hspeed = image_xscale * 15;
You're creating a generic bullet here, basically. You're saying ALL guns should make a bullet that moves 15 pixels per step. Your lightning gun doesn't work like that, though, does it? So you can't just create a generic bullet like that. The instance_create() line itself is fine. The issue is you need to check the ammo_type to decide what kind of code you are going to run.

Personally I would have the lightning gun create multiple lightning bullets evenly spaced apart using a loop. At your level, that would probably be the easiest. Each of those lightning bolts could then run its own collision code, also. It's not an ideal method, but it's probably the most beginner-friendly.
Code:
switch global.wep[cur,e_wep.ammo_type] {
    case lightning_ammo:
        var i = 0;
        repeat 10
            instance_create(box+image_xscale*(42+(i++)*16), y-17,global.wep[cur,e_wep.ammo_type] );
        break;

    case paintball_ammo:
       var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
        ins.hspeed = image_xscale * 15;
        ins.sprite_index = choose(spr_ball_red,spr_ball_green,spr_ball_blue,spr_ball_brown);
}
Replace the 10 with how many lightning bullets to create. Replace the 16 with how wide the lightning sprite is. The i++ will increment i, spacing out each of the lightning bullets.
As for your paintball bullets, the way I would handle it (actually, the way I'd do it isn't encouraged here....) is to just choose() a random sprite. Paintballs are randomly shot.

If you don't want them to be randomized, then add all the colored balls to an array in the Create Event. Then set a variable to irandom(3).
Code:
paintballs[0] = spr_ball_red;
paintballs[1] = spr_ball_green;
paintballs[2] = spr_ball_blue;
paintballs[3] = spr_ball_brown;
paintball_color = irandom(3);
Then instead of assigning a random sprite_index, set the sprite based on the array indexed by that variable. Then increase that variable and wrap it between 0 and 3.
Code:
ins.sprite_index = paintballs[paintball_color++];
paintball_color &= 3;
If bitwise & scares you, you can use
Code:
paintball_color = paintball_color mod 4;
 
Last edited:

Imiglikos

Member
TH
You're creating a generic bullet here, basically. You're saying ALL guns should make a bullet that moves 15 pixels per step. Your lightning gun doesn't work like that, though, does it? So you can't just create a generic bullet like that. The instance_create() line itself is fine. The issue is you need to check the ammo_type to decide what kind of code you are going to run.

Personally I would have the lightning gun create multiple lightning bullets evenly spaced apart using a loop. At your level, that would probably be the easiest. Each of those lightning bolts could then run its own collision code, also. It's not an ideal method, but it's probably the most beginner-friendly.
Code:
switch global.wep[cur,e_wep.ammo_type] {
    case lightning_ammo:
        var i = 0;
        repeat 10
            instance_create(box+image_xscale*(42+(i++)*16), y-17,global.wep[cur,e_wep.ammo_type] );
        break;

    case paintball_ammo:
       var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
        ins.hspeed = image_xscale * 15;
        ins.sprite_index = choose(spr_ball_red,spr_ball_green,spr_ball_blue,spr_ball_brown);
}
Replace the 10 with how many lightning bullets to create. Replace the 16 with how wide the lightning sprite is. The i++ will increment i, spacing out each of the lightning bullets.
As for your paintball bullets, the way I would handle it (actually, the way I'd do it isn't encouraged here....) is to just choose() a random sprite. Paintballs are randomly shot.

If you don't want them to be randomized, then add all the colored balls to an array in the Create Event. Then set a variable to irandom(3).
Code:
paintballs[0] = spr_ball_red;
paintballs[1] = spr_ball_green;
paintballs[2] = spr_ball_blue;
paintballs[3] = spr_ball_brown;
paintball_color = irandom(3);
Then instead of assigning a random sprite_index, set the sprite based on the array indexed by that variable. Then increase that variable and wrap it between 0 and 3.
Code:
ins.sprite_index = paintballs[paintball_color++];
paintball_color &= 3;
If bitwise & scares you, you can use
Code:
paintball_color = paintball_color mod 4;

Thank you,

Painball is already working ... this board is convenient ... although there is such a phenomenon ... I set 4 sprites, i.e. from 0 to 3, as in your example ... when I shoot, the painball sprite changes ... but it is often repeated in row the same color of the ball even though each is alternately set to a different color
I would like to set the distance at which the ball is to be destroyed ... now it only destroys itself when it touches a wall or an enemy ...



obj_ball


create

GML:
paintballs[0] = spr_ball_red;
paintballs[1] = spr_ball_green;
paintballs[2] = spr_ball_blue;
paintballs[3] = spr_ball_brown;


obj_hero

step

GML:
var cur = obj_game.current_weapon; //the control object has the index of the current weapon, so we need to get it first

if keyboard_check_pressed(ord('X')) && timeAttack <= 0 && in_air=false &&
(global.wep[cur,e_wep.ammo] > 0 || global.wep[cur,e_wep.ammo] == -1) {
timeAttack = global.wep[cur,e_wep.firerate];

timeAttack = _attackClock;
current_attack =1;

with instance_create(x,y,par_attack) {

sprite_index = spr_hero_attack;
image_xscale = other.image_xscale;


}

    var box, ins;
    if image_xscale == -1
        box = bbox_left;
    else
        box = bbox_right;


if (global.wep[cur,e_wep.ammo] >= 1) // if not infinite ammo
{
global.wep[cur,e_wep.ammo]-=1;
}



var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
ins.hspeed = image_xscale * 15;
ins.sprite_index = paintballs[irandom(3)];//balls
ins.dmg = irandom_range(global.wep[cur,e_wep.dmg_min],global.wep[cur,e_wep.dmg_max]);


   audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)
}

As for lightning weapons / thunder
I would have to add that part of the code that will create lightning / lightning also to the hero's step?
I can see that I am using the same code..and I also have other weapons that use this same code ..

GML:
var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
what about the field of fire of this weapon? I wanted to get the effect that lightning / thunder is created at the appropriate distance ...
if there will be, for example, 1 to 3 enemies next to each other, then each of the enemies is to take damage ...


obj_hero

step

GML:
if keyboard_check_pressed(ord('X')) && timeAttack <= 0 && in_air=false &&
(global.wep[cur,e_wep.ammo] > 0 || global.wep[cur,e_wep.ammo] == -1) {
timeAttack = global.wep[cur,e_wep.firerate];

timeAttack = _attackClock;
current_attack =1;

with instance_create(x,y,par_attack) {

sprite_index = spr_hero_attack;
image_xscale = other.image_xscale;


}

    var box, ins;
    if image_xscale == -1
        box = bbox_left;
    else
        box = bbox_right;


if (global.wep[cur,e_wep.ammo] >= 1) // if not infinite ammo
{
global.wep[cur,e_wep.ammo]-=1;
}


switch global.wep[cur,e_wep.ammo_type] {
    case lightning_ammo:
        var i = 0;
        repeat 10
            instance_create(box+image_xscale*(42+(i++)*16), y-17,global.wep[cur,e_wep.ammo_type] ); //will it not conflict with the same code below
        break;
}



var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
ins.hspeed = image_xscale * 15;
ins.sprite_index = paintballs[irandom(3)];//balls
ins.dmg = irandom_range(global.wep[cur,e_wep.dmg_min],global.wep[cur,e_wep.dmg_max]);






   audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)
}
 

Imiglikos

Member
You're creating a generic bullet here, basically. You're saying ALL guns should make a bullet that moves 15 pixels per step. Your lightning gun doesn't work like that, though, does it? So you can't just create a generic bullet like that. The instance_create() line itself is fine. The issue is you need to check the ammo_type to decide what kind of code you are going to run.

Personally I would have the lightning gun create multiple lightning bullets evenly spaced apart using a loop. At your level, that would probably be the easiest. Each of those lightning bolts could then run its own collision code, also. It's not an ideal method, but it's probably the most beginner-friendly.
Code:
switch global.wep[cur,e_wep.ammo_type] {
    case lightning_ammo:
        var i = 0;
        repeat 10
            instance_create(box+image_xscale*(42+(i++)*16), y-17,global.wep[cur,e_wep.ammo_type] );
        break;

    case paintball_ammo:
       var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
        ins.hspeed = image_xscale * 15;
        ins.sprite_index = choose(spr_ball_red,spr_ball_green,spr_ball_blue,spr_ball_brown);
}
Replace the 10 with how many lightning bullets to create. Replace the 16 with how wide the lightning sprite is. The i++ will increment i, spacing out each of the lightning bullets.
As for your paintball bullets, the way I would handle it (actually, the way I'd do it isn't encouraged here....) is to just choose() a random sprite. Paintballs are randomly shot.

If you don't want them to be randomized, then add all the colored balls to an array in the Create Event. Then set a variable to irandom(3).
Code:
paintballs[0] = spr_ball_red;
paintballs[1] = spr_ball_green;
paintballs[2] = spr_ball_blue;
paintballs[3] = spr_ball_brown;
paintball_color = irandom(3);
Then instead of assigning a random sprite_index, set the sprite based on the array indexed by that variable. Then increase that variable and wrap it between 0 and 3.
Code:
ins.sprite_index = paintballs[paintball_color++];
paintball_color &= 3;
If bitwise & scares you, you can use
Code:
paintball_color = paintball_color mod 4;

Ok i understand..
Thank you

Only weapon variables lightning_ammo and paintball_ammo are not recognized and an error pops up because I do not have them in the event create obj_hero only in obj_game in the event create
Obj_hero

Step

GML:
switch global.wep[cur,e_wep.ammo_type] {
    case lightning_ammo:
        var i = 0;
        repeat 10
            instance_create(box+image_xscale*(42+(i++)*16), y-17,global.wep[cur,e_wep.ammo_type] );
        break;

    case paintball_ammo:
       var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
        ins.hspeed = image_xscale * 15;
        ins.sprite_index = choose(spr_ball_red,spr_ball_green,spr_ball_blue,spr_ball_brown);
}

Obj_game


Create

GML:
obj_game

create

GML:
enum e_wep { have,ammo,firerate,dmg_min,dmg_max,ammo_type,name,ammo_sound }
enum e_gun   {  paintball_ammo , lightning_ammo ,shotgun,blue_laser,ice }



weapons_total = 5;
current_weapon = 0;




var i = 0;


//basic weapon
global.wep[0 ,e_wep.ammo_type] = obj_paintball;
global.wep[0, e_wep.have] = true;
global.wep[0 ,e_wep.ammo] = -1; //endless ammo
global.wep[0 ,e_wep.firerate] = 5;
global.wep[0 ,e_wep.dmg_min] = 3;
global.wep[0 ,e_wep.dmg_max] = 5;
global.wep[0 ,e_wep.name] = "paintball_ammo";


//second weapon
global.wep[1 ,e_wep.ammo_type] = obj_thunder;
global.wep[1, e_wep.have] = false;
global.wep[1 ,e_wep.ammo] = 30;
global.wep[1 ,e_wep.firerate] = 10;
global.wep[1 ,e_wep.dmg_min] = 3;
global.wep[1 ,e_wep.dmg_max] = 5;
global.wep[1 ,e_wep.name] = "lightning_ammo";


//third weapon
global.wep[2 ,e_wep.ammo_type] = obj_shotgun;
global.wep[2, e_wep.have] = false;
global.wep[2 ,e_wep.ammo] = 20;
global.wep[2 ,e_wep.firerate] = 15;
global.wep[2 ,e_wep.dmg_min] = 3;
global.wep[2 ,e_wep.dmg_max] = 5;
global.wep[2 ,e_wep.name] = "shotgun";


//fourth weapon
global.wep[3 ,e_wep.ammo_type] = obj_blue_laser;
global.wep[3, e_wep.have] = false;
global.wep[3 ,e_wep.ammo] = 10;
global.wep[3 ,e_wep.firerate] = 20;
global.wep[3 ,e_wep.dmg_min] = 3;
global.wep[3 ,e_wep.dmg_max] = 5;
global.wep[3 ,e_wep.name] = "blue_laser";


//fifth weapon
global.wep[4 ,e_wep.ammo_type] = obj_ice;
global.wep[4, e_wep.have] = false;
global.wep[4 ,e_wep.ammo] = 5;
global.wep[4 ,e_wep.firerate] = 25;
global.wep[4 ,e_wep.dmg_min] = 3;
global.wep[4 ,e_wep.dmg_max] = 5;
global.wep[4 ,e_wep.name] = "ice";
 
Last edited:

Imiglikos

Member
Those aren't variables, replace them with the name of your various ammo types.

so it has to be this way ... although there is no longer any error when I press the fire button, no projectile is formed on any of the weapons ...


GML:
if keyboard_check_pressed(ord('X')) && timeAttack <= 0 && in_air=false &&
(global.wep[cur,e_wep.ammo] > 0 || global.wep[cur,e_wep.ammo] == -1) {
timeAttack = global.wep[cur,e_wep.firerate];

timeAttack = _attackClock;
current_attack =1;

with instance_create(x,y,par_attack) {

sprite_index = spr_hero_attack;
image_xscale = other.image_xscale;


}

    var box, ins;
    if image_xscale == -1
        box = bbox_left;
    else
        box = bbox_right;


if (global.wep[cur,e_wep.ammo] >= 1) // if not infinite ammo
{
global.wep[cur,e_wep.ammo]-=1;
}


switch global.wep[cur,e_wep.ammo_type] {
    case e_gun.lightning_ammo:
        var i = 0;
        repeat 10
            instance_create(box+image_xscale*(42+(i++)*16), y-17,global.wep[cur,e_wep.ammo_type] );
           
            audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)
           
        break;

    case e_gun.paintball_ammo:
       var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
        ins.hspeed = image_xscale * 15;
        ins.sprite_index = choose(spr_ball_red,spr_ball_green,spr_ball_blue,spr_ball_brown);
       
       
        audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)
       
        break;
       
       
       
   case e_gun.shotgun:
         var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
         ins.hspeed = image_xscale * 15;
         ins.dmg = irandom_range(global.wep[cur,e_wep.dmg_min],global.wep[cur,e_wep.dmg_max]);
       
         audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)
       
        break;
       
       
    case e_gun.blue_laser:
         var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
         ins.hspeed = image_xscale * 15;
         ins.dmg = irandom_range(global.wep[cur,e_wep.dmg_min],global.wep[cur,e_wep.dmg_max]);
       
         audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)
       
        break;
       
       
   case e_gun.ice:
         var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
         ins.hspeed = image_xscale * 15;
         ins.dmg = irandom_range(global.wep[cur,e_wep.dmg_min],global.wep[cur,e_wep.dmg_max]);
       
         audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)
       
        break;
       
       
}


/*
var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
ins.hspeed = image_xscale * 15;
ins.sprite_index = paintballs[irandom(3)];//balls
ins.dmg = irandom_range(global.wep[cur,e_wep.dmg_min],global.wep[cur,e_wep.dmg_max]);
audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)
*/

}
 

TheouAegis

Member
You don't want to use e_gun.lightning_ammo in that code. You would want to use obj_thunder, or obj_ball. Your array defines e_wep.ammo_type as the object created for that gun's ammo. If you use the switch to check that value, you need to check what object e_wep.ammo_type is. Otherwise, you can have the switch check what the value of current_weapon is and then your switch should be fine.
 

Imiglikos

Member
You don't want to use e_gun.lightning_ammo in that code. You would want to use obj_thunder, or obj_ball. Your array defines e_wep.ammo_type as the object created for that gun's ammo. If you use the switch to check that value, you need to check what object e_wep.ammo_type is. Otherwise, you can have the switch check what the value of current_weapon is and then your switch should be fine.
Yes, but when i weapon name is defined like this

an error pops up when you press the action button ..
because weapons with such names do not exist in obj_hero ..
I have arrays in obj_game

unless I need to define some variables in the create event of these two weapons

GML:
switch global.wep[cur,e_wep.ammo_type] {
    case lightning_ammo:
        var i = 0;
        repeat 10
            instance_create(box+image_xscale*(42+(i++)*16), y-17,global.wep[cur,e_wep.ammo_type] );
        break;

    case paintball_ammo:
       var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
        ins.hspeed = image_xscale * 15;
        ins.sprite_index = choose(spr_ball_red,spr_ball_green,spr_ball_blue,spr_ball_brown);
}





Edit

wait..the "case" must have the name of the weapon objects..not the variable you mentioned this ..
or

e.g. yes

obj_paintball and obj_thunder

Yes?




switch global.wep[cur,e_wep.ammo_type] {
case obj_thunder:
var i = 0;
repeat 10
instance_create(box+image_xscale*(42+(i++)*16), y-17,global.wep[cur,e_wep.ammo_type] );
break;

case obj_paintball:
var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
ins.hspeed = image_xscale * 15;
ins.sprite_index = choose(spr_ball_red,spr_ball_green,spr_ball_blue,spr_ball_brown);
}
 
Last edited:

Imiglikos

Member
you are using my PAID code. But you did not pay me. I know you very well.
what code is payable ??? if you have any problem, contact the administrator and let him look for a man who did not pay you .. Don't accuse me of something I didn't do ..
one more post and I will report the matter to the administrator about stalking ... I don't know you ..
 

Imiglikos

Member
You don't want to use e_gun.lightning_ammo in that code. You would want to use obj_thunder, or obj_ball. Your array defines e_wep.ammo_type as the object created for that gun's ammo. If you use the switch to check that value, you need to check what object e_wep.ammo_type is. Otherwise, you can have the switch check what the value of current_weapon is and then your switch should be fine.

ok it finally works..the question i have..I have a similar sprite like here in the picture.. it behaves in the same way..The player will shoot a lightning and there is an animated lightning bolt ... the player presses the action button
and there should be lightning like this ...
sprite has 32 pictures of animation

giphy.gif


and how to make the field of fire, when several enemies are within the range of lightning, also take damage ...

this is what the code in the thunder weapon looks like ..


obj_thunder


step

GML:
image_angle=direction

animation end

GML:
instance_destroy();
draw

GML:
draw_sprite_ext(sprite_index, image_index, round(x), round(y), image_xscale, image_yscale, image_angle, image_blend, image_alpha);


and obj_hero

step



GML:
switch global.wep[cur,e_wep.ammo_type] {
    case obj_thunder:
        var i = 0;
        repeat 10
            instance_create(box+image_xscale*(42+(i++)*16), y-17,global.wep[cur,e_wep.ammo_type] );
        break;
 

TheouAegis

Member
So first off, the "16" in the instance_create() would need to be changed to the width of that sprite. And you need to change the "repeat 10" so the beam extends out however far you want it.

I would set the image_index=irandom(image_number-1) in the Create event of obj_thunder. It should make it look a little nicer.

For damage, you could give the parent object of all enemies a Collision Event with obj_thunder. This is the simplest method to implement since you already have code for it.
 

Imiglikos

Member
So first off, the "16" in the instance_create() would need to be changed to the width of that sprite. And you need to change the "repeat 10" so the beam extends out however far you want it.

I would set the image_index=irandom(image_number-1) in the Create event of obj_thunder. It should make it look a little nicer.

For damage, you could give the parent object of all enemies a Collision Event with obj_thunder. This is the simplest method to implement since you already have code for it.

I'm trying to set the lightning sprite according to the guidelines ... but it does not work out as it should
I set it according to the instructions .. because my sprite has a width of 8 and a height of 3 and is in 5 pictures of the animation

if I do not give the option animation end -instance_destroy (), my sprite does not disappear and stays on the board .. But if I give this option, my sprite is not visible, only as if it was generated only from code ..

this is my obj_thunder weapon code


obj_thunder

create

GML:
image_index = irandom (image_number-1)

GML:
image_angle=direction


if distance_to_point(obj_hero.x,obj_hero.y) > 400
{
       instance_destroy();
}

draw

GML:
draw_sprite_ext( sp_thunder, 5, x, y, 1, 1, 0, -1, 1 );

coliision with obj_wall

GML:
instance_destroy();

and the second thing ... when setting one enemy's damage no problem..it works very well on my code..but when two or three enemies are standing side by side and each one is within the range of the lightning
only the first enemy gets damage .. and the other enemies do not


obj_hero

step

GML:
switch global.wep[cur,e_wep.ammo_type] {
    case obj_thunder:
        var i = 0;
        repeat 30
            instance_create(box+image_xscale*(42+(i++)*8), y-17,global.wep[cur,e_wep.ammo_type] );
        break;
 

Yal

🐧 *penguin noises*
GMC Elder
For obj_ball, you can give it random colors using image_blend:
GML:
image_blend = make_color_hsv(irandom(255),irandom(255),irandom(255))
Just color the ball's sprite white and image_blend will take care of the rest. When the ball is destroyed, create a splash effect (which is also white) and carry over the blend color:
GML:
n = instance_create_depth(x,y,depth,obj_splasheffect)
n.image_blend = image_blend
 

TheouAegis

Member
First off, remove the Draw event in obj_thunder. Your sprite won't animate with that code.

Second, remove the distance_to_object() check. Either the lightning needs to follow the player, or it exists on its own.

For making obj_thunder kill itself, set an alarm in obj_thunder to something like room_speed/2, or however long you want the lightning to exist. Then in that alarm event, destroy the lightning.

The Animation End event doesn't work because the image_index can be 5 upon creation, so the thunder would be destroyed immediately.

And you need to post the code for your enemy's collision event with obj_thunder, because what you are describing is not what would happen unless you have a syntax error.
 

Imiglikos

Member
First off, remove the Draw event in obj_thunder. Your sprite won't animate with that code.

Second, remove the distance_to_object() check. Either the lightning needs to follow the player, or it exists on its own.

For making obj_thunder kill itself, set an alarm in obj_thunder to something like room_speed/2, or however long you want the lightning to exist. Then in that alarm event, destroy the lightning.

The Animation End event doesn't work because the image_index can be 5 upon creation, so the thunder would be destroyed immediately.

And you need to post the code for your enemy's collision event with obj_thunder, because what you are describing is not what would happen unless you have a syntax error.

here is the enemy collision code with obj_thunder


GML:
 if damageClock == 0 {

  hp -= 3;
  damageClock = room_speed/2;

}

destroy instances



You mention to set the alarm in this way room_speed / 2 should I declare this value in create obj_thunder? and the alarm [0] set instance_destroy?

obj_thunder

create

GML:
image_index = irandom (image_number-1)
alarm[0] = room_speed/2;
alarm[0]

GML:
instance_destroy();
step

GML:
image_angle=direction

obj_thunder collision with the obj_enemy


GML:
 if damageClock == 0 {

  hp -= 3;
  damageClock = room_speed/2;

}

destroy instances

obj_thunder collision with the obj_wall

GML:
instance_destroy();
 

TheouAegis

Member
Yeah that looks right.

Does the enemy collision also work better now that you have the alarm destroying obj_thunder?

if damageClock == 0 {
hp -= 3;
damageClock = room_speed/2;
}
Just wanted to verify, this code is inside your enemy only right? Not inside obj_thunder?
 

Imiglikos

Member
Yeah that looks right.

Does the enemy collision also work better now that you have the alarm destroying obj_thunder?


Just wanted to verify, this code is inside your enemy only right? Not inside obj_thunder?

this code is only in the obj_enemy object

in enemy collision with obj_thunder

GML:
/*
if other.owner == obj_hero { // this code will not work only for the obj_thunder weapon because there is no local variable "ins" defined
with other {
  instance_destroy();
}
*/


if damageClock == 0 {
hp -= 3;
damageClock = room_speed/2;
}
this is how it works ... enemy takes damage from obj_thunder ... but when another enemy stands next to that enemy, behind that enemy ... only the first enemy takes damage ... and I wish the other enemy could take damage at the same time ...


obj_thunder damage.png

as for the animation obj_thunder..to still does not display properly ..
i tried to change room_speed / 2 to room_speed / 10 but it doesn't help ... I can't even see the lightning sprite


obj_thunder

create

GML:
image_index = irandom (image_number-1)
alarm[0] = room_speed/2;

alarm[0]

GML:
instance_destroy();

step

GML:
image_angle=direction

in enemy collision with obj_thunder

GML:
if damageClock == 0 {
hp -= 3;
damageClock = room_speed/2;
}

obj_thunder collision with the obj_wall


GML:
instance_destroy();

obj_hero

step


GML:
if keyboard_check_pressed(ord('X')) && timeAttack <= 0 && in_air=false &&
(global.wep[cur,e_wep.ammo] > 0 || global.wep[cur,e_wep.ammo] == -1) {
timeAttack = global.wep[cur,e_wep.firerate];

timeAttack = _attackClock;
current_attack =1;

with instance_create(x,y,par_attack) {

sprite_index = spr_hero_attack;
image_xscale = other.image_xscale;


}

    var box, ins;
    if image_xscale == -1
        box = bbox_left;
    else
        box = bbox_right;


if (global.wep[cur,e_wep.ammo] >= 1) // if not infinite ammo
{
global.wep[cur,e_wep.ammo]-=1;
}


switch global.wep[cur,e_wep.ammo_type] {
    case obj_thunder:
        var i = 0;
        repeat 10
            instance_create(box+image_xscale*(42+(i++)*8), y-17,global.wep[cur,e_wep.ammo_type] );
            audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)
     
        break;

    case obj_paintball:
       var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
        ins.hspeed = image_xscale * 15;
        ins.sprite_index = paintballs[paintball_color++];
        paintball_color &= 3;
        ins.owner = obj_hero;
        audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)
 
        break;
 
 
 
   case obj_shotgun:
         var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
         ins.hspeed = image_xscale * 15;
         ins.dmg = irandom_range(global.wep[cur,e_wep.dmg_min],global.wep[cur,e_wep.dmg_max]);
         ins.owner = obj_hero;
         audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)
 
        break;
 
 
    case obj_blue_laser:
         var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
         ins.hspeed = image_xscale * 15;
         ins.dmg = irandom_range(global.wep[cur,e_wep.dmg_min],global.wep[cur,e_wep.dmg_max]);
         ins.owner = obj_hero;
         audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)
 
        break;
 
 
   case obj_ice:
         var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
         ins.hspeed = image_xscale * 15;
         ins.dmg = irandom_range(global.wep[cur,e_wep.dmg_min],global.wep[cur,e_wep.dmg_max]);
         ins.owner = obj_hero
         audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)
 
        break;
 
 
}

  }
 
Last edited:

TheouAegis

Member
You don't want /10. That makes the thunder destroy itself faster. Try room_speed, or even room_speed*3/2. But keep in mind the higher the alarm value, the higher timeAttack will need to be so the player isn't creating hundreds of obk_thunder per second. Also, the higher the alarm, the longer the enemy's damageClock would need to be as well so that one obj_thunder doesn't hit an enemy too often.

Are you sure the animation issue"s not just an issue with how your sprite is drawn? Comment out the image_index=irandom(image_number-1) and see if that's what you are referring to.

Is obj_thunder being destroyed when it collides with an enemy? The only thing destroying obj_thunder should be obj_thunder's alarm or when it collides with a wall. There's no reason for obj_thunder to only collide with one instance. Or do you mean you want the attack to branch out to the next enemy if one is close enough? That opens up so many questions about what you want the actual mechanics of the gun to be.
 

Imiglikos

Member
You don't want /10. That makes the thunder destroy itself faster. Try room_speed, or even room_speed*3/2. But keep in mind the higher the alarm value, the higher timeAttack will need to be so the player isn't creating hundreds of obk_thunder per second. Also, the higher the alarm, the longer the enemy's damageClock would need to be as well so that one obj_thunder doesn't hit an enemy too often.

Are you sure the animation issue"s not just an issue with how your sprite is drawn? Comment out the image_index=irandom(image_number-1) and see if that's what you are referring to.

Is obj_thunder being destroyed when it collides with an enemy? The only thing destroying obj_thunder should be obj_thunder's alarm or when it collides with a wall. There's no reason for obj_thunder to only collide with one instance. Or do you mean you want the attack to branch out to the next enemy if one is close enough? That opens up so many questions about what you want the actual mechanics of the gun to be.

Exactly yes i want that the attack branches to the next enemy if it's close enough (in the scope of obj_thunder)
if I remove the sprite drawing code from the draw event ... sprite is not created it is invisible ...

if I turn on this code event draw, sprite is created ... destroying obj_thunder also works ...
the problem, however, occurs on enemies..and on obj_wall because you cannot see this sprite..the fact is that the sprite only has 5 image frames ... but it should work normally..and the sprite should show up


this is what the code obj_thunder looks like now


obj_thunder

create

GML:
image_index = irandom (image_number-1)
alarm[0] = room_speed*3/2;
Alarm[0]

GML:
instance_destroy();

step

GML:
image_angle=direction

collision obj_thunder with obj_wall

GML:
instance_destroy();

outside room

GML:
instance_destroy();

draw


GML:
draw_sprite_ext( spr_thunder, 5, x, y, 1, 1, 0, -1, 1 );//I turned on this code ... because if I turn it off it doesn't create a sprite thunder

enemy collision with obj_thunder


GML:
/*
if other.owner == obj_hero { // this code will not work only for the obj_thunder weapon because there is no local variable "ins" defined
with other {
  instance_destroy();
}
*/


if damageClock == 0 {
hp -= 3;
damageClock = room_speed/2;
}
DnD block
GML:
destroy the instance - obj_thunder

obj_hero

step

GML:
if keyboard_check_pressed(ord('X')) && timeAttack <= 0 && in_air=false &&
(global.wep[cur,e_wep.ammo] > 0 || global.wep[cur,e_wep.ammo] == -1) {
timeAttack = global.wep[cur,e_wep.firerate];

timeAttack = _attackClock;
current_attack =1;

with instance_create(x,y,par_attack) {

sprite_index = spr_hero_attack;
image_xscale = other.image_xscale;


}

    var box, ins;
    if image_xscale == -1
        box = bbox_left;
    else
        box = bbox_right;


if (global.wep[cur,e_wep.ammo] >= 1) // if not infinite ammo
{
global.wep[cur,e_wep.ammo]-=1;
}


switch global.wep[cur,e_wep.ammo_type] {
    case obj_thunder:
        var i = 0;
        repeat 10
            instance_create(box+image_xscale*(42+(i++)*8), y-17,global.wep[cur,e_wep.ammo_type] );
            audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)
   
        break;

    case obj_paintball:
       var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
        ins.hspeed = image_xscale * 15;
        ins.sprite_index = paintballs[paintball_color++];
        paintball_color &= 3;
        ins.owner = obj_hero;
        audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)

        break;



   case obj_shotgun:
         var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
         ins.hspeed = image_xscale * 15;
         ins.dmg = irandom_range(global.wep[cur,e_wep.dmg_min],global.wep[cur,e_wep.dmg_max]);
         ins.owner = obj_hero;
         audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)

        break;


    case obj_blue_laser:
         var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
         ins.hspeed = image_xscale * 15;
         ins.dmg = irandom_range(global.wep[cur,e_wep.dmg_min],global.wep[cur,e_wep.dmg_max]);
         ins.owner = obj_hero;
         audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)

        break;


   case obj_ice:
         var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
         ins.hspeed = image_xscale * 15;
         ins.dmg = irandom_range(global.wep[cur,e_wep.dmg_min],global.wep[cur,e_wep.dmg_max]);
         ins.owner = obj_hero
         audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)

        break;


}

  }
 

Imiglikos

Member
You don't want /10. That makes the thunder destroy itself faster. Try room_speed, or even room_speed*3/2. But keep in mind the higher the alarm value, the higher timeAttack will need to be so the player isn't creating hundreds of obk_thunder per second. Also, the higher the alarm, the longer the enemy's damageClock would need to be as well so that one obj_thunder doesn't hit an enemy too often.

Are you sure the animation issue"s not just an issue with how your sprite is drawn? Comment out the image_index=irandom(image_number-1) and see if that's what you are referring to.

Is obj_thunder being destroyed when it collides with an enemy? The only thing destroying obj_thunder should be obj_thunder's alarm or when it collides with a wall. There's no reason for obj_thunder to only collide with one instance. Or do you mean you want the attack to branch out to the next enemy if one is close enough? That opens up so many questions about what you want the actual mechanics of the gun to be.

I can't think of how to solve it ..
 

TheouAegis

Member
My other post didn't show up... Odd.


draw_sprite_ext( spr_thunder, 5, x, y, 1, 1, 0, -1, 1 );
Change the 5 to -1 in order for it to animate.

Make sure spr_thunder is assigned as the sprite_index for obj_thunder. If sprite_index is not set, you won't see anything without a Draw event. Furthermore, if sprite_index isn't set, draw_sprite_ext() will not animate without your own animation code.

For jumping to nearby enemies, you need to find which enemies are in range of each enemy hit. The tricky part is preventing obj_thunder from stacking. The simplest one is if you want it to only branch straight ahead or straight back, no diagonals.
(Don't use this code, I typed it up on my phone and it needs to be edited)
Code:
case obj_thunder:
        var dir = image_xscale;
        var branches = 4;
        var minimum = 10;
        var range = 8 * (minimum - 2);
        var i = 0;
        repeat minimum
        with instance_create(b+dir*(42+(i++)*8), y-17,global.wep[cur,e_wep.ammo_type] )
            if i == 10 {
                var next = id;
                var dis = room_width;
                var jumpto = noone;
                var n,k;
                while branches (
                    with enemy {
                        n = x - other.x;
                        if sign(n) == dir && abs(n) < dis && abs(n) < range {
                            dis = n;
                            jumpto = id;
                        }
                        if jumpto != noone {
                            k = abs(jumpto.x - x) div 8 * 8;
                            repeat k
                                with instance_create(x+dir*(i++)*8, y,global.wep[cur,e_wep.ammo_type] ) {
                                    if --k == 0 {
                                        next = id;
                                        branches--;
                                    }
                                }
                            }
                        }
                    }
                }
        audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false);
      
        break;
 

Imiglikos

Member
My other post didn't show up... Odd.




Change the 5 to -1 in order for it to animate.

Make sure spr_thunder is assigned as the sprite_index for obj_thunder. If sprite_index is not set, you won't see anything without a Draw event. Furthermore, if sprite_index isn't set, draw_sprite_ext() will not animate without your own animation code.

For jumping to nearby enemies, you need to find which enemies are in range of each enemy hit. The tricky part is preventing obj_thunder from stacking. The simplest one is if you want it to only branch straight ahead or straight back, no diagonals.
(Don't use this code, I typed it up on my phone and it needs to be edited)
Code:
case obj_thunder:
        var dir = image_xscale;
        var branches = 4;
        var minimum = 10;
        var range = 8 * (minimum - 2);
        var i = 0;
        repeat minimum
        with instance_create(b+dir*(42+(i++)*8), y-17,global.wep[cur,e_wep.ammo_type] )
            if i == 10 {
                var next = id;
                var dis = room_width;
                var jumpto = noone;
                var n,k;
                while branches (
                    with enemy {
                        n = x - other.x;
                        if sign(n) == dir && abs(n) < dis && abs(n) < range {
                            dis = n;
                            jumpto = id;
                        }
                        if jumpto != noone {
                            k = abs(jumpto.x - x) div 8 * 8;
                            repeat k
                                with instance_create(x+dir*(i++)*8, y,global.wep[cur,e_wep.ammo_type] ) {
                                    if --k == 0 {
                                        next = id;
                                        branches--;
                                    }
                                }
                            }
                        }
                    }
                }
        audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false);
   
        break;

I figured your second post might not have appeared ... maybe because quite a bit of this post has already happened

You mean obj_thunder must have spr_thunder set .. it cannot be an empty object
it yes spr_thunder is assigned as sprite_index for obj_thunder
I just want the thunder weapon to branch straight ahead .. not backwards and not diagonally ..

Ok this is what the code in obj_thunder looks like after your advice .. animation works ok ... but when I shoot at the wall or at the enemy I can't see sprite spr_thunder ... but if I shoot in a place where there is no obstacle, everything is clearly visible ..
There is also a phenomenon where the hero shoots a lightning bolt and I make a move, then the lightning bolt is at the point of the shot ...


obj_thunder


create

GML:
image_index = irandom (image_number-1)
alarm[0] = room_speed*3/2;
sprite_index = spr_thunder;

alarm[0]

GML:
instance_destroy();

step

GML:
image_angle=direction
obj_thunder collision with obj_wall

GML:
instance_destroy();
draw

GML:
draw_sprite_ext( spr_thunder, -1, x, y, 1, 1, 0, -1, 1 );


enemy collision with obj_thunder

GML:
/*
if other.owner == obj_hero { // this code will not work only for the obj_thunder weapon because there is no local variable "ins" defined
with other {
  instance_destroy();
}
*/


if damageClock == 0 {
hp -= 3;
damageClock = room_speed/2;
}

DnD block

GML:
destroy the instance - obj_thunder

obj_hero

step

GML:
if keyboard_check_pressed(ord('X')) && timeAttack <= 0 && in_air=false &&
(global.wep[cur,e_wep.ammo] > 0 || global.wep[cur,e_wep.ammo] == -1) {
timeAttack = global.wep[cur,e_wep.firerate];

timeAttack = _attackClock;
current_attack =1;

with instance_create(x,y,par_attack) {

sprite_index = spr_hero_attack;
image_xscale = other.image_xscale;


}

    var box, ins;
    if image_xscale == -1
        box = bbox_left;
    else
        box = bbox_right;


if (global.wep[cur,e_wep.ammo] >= 1) // if not infinite ammo
{
global.wep[cur,e_wep.ammo]-=1;
}


switch global.wep[cur,e_wep.ammo_type] {
    case obj_thunder:
        var i = 0;
        repeat 10
            instance_create(box+image_xscale*(42+(i++)*8), y-17,global.wep[cur,e_wep.ammo_type] );
            audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)

        break;

    case obj_paintball:
       var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
        ins.hspeed = image_xscale * 15;
        ins.sprite_index = paintballs[paintball_color++];
        paintball_color &= 3;
        ins.owner = obj_hero;
        audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)

        break;



   case obj_shotgun:
         var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
         ins.hspeed = image_xscale * 15;
         ins.dmg = irandom_range(global.wep[cur,e_wep.dmg_min],global.wep[cur,e_wep.dmg_max]);
         ins.owner = obj_hero;
         audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)

        break;


    case obj_blue_laser:
         var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
         ins.hspeed = image_xscale * 15;
         ins.dmg = irandom_range(global.wep[cur,e_wep.dmg_min],global.wep[cur,e_wep.dmg_max]);
         ins.owner = obj_hero;
         audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)

        break;


   case obj_ice:
         var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
         ins.hspeed = image_xscale * 15;
         ins.dmg = irandom_range(global.wep[cur,e_wep.dmg_min],global.wep[cur,e_wep.dmg_max]);
         ins.owner = obj_hero
         audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)

        break;


}

  }
 
Last edited:

woods

Member
enemy collision with obj_thunder
DnD block
destroy the instance - obj_thunder


obj_thunder collision with obj_wall
instance_destroy();




===========
you are destroying the instance of obj_thunder as soon as it is created (if it touches the enemy or the wall)??
 

TheouAegis

Member
Destroying obj_thunder when it hits the wall makes sense. destroying it when it hits the enemy doesn't make sense because the enemy needs to be shown to be electrocuted. You have the alarm inside obj_thunder so that you can see it play through its entire animation, ideally, and you have the damageClock inside the enemy so that the enemy doesn't continually take damage while obj_thunder is on top of it.

if you want it to be destroyed when it hits the wall but still be visible for a second, then instead of destroying obj_thunder inside the wall collision, change obj_thunder's alarm so it lasts for only 2 steps instead of whatever it's set to.

collision with obj_wall event
Code:
if alarm[0] > 2
    alarm[0] = 2;
If you mean the issue is obj_thundet appears to pass through the wall because your wall is not as thick as the full range of obj_thunder, then what you need to do is have the player check if there is a wall where it creates a new obj_thunder and if so, break the loop(s) creating obj_thunder. I will have to edit that into the code I drafted up last night.
 

Imiglikos

Member
Destroying obj_thunder when it hits the wall makes sense. destroying it when it hits the enemy doesn't make sense because the enemy needs to be shown to be electrocuted. You have the alarm inside obj_thunder so that you can see it play through its entire animation, ideally, and you have the damageClock inside the enemy so that the enemy doesn't continually take damage while obj_thunder is on top of it.

if you want it to be destroyed when it hits the wall but still be visible for a second, then instead of destroying obj_thunder inside the wall collision, change obj_thunder's alarm so it lasts for only 2 steps instead of whatever it's set to.

collision with obj_wall event
Code:
if alarm[0] > 2
    alarm[0] = 2;
If you mean the issue is obj_thundet appears to pass through the wall because your wall is not as thick as the full range of obj_thunder, then what you need to do is have the player check if there is a wall where it creates a new obj_thunder and if so, break the loop(s) creating obj_thunder. I will have to edit that into the code I drafted up last night.

Ok, i did that way..as you wrote ..
Now, when I shoot an enemy, the thunder weapon does not disappear immediately, only after the set time .. Same on the object obj_wall


But still has the following problem:

1.If I shoot a lightning weapon at an enemy or against a wall, the weapon should destroyed
2.When I shoot a thunder gun and make a move, the weapon stays in place. ... Probably because when the lightning bolt is fired, the animated bolt of lightning should follow the player as he moves hero
3.What you mentioned the issue is obj_thunder appears to pass through the wall because my wall is not as thick as the full range of obj_thunder, and this phenomenon also occurs here

I don't know if I was supposed to use this code, what you sent me in the previous post, obj_hero-step .. I see that there is no local variable b and no local variable enemy .. so I haven't used that code anymore

this is what my code looks like now.

obj_thunder

create

GML:
image_index = irandom (image_number-1)
alarm[0] = room_speed*3/2;
sprite_index = spr_thunder;

alarm[0]

GML:
instance_destroy();
step


GML:
image_angle=direction

obj_thunder collision with obj_wall

GML:
if alarm[0] > 2
    alarm[0] = 2;

draw

GML:
draw_sprite_ext( spr_thunder, -1, x, y, 1, 1, 0, -1, 1 );

enemy collision with obj_thunder


GML:
/*
if other.owner == obj_hero { // this code will not work only for the obj_thunder weapon because there is no local variable "ins" defined
with other {
  instance_destroy();
}
*/


if damageClock == 0 {
hp -= 3;
damageClock = room_speed/2;
}

if alarm[0] > 2
    alarm[0] = 2;

obj_enemy


alarm[0]

GML:
instance_destroy();

obj_hero

step


GML:
if keyboard_check_pressed(ord('X')) && timeAttack <= 0 && in_air=false &&
(global.wep[cur,e_wep.ammo] > 0 || global.wep[cur,e_wep.ammo] == -1) {
timeAttack = global.wep[cur,e_wep.firerate];

timeAttack = _attackClock;
current_attack =1;

with instance_create(x,y,par_attack) {

sprite_index = spr_hero_attack;
image_xscale = other.image_xscale;


}

    var box, ins;
    if image_xscale == -1
        box = bbox_left;
    else
        box = bbox_right;


if (global.wep[cur,e_wep.ammo] >= 1) // if not infinite ammo
{
global.wep[cur,e_wep.ammo]-=1;
}


switch global.wep[cur,e_wep.ammo_type] {
    case obj_thunder:
        var i = 0;
        repeat 10
            instance_create(box+image_xscale*(42+(i++)*8), y-17,global.wep[cur,e_wep.ammo_type] );
            audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)

        break;

    case obj_paintball:
       var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
        ins.hspeed = image_xscale * 15;
        ins.sprite_index = paintballs[paintball_color++];
        paintball_color &= 3;
        ins.owner = obj_hero;
        audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)

        break;



   case obj_shotgun:
         var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
         ins.hspeed = image_xscale * 15;
         ins.dmg = irandom_range(global.wep[cur,e_wep.dmg_min],global.wep[cur,e_wep.dmg_max]);
         ins.owner = obj_hero;
         audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)

        break;


    case obj_blue_laser:
         var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
         ins.hspeed = image_xscale * 15;
         ins.dmg = irandom_range(global.wep[cur,e_wep.dmg_min],global.wep[cur,e_wep.dmg_max]);
         ins.owner = obj_hero;
         audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)

        break;


   case obj_ice:
         var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
         ins.hspeed = image_xscale * 15;
         ins.dmg = irandom_range(global.wep[cur,e_wep.dmg_min],global.wep[cur,e_wep.dmg_max]);
         ins.owner = obj_hero
         audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)

        break;


}

  }
 
Last edited:

TheouAegis

Member
The b was supposed to be box. I had changed my code up and then changed it back. I forgot to fix that. Thanks for pointing it out.

enemy is your enemy parent object.
 

Imiglikos

Member
The b was supposed to be box. I had changed my code up and then changed it back. I forgot to fix that. Thanks for pointing it out.

enemy is your enemy parent object.
No problem TheouAegis, thank you for your willingness to help :)

I corrected these variables well ... but now when I try to shoot a thunder gun my game stops ... I can't do anything ...
And I put some comments into the code ...


obj_hero

step


GML:
if keyboard_check_pressed(ord('X')) && timeAttack <= 0 && in_air=false &&
(global.wep[cur,e_wep.ammo] > 0 || global.wep[cur,e_wep.ammo] == -1) {
timeAttack = global.wep[cur,e_wep.firerate];

timeAttack = _attackClock;
current_attack =1;

with instance_create(x,y,par_attack) {

sprite_index = spr_hero_attack;
image_xscale = other.image_xscale;


}

    var box, ins;
    if image_xscale == -1
        box = bbox_left;
    else
        box = bbox_right;


if (global.wep[cur,e_wep.ammo] >= 1) // if not infinite ammo
{
global.wep[cur,e_wep.ammo]-=1;
}


switch global.wep[cur,e_wep.ammo_type] {

case obj_thunder:
        var dir = image_xscale;
        var branches = 4;
        var minimum = 10;
        var range = 8 * (minimum - 2);
        var i = 0;
        repeat minimum
        with instance_create(box+dir*(42+(i++)*8), y-17,global.wep[cur,e_wep.ammo_type] ) [B]// I corrected from local variable "b" to local variable "box"[/B]
            if i == 10 {
                var next = id;
                var dis = room_width;
                var jumpto = noone;
                var n,k;
                while branches {
                    with par_enemy { [B]//I have several parents for my enemies should I indicate several parents here ?? like this way with par_enemy  and par_type1 and par_type2 and par_type3 {[/B]
                        n = x - other.x;
                        if sign(n) == dir && abs(n) < dis && abs(n) < range {
                            dis = n;
                            jumpto = id;
                        }
                        if jumpto != noone {
                            k = abs(jumpto.x - x) div 8 * 8;
                            repeat k
                                with instance_create(x+dir*(i++)*8, y,global.wep[cur,e_wep.ammo_type] ) {
                                    if --k == 0 {
                                        next = id;
                                        branches--;
                                    }
                                }
                            }
                        }
                    }
                }
        audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false);
  
        break;


/* [B]// I disabled this code ...[/B]
    case obj_thunder:
        var i = 0;
        repeat 10
            instance_create(box+image_xscale*(42+(i++)*8), y-17,global.wep[cur,e_wep.ammo_type] );
            audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)

        break;
*/


    case obj_paintball:
       var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
        ins.hspeed = image_xscale * 15;
        ins.sprite_index = paintballs[paintball_color++];
        paintball_color &= 3;
        ins.owner = obj_hero;
        audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)

        break;



   case obj_shotgun:
         var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
         ins.hspeed = image_xscale * 15;
         ins.dmg = irandom_range(global.wep[cur,e_wep.dmg_min],global.wep[cur,e_wep.dmg_max]);
         ins.owner = obj_hero;
         audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)

        break;


    case obj_blue_laser:
         var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
         ins.hspeed = image_xscale * 15;
         ins.dmg = irandom_range(global.wep[cur,e_wep.dmg_min],global.wep[cur,e_wep.dmg_max]);
         ins.owner = obj_hero;
         audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)

        break;


   case obj_ice:
         var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
         ins.hspeed = image_xscale * 15;
         ins.dmg = irandom_range(global.wep[cur,e_wep.dmg_min],global.wep[cur,e_wep.dmg_max]);
         ins.owner = obj_hero
         audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)

        break;


}

  }
 
Last edited:

TheouAegis

Member
Code:
    case obj_thunder:
        var dir = image_xscale;
        var branches = 4;
        var minimum = 10;
        var range = 8 * (minimum - 2);
        var dis = room_width;
        var jumpto = noone;
        var brk = 0;
        var i = 0;
        var n,k;
        repeat minimum {    //create the minimum number of bolts
            with instance_create(box+dir*(42+(i++)*8), y-17,global.wep[cur,e_wep.ammo_type] ) {
                if place_meeting(x,y,obj_wall) {    //destroy a bolt if it spawns on a wall, stop the loop early
                    brk = 1;
                    instance_destroy();
                    break;
                }
                if i == 10 {    //have the last bolt deal with branching
                    var next = id;
                    while branches-- {    //search for the next enemy, up to the specified number of times
                        with next {     //perform the check from the last created enemy
                            with obj_enemy {    //loop through all enemies and find the nearest one to jump to
                                n = x - other.x;
                                if sign(n) == dir && abs(n) < dis && abs(n) < range {
                                    dis = n;
                                    jumpto = id;
                                }
                                if jumpto != noone {
                                    k = abs(jumpto.x - x) div 8;    //if an enemy is found, find how many bolts to create
                                    repeat k {  //create bolts toward the next enemy the same as before
                                        with instance_create(x+dir*(i++)*8, y,global.wep[cur,e_wep.ammo_type] ) {
                                            if place_meeting(x,y,obj_wall) {
                                                brk = 1;
                                                instance_destroy();
                                                break;
                                            }
                                            if --k == 0
                                                next = id;
                                        }
                                        if brk
                                            break;
                                    }
                                }
                                else {   //if no nearby enemies to jump to, stop the loop
                                    branches = 0;
                                    break;
                                 }
                            }
                        }
                    }
                }
            }
            if brk
                break;
        }
        audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false);
        break;
I didn't test the code, but it should have no syntax errors, at least. I changed enemy to obj_enemy to make it clearer what was intended there. I added comments also. I also tried to add conditions to destroy obj_thunder and prevent further obj_thunder from being created upon collision with obj_wall.
EDIT: my code might still freeze. I'm looking over your code and my code right now.
EDIT #2: I think I fixed the freezing condition. My best guess is branches was never getting reduced to 0. I fixed that in this code.

You can have the enemy destroy obj_thunder upon collision, but don't be shocked that you can't see obj_thunder on obj_enemy when you do that. If you want all obj_thunder that overlap any enemies to be destroyed, have obj_thunder use its Collision With Enemy event and set its alarm[0] to 2. This way the enemy will still have time to take damage and the obj_thunder will be visible for a split second to the player. Or rather than letting obj_thunder get destroyed upon collision with enemies, just give obj_thunder a higher depth than the enemies so it will be behind the enemies. That's just an idea.
 
Last edited:

Imiglikos

Member
Code:
    case obj_thunder:
        var dir = image_xscale;
        var branches = 4;
        var minimum = 10;
        var range = 8 * (minimum - 2);
        var dis = room_width;
        var jumpto = noone;
        var brk = 0;
        var i = 0;
        var n,k;
        repeat minimum {    //create the minimum number of bolts
            with instance_create(box+dir*(42+(i++)*8), y-17,global.wep[cur,e_wep.ammo_type] ) {
                if place_meeting(x,y,obj_wall) {    //destroy a bolt if it spawns on a wall, stop the loop early
                    brk = 1;
                    instance_destroy();
                    break;
                }
                if i == 10 {    //have the last bolt deal with branching
                    var next = id;
                    while branches-- {    //search for the next enemy, up to the specified number of times
                        with next {     //perform the check from the last created enemy
                            with obj_enemy {    //loop through all enemies and find the nearest one to jump to
                                n = x - other.x;
                                if sign(n) == dir && abs(n) < dis && abs(n) < range {
                                    dis = n;
                                    jumpto = id;
                                }
                                if jumpto != noone {
                                    k = abs(jumpto.x - x) div 8;    //if an enemy is found, find how many bolts to create
                                    repeat k {  //create bolts toward the next enemy the same as before
                                        with instance_create(x+dir*(i++)*8, y,global.wep[cur,e_wep.ammo_type] ) {
                                            if place_meeting(x,y,obj_wall) {
                                                brk = 1;
                                                instance_destroy();
                                                break;
                                            }
                                            if --k == 0
                                                next = id;
                                        }
                                        if brk
                                            break;
                                    }
                                }
                                else {   //if no nearby enemies to jump to, stop the loop
                                    branches = 0;
                                    break;
                                 }
                            }
                        }
                    }
                }
            }
            if brk
                break;
        }
        audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false);
        break;
I didn't test the code, but it should have no syntax errors, at least. I changed enemy to obj_enemy to make it clearer what was intended there. I added comments also. I also tried to add conditions to destroy obj_thunder and prevent further obj_thunder from being created upon collision with obj_wall.
EDIT: my code might still freeze. I'm looking over your code and my code right now.
EDIT #2: I think I fixed the freezing condition. My best guess is branches was never getting reduced to 0. I fixed that in this code.

You can have the enemy destroy obj_thunder upon collision, but don't be shocked that you can't see obj_thunder on obj_enemy when you do that. If you want all obj_thunder that overlap any enemies to be destroyed, have obj_thunder use its Collision With Enemy event and set its alarm[0] to 2. This way the enemy will still have time to take damage and the obj_thunder will be visible for a split second to the player. Or rather than letting obj_thunder get destroyed upon collision with enemies, just give obj_thunder a higher depth than the enemies so it will be behind the enemies. That's just an idea.
ok now it takes damage to enemies if they are within range of a thunder weapon
Take damage ... but should die after 4 shots because their HP is 10 ... and now they die after one shot from a thunder weapon.
I just increased the number 10 to 40 ... to make the thunder longer
I added one comment on in the code

Problems remain below ...

1.If I shoot a thunder weapon at an enemy or against a wall, the weapon should destroyed...maybe if I add sprite spr_thunder here consisting of not 5 and, for example, 90 pictures, the problem will solve itself? because the whole animation will open ...?????
2.When I shoot a thunder gun and make a move, the weapon stays in place. ... Probably because when the lightning bolt is fired, the animated bolt of lightning should follow the player as he moves hero
3. Take damage ... but should die after 4 shots because their HP is 10 ... and now they die after one shot from a thunder weapon.


obj_hero

step

GML:
case obj_thunder:

        var dir = image_xscale;

        var branches = 4;

        var minimum = 40;

        var range = 8 * (minimum - 2);

        var dis = room_width;

        var jumpto = noone;

        var brk = 0;

        var i = 0;

        var n,k;

        repeat minimum {    //create the minimum number of bolts

            with instance_create(box+dir*(42+(i++)*8), y-17,global.wep[cur,e_wep.ammo_type] ) {

                if place_meeting(x,y,obj_wall) {    //destroy a bolt if it spawns on a wall, stop the loop early

                    brk = 1;

                    instance_destroy();

                    break;

                }

                if i == 40 {    //have the last bolt deal with branching

                    var next = id;

                    while branches-- {    //search for the next enemy, up to the specified number of times

                        with next {     //perform the check from the last created enemy

                            with par_enemy {    [B]// here did you mean all the parents for the enemies? or one particular enemy?[/B]

                                n = x - other.x;

                                if sign(n) == dir && abs(n) < dis && abs(n) < range {

                                    dis = n;

                                    jumpto = id;

                                }

                                if jumpto != noone {

                                    k = abs(jumpto.x - x) div 8;    //if an enemy is found, find how many bolts to create

                                    repeat k {  //create bolts toward the next enemy the same as before

                                        with instance_create(x+dir*(i++)*8, y,global.wep[cur,e_wep.ammo_type] ) {

                                            if place_meeting(x,y,obj_wall) {

                                                brk = 1;

                                                instance_destroy();

                                                break;

                                            }

                                            if --k == 0

                                                next = id;

                                        }

                                        if brk

                                            break;

                                    }

                                }

                                else {   //if no nearby enemies to jump to, stop the loop

                                    branches = 0;

                                    break;

                                 }

                            }

                        }

                    }

                }

            }

            if brk

                break;

        }

        audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false);

        break;

obj_thunder

create

GML:
image_index = irandom (image_number-1)
alarm[0] = room_speed*3/2;
sprite_index = spr_thunder;
alarm[0]

GML:
instance_destroy();

step

GML:
image_angle=direction  [B]// I don't know if this step is needed now to turn the sprite with the new code[/B]

obj_thunder collision with obj_wall



GML:
 if alarm[0] > 2
alarm[0] = 2;

draw

GML:
draw_sprite_ext( spr_thunder, -1, x, y, 1, 1, 0, -1, 1 );


enemy collision with obj_thunder



GML:
 /*
if other.owner == obj_hero { // this code will not work only for the obj_thunder weapon because there is no local variable "ins" defined
with other {
instance_destroy();
}
*/


if damageClock == 0 {
hp -= 3;
damageClock = room_speed/2;
}

if alarm[0] > 2
alarm[0] = 2;


obj_enemy


alarm[0]

GML:
       instance_destroy();
 
Last edited:

Imiglikos

Member
Code:
    case obj_thunder:
        var dir = image_xscale;
        var branches = 4;
        var minimum = 10;
        var range = 8 * (minimum - 2);
        var dis = room_width;
        var jumpto = noone;
        var brk = 0;
        var i = 0;
        var n,k;
        repeat minimum {    //create the minimum number of bolts
            with instance_create(box+dir*(42+(i++)*8), y-17,global.wep[cur,e_wep.ammo_type] ) {
                if place_meeting(x,y,obj_wall) {    //destroy a bolt if it spawns on a wall, stop the loop early
                    brk = 1;
                    instance_destroy();
                    break;
                }
                if i == 10 {    //have the last bolt deal with branching
                    var next = id;
                    while branches-- {    //search for the next enemy, up to the specified number of times
                        with next {     //perform the check from the last created enemy
                            with obj_enemy {    //loop through all enemies and find the nearest one to jump to
                                n = x - other.x;
                                if sign(n) == dir && abs(n) < dis && abs(n) < range {
                                    dis = n;
                                    jumpto = id;
                                }
                                if jumpto != noone {
                                    k = abs(jumpto.x - x) div 8;    //if an enemy is found, find how many bolts to create
                                    repeat k {  //create bolts toward the next enemy the same as before
                                        with instance_create(x+dir*(i++)*8, y,global.wep[cur,e_wep.ammo_type] ) {
                                            if place_meeting(x,y,obj_wall) {
                                                brk = 1;
                                                instance_destroy();
                                                break;
                                            }
                                            if --k == 0
                                                next = id;
                                        }
                                        if brk
                                            break;
                                    }
                                }
                                else {   //if no nearby enemies to jump to, stop the loop
                                    branches = 0;
                                    break;
                                 }
                            }
                        }
                    }
                }
            }
            if brk
                break;
        }
        audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false);
        break;
I didn't test the code, but it should have no syntax errors, at least. I changed enemy to obj_enemy to make it clearer what was intended there. I added comments also. I also tried to add conditions to destroy obj_thunder and prevent further obj_thunder from being created upon collision with obj_wall.
EDIT: my code might still freeze. I'm looking over your code and my code right now.
EDIT #2: I think I fixed the freezing condition. My best guess is branches was never getting reduced to 0. I fixed that in this code.

You can have the enemy destroy obj_thunder upon collision, but don't be shocked that you can't see obj_thunder on obj_enemy when you do that. If you want all obj_thunder that overlap any enemies to be destroyed, have obj_thunder use its Collision With Enemy event and set its alarm[0] to 2. This way the enemy will still have time to take damage and the obj_thunder will be visible for a split second to the player. Or rather than letting obj_thunder get destroyed upon collision with enemies, just give obj_thunder a higher depth than the enemies so it will be behind the enemies. That's just an idea.

still the same ... such problems occur:

1.If I shoot a thunder weapon at an enemy or against a wall, the weapon should destroyed...maybe if I add sprite spr_thunder here consisting of not 5 and, for example, 90 pictures, the problem will solve itself? because the whole animation will open ...?????

2.When I shoot a thunder gun and make a move, the weapon stays in place. ... Probably because when the lightning bolt is fired, the animated bolt of lightning should follow the player as he moves hero

3. Enemy should die after 4 shots because their HP is 10 ... and now they die after one shot from a thunder weapon.
After firing a thunder it should deal one damage to enemies each time .. but this is what it looks like as long as the thunder weapon is visible after firing and enemies come upon it, they take damage all the time ..

4. The issue is obj_thunder appears to pass through the wall because your wall is not as thick as the full range of obj_thunder


obj_hero


step

GML:
case obj_thunder:
        var dir = image_xscale;
        var branches = 4;
        var minimum = 10;
        var range = 8 * (minimum - 2);
        var dis = room_width;
        var jumpto = noone;
        var brk = 0;
        var i = 0;
        var n,k;
        repeat minimum {    //create the minimum number of bolts
            with instance_create(box+dir*(42+(i++)*8), y-17,global.wep[cur,e_wep.ammo_type] ) {
                if place_meeting(x,y,obj_wall) {    //destroy a bolt if it spawns on a wall, stop the loop early
                    brk = 1;
                    instance_destroy();
                    break;
                }
                if i == 10 {    //have the last bolt deal with branching
                    var next = id;
                    while branches-- {    //search for the next enemy, up to the specified number of times
                        with next {     //perform the check from the last created enemy
                            with par_enemy {    //loop through all enemies and find the nearest one to jump to
                                n = x - other.x;
                                if sign(n) == dir && abs(n) < dis && abs(n) < range {
                                    dis = n;
                                    jumpto = id;
                                }
                                if jumpto != noone {
                                    k = abs(jumpto.x - x) div 8;    //if an enemy is found, find how many bolts to create
                                    repeat k {  //create bolts toward the next enemy the same as before
                                        with instance_create(x+dir*(i++)*8, y,global.wep[cur,e_wep.ammo_type] ) {
                                            if place_meeting(x,y,obj_wall) {
                                                brk = 1;
                                                instance_destroy();
                                                break;
                                            }
                                            if --k == 0
                                                next = id;
                                        }
                                        if brk
                                            break;
                                    }
                                }
                                else {   //if no nearby enemies to jump to, stop the loop
                                    branches = 0;
                                    break;
                                 }
                            }
                        }
                    }
                }
            }
            if brk
                break;
        }
        audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false);
        break;

obj_thunder

create


GML:
image_index = irandom (image_number-1)
alarm[0] = room_speed*3/2;
sprite_index = spr_thunder;
alarm[0]

GML:
instance_destroy();

step

GML:
image_angle=direction  [B]// I don't know if this step is needed now to turn the sprite with the new code[/B]

obj_thunder collision with obj_wall



GML:
        if alarm[0] > 2
alarm[0] = 2;



draw

GML:
draw_sprite_ext( spr_thunder, -1, x, y, 1, 1, 0, -1, 1 );


enemy collision with obj_thunder




GML:
 /*
if other.owner == obj_hero { // this code will not work only for the obj_thunder weapon because there is no local variable "ins" defined
with other {
instance_destroy();
}
*/


if damageClock == 0 {
hp -= 3;
damageClock = room_speed/2;
}

if alarm[0] > 2
alarm[0] = 2;


obj_enemy


alarm[0]

GML:
              instance_destroy();
 
Last edited:

woods

Member
3. Enemy should die after 4 shots because their HP is 10 ... and now they die after one shot from a thunder weapon.
After firing a thunder it should deal one damage to enemies each time .. but this is what it looks like as long as the thunder weapon is visible after firing and enemies come upon it, they take damage all the time ..

enemy collision with obj_thunder

if damageClock == 0 {
hp -= 3;
damageClock = room_speed/2;
}

if alarm[0] > 2
alarm[0] = 2;


are you setting the variable damageClock to 0 anywhere else?
also how are you decreasing the variable damageClock?
 

Imiglikos

Member
3. Enemy should die after 4 shots because their HP is 10 ... and now they die after one shot from a thunder weapon.
After firing a thunder it should deal one damage to enemies each time .. but this is what it looks like as long as the thunder weapon is visible after firing and enemies come upon it, they take damage all the time ..





are you setting the variable damageClock to 0 anywhere else?
also how are you decreasing the variable damageClock?


No,

if I changed the DamageClock variable to 0 elsewhere, the damage in all enemies would not work properly
 

woods

Member
thats what im saying...

if the damageClock is always zero, your enemy will take damage each step..... that is the issue you say you are having

have you tried adding some debug text to double check that value?
 

Imiglikos

Member
thats what im saying...

if the damageClock is always zero, your enemy will take damage each step..... that is the issue you say you are having

have you tried adding some debug text to double check that value?

For enemy damage I set the variable damageClock to 0 in the create event and in the enemy step event.


obj_enemy

create

GML:
damageClock = 0;
hp = 10;
step


GML:
if damageClock > 0 {
visible = !visible;
   damageClock -= 1;
} else {
visible = true;
}

if hp <= 0  {

instance_destroy();

}

enemy collision with obj_thunder

GML:
 /*
if other.owner == obj_hero { // this code will not work only for the obj_thunder weapon because there is no local variable "ins" defined
with other {
instance_destroy();
}
*/


if damageClock == 0 {
hp -= 3;
damageClock = room_speed/2;
}

if alarm[0] > 2
alarm[0] = 2;
if I set a different value in the damageClock variable, e.g. the value of 1 or "<" ">" from 0, the enemy will not receive any damage at all .. Therefore, there is an equal sign to receive damage from weapons ..
that's how it always works and it works for enemies I fire at any kind weapons .. I just want to extend the ability to attack with one weapon so that it branch lengthwise to the next enemy if he is nearby ..
and now how one forum member helped me to do this, more than one enemy takes damage from that one weapon when it is within range. the problem is that these enemies should receive one damage from the weapon each time..and yes they receive all the time until the weapons are out of range.
I have hp set in enemies so that after 4 shots they die ... now they die after one shot ... This solution works on any other weapon ... so it's not the problem ... because it works on other weapons and the enemies dies after 4 damage this is not at fault with the variable damageClock being zero

such problems occur on this weapon ...


1.If I shoot a thunder weapon at an enemy or against a wall, the weapon should destroyed...maybe if I add sprite spr_thunder here consisting of not 5 and, for example, 90 pictures, the problem will solve itself? because the whole animation will open ...?????

2.When I shoot a thunder gun and make a move, the weapon stays in place. ... Probably because when the lightning bolt is fired, the animated bolt of lightning should follow the player as he moves hero

3. Enemy should die after 4 shots because their HP is 10 ... and now they die after one shot from a thunder weapon.
After firing a thunder it should deal one damage to enemies each time .. but this is what it looks like as long as the thunder weapon is visible after firing and enemies come upon it, they take damage all the time ..

4. The issue is obj_thunder appears to pass through the wall because your wall is not as thick as the full range of obj_thunder


edit2

I also discovered the phenomenon ... that when I remove the alarm that causes the thunder weapon to be displayed for some time, the enemy from the thunder weapon dies after 4 shots ..
and the thunder weapon stops showing when we are a hero quite close to enemy / enemies
there is only such a phenomenon ... when two enemies are close together ... only the last enemy takes damage the first enemy does not take damage ... and they should both take damage at the same time


thunder damage.png
 
Last edited:

woods

Member
working on one issue at a time ;o)
i'm still on number 3..

3. Enemy should die after 4 shots because their HP is 10 ... and now they die after one shot from a thunder weapon.
After firing a thunder it should deal one damage to enemies each time .. but this is what it looks like as long as the thunder weapon is visible after firing and enemies come upon it, they take damage all the time ..

are you maybe creating more than one obj_thunder? ..if they are overlapping and all of them are hitting the enemy, that could account for taking multiple hits




===
i made a simple project trying to figure this out..
havn't started in with any branching more lightning bolts to other enemies(but the one bolt does a single hit to each enemy it touches)

obj_player
create
Code:
///initialize

hsp = 0;
vsp = 0;
move_speed = 4;

attack_time = 0;
attack_key = vk_space;
obj_player
step -movement
Code:
///movement and states

hsp = keyboard_check(ord("D"))-(keyboard_check(ord("A")))
vsp = keyboard_check(ord("S"))-(keyboard_check(ord("W")))

hsp *= move_speed;
vsp *= move_speed;

//moving
var moving = hsp!=0 || vsp!=0;

//direction
if (moving){ 
    var _dir = point_direction(0, 0, hsp, vsp); 
    dir = floor(_dir/90);
}

//movement
x += hsp;
y += vsp;
obj_player
step -thunder attack
Code:
///thunder attack

if keyboard_check_pressed(vk_space)
{
    instance_create(x,y,obj_thunder);
}


obj_enemy
create
Code:
///initialize

damageClock = 0;
hp = 10;
obj_enemy
step
Code:
/// damage

if (damageClock > 0) 
{
    damageClock -= 1;
} 

if (hp <= 0)  
{
    instance_destroy();
}


// collision with thunder
if (place_meeting(x,y,obj_thunder))
{
    if (damageClock == 0)
    {
    hp -= 3;
    damageClock = room_speed/2;
    }
}

obj_enemy
draw
Code:
draw_text(x,y-32,"hp: "+string(hp));
draw_text(x,y-64,"dam Clock: "+string(damageClock));

draw_self();

obj_thunder
create
Code:
/// initialize

image_index = 0;
obj_thunder
other - animation end
Code:
///destroy self

instance_destroy();
 

Imiglikos

Member
working on one issue at a time ;o)
i'm still on number 3..

3. Enemy should die after 4 shots because their HP is 10 ... and now they die after one shot from a thunder weapon.
After firing a thunder it should deal one damage to enemies each time .. but this is what it looks like as long as the thunder weapon is visible after firing and enemies come upon it, they take damage all the time ..

are you maybe creating more than one obj_thunder? ..if they are overlapping and all of them are hitting the enemy, that could account for taking multiple hits




===
i made a simple project trying to figure this out..
havn't started in with any branching more lightning bolts to other enemies(but the one bolt does a single hit to each enemy it touches)

obj_player
create
Code:
///initialize

hsp = 0;
vsp = 0;
move_speed = 4;

attack_time = 0;
attack_key = vk_space;
obj_player
step -movement
Code:
///movement and states

hsp = keyboard_check(ord("D"))-(keyboard_check(ord("A")))
vsp = keyboard_check(ord("S"))-(keyboard_check(ord("W")))

hsp *= move_speed;
vsp *= move_speed;

//moving
var moving = hsp!=0 || vsp!=0;

//direction
if (moving){
    var _dir = point_direction(0, 0, hsp, vsp);
    dir = floor(_dir/90);
}

//movement
x += hsp;
y += vsp;
obj_player
step -thunder attack
Code:
///thunder attack

if keyboard_check_pressed(vk_space)
{
    instance_create(x,y,obj_thunder);
}


obj_enemy
create
Code:
///initialize

damageClock = 0;
hp = 10;
obj_enemy
step
Code:
/// damage

if (damageClock > 0)
{
    damageClock -= 1;
}

if (hp <= 0)
{
    instance_destroy();
}


// collision with thunder
if (place_meeting(x,y,obj_thunder))
{
    if (damageClock == 0)
    {
    hp -= 3;
    damageClock = room_speed/2;
    }
}

obj_enemy
draw
Code:
draw_text(x,y-32,"hp: "+string(hp));
draw_text(x,y-64,"dam Clock: "+string(damageClock));

draw_self();

obj_thunder
create
Code:
/// initialize

image_index = 0;
obj_thunder
other - animation end
Code:
///destroy self

instance_destroy();

I create one obj_thunder object each time ... one shot, one obj_thunder ... and each one shot of the obj_thunder should do damage to every enemy that comes within range of the thunder weapon
Of course it works ... deals one damage..on your code on mine too, but for me it should also deal damage to any enemy that is within the range of the thunder weapon
You see .. I said I have a well-defined variable damageClock ;-)
 
Last edited:

woods

Member
....but for me it should also deal damage to any enemy that is within the range of the thunder weapon

in my short test project it works as intended ;/
there has got to be something we are missing, some code tucked in somewhere else or something

hopefully someone with a bit more experience will come along and save the day ;o)
 

Imiglikos

Member
....but for me it should also deal damage to any enemy that is within the range of the thunder weapon

in my short test project it works as intended ;/
there has got to be something we are missing, some code tucked in somewhere else or something

hopefully someone with a bit more experience will come along and save the day ;o)

I am already trying to figure it out in different ways ;-) thank you for helping me solve this problem..Yes..hope here in one colleague from the forum ... who, as I can see, is very knowledgeable is able to solve this problem ..
 
Top