GML topdown Enemy melee attack with code

J

JoeCruz

Guest
So far my player when attacking, creates and rotates a "sword" obj in the facing direction, that works fine. id like for enemies to be able to have melee attacks as well, starting to realize will be more difficult than i thought.
How could i go about implementing that using existing code? the principle should be the same but enemies atm just wander randomly so idk how the face_direction would work etc.


here's my code for creating the sword obj

Players step event:

GML:
//Attack animation

if(attack && weapon_cooldown < 1)
{
        var weapon = instance_create(x,y-50, weapon_obj);
        weapon.owner = id;
        weapon_cooldown += 30;
        weapon.dir = face_direction*90;
        weapon.image_angle = (face_direction*90)+45;
       
  // Attack sound
        var change = choose(0,1,2,3);
          switch(change)
          {
             
              case 0: audio_play_sound(attack1_sound,7,false);
              case 1: audio_play_sound(attack2_sound,7,false);
              case 2: audio_play_sound(attack3_sound,7,false);
              case 3: audio_play_sound(attack4_sound,7,false); break;
       
     
          }
       
}  


    //Weapon Cooldown
        weapon_cooldown -= 1;
    if(weapon_cooldown <= 0)
    {
        weapon_cooldown = 0
    }

here's the weapon_obj step event:

GML:
//////////////////////////////////////// RIGHT

    if owner.face_direction == 0 {
        if (image_angle >= dir-45) {
    image_angle -= 7;
} else {
    instance_destroy();
}

move_towards_point(player_obj.x+30,player_obj.y-40,10);
    }
   
    //////////////////////////////////////////  UP
        if owner.face_direction == 1 {
        if (image_angle >= dir-45) {
    image_angle -= 7;
} else {
    instance_destroy();
}

move_towards_point(player_obj.x,player_obj.y-50,10);


    }
    //////////////////////////////    LEFT
   
        if owner.face_direction == 2 {
        if (image_angle >= dir-45) {
    image_angle -= 7;
} else {
    instance_destroy();
}

move_towards_point(player_obj.x-30,player_obj.y-40,10);
    }
   
    //////////////////////////////////////////////   DOWN
   
   
        if owner.face_direction == 3 {
        if (image_angle >= dir-45) {
    image_angle -= 7;
} else {
    instance_destroy();
}

move_towards_point(player_obj.x,player_obj.y-40,10);
    }
and here's the enemy step event (code is wrong/unfinished in the attack/swing state, hence me here ^^):

GML:
if(state == goblin3_states.resting)
{
      
      
      #region Resting
      
      counter += 1;
      sprite_index = goblin3_idle_spr;
      
      
      spd = 2
      
                if(collision_circle(x,y, 512, player_obj, false, false))     
          {
              state = goblin3_states.attack;
          }
          
      if(counter >= room_speed * 2)
      {
          var change = choose(0,1);
          switch(change)
          {
              case 0: state = goblin3_states.wander;
              case 1: counter = 0; break;
         }
      }

          
      
      
      
      
      
      
     #endregion
    
    
 }
 
 
 
  if(state == goblin3_states.wander)
  {
      
      
      #region Wander
      

                    my_dir += random_range(-20,20);
                    x += lengthdir_x(spd, my_dir);
                    y += lengthdir_y(spd, my_dir);
                    
                    sprite_index = goblin3_walk_spr;
                    if(my_dir >= 180)
                    {
                        image_xscale = 1;   
                    }
                    else
                    {
                            image_xscale = -1;   
                            
                    }
                    counter += 1;
           if(counter >= room_speed * 4)
          
          if(collision_circle(x,y, 512, player_obj, false, false))     
          {
              state = goblin3_states.attack;
          }

          
      {
          var change = choose(0,1);
          switch(change)
          {
              case 0: state = goblin3_states.wander;
              case 1: state = goblin3_states.resting; break;
      
          }
      }

      
     #endregion
      
      
  }
      
      
  if(state == goblin3_states.attack)
  {
        move_towards_point(player_obj.x,player_obj.y,4);
        if(collision_circle(x,y,128, player_obj, false, false))     
          {
              state = goblin3_states.swing;
          }
  }
 
 
    if(state == goblin3_states.swing)
  {
       instance_create(x,y-50, small_axe_obj);
       if(instance_number(small_axe_obj) > 1)
       {
           instance_deactivate_object(small_axe_obj);
       }
        weapon_cooldown += 30;
        
    
  }
        depth = -y;
Any tips or help in the right direction would be appreciated, still fairly new so i apologize for my messy code :p
 
Last edited by a moderator:

TheouAegis

Member
GML:
  // Attack sound
        var change = choose(0,1,2,3);
          switch(change)
          {
            
              case 0: audio_play_sound(attack1_sound,7,false);
              case 1: audio_play_sound(attack2_sound,7,false);
              case 2: audio_play_sound(attack3_sound,7,false);
              case 3: audio_play_sound(attack4_sound,7,false); break;
      
    
          }
[/QUOTE]

First off, this is overly complex.

//Attack sound
audio_play_sound(choose(attack1_sound,attack2_sound,attack3_sound,attack4_sound),7,false);

[QUOTE="JoeCruz, post: 453214, member: 51923"]
move_towards_point(player_obj.x+30,player_obj.y-40,10);
[/QUOTE]

There is no need to use "player_obj" here. The sword isn't following the player, it's following its owner.

move_towards_point(owner.x+30,owner.y-40,10);

[QUOTE="JoeCruz, post: 453214, member: 51923"]
[code]
    if(state == goblin3_states.swing)
  {
       instance_create(x,y-50, small_axe_obj);
       if(instance_number(small_axe_obj) > 1)
       {
           instance_deactivate_object(small_axe_obj);
       }
        weapon_cooldown += 30;
        
    
  }
Why are you deactivating the axe? Why not just not create the axe to begin with? And do you want it so only one enemy can ever throw an axe at a time? Right now, your code says even if there are 100 goblins in range of the player, they will all go into their attack animation, but only one will throw an axe (and apparently then you'll have 99 deactivated axes floating in limbo).

Create Event: weapon=noone;
Code:
if state==goblin3_states.swing 
{
    if weapon==noone
    {
        weapon = instance_create(x,y-50,small_axe_obj);
        weapon.owner = id;
        weapon_cooldown = 30;
    }
}
In small_axe_obj's Destroy Event:
owner.weapon=noone;
 
Top