• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Help with enemy AI

V

VicoZann

Guest
Hello all,
I've started to build some simple enemies and I'm already stuck with my third one.

I made a simple goomba like enemy and one that chases you until you get far away enough from it. Simple, not ideal, but great for learning purposes.
Now, for my third enemy, I wanted to expand on the chasing one. What I want him to do is:
-start in Idle state
-chases if player gets close
-if close enough, goes faster
-runs through player
-if player was in one side, let's say, to the left of the enemy, and moved to the right, it goes slower until stops, then turns to face the player again and goes back to the chase


Those 2 last behaviors are giving me a lot of problems, though. I kinda know what to do, but I don't know how to do it. I'm thinking of having some variable that rules over the enemy capacity of changing direction, but whatever I try to do, I end up making it stay stuck in the Idle state.

Here's the behavior code I have right now. For now, he's idle until I get close, chases me and goes faster if close enough. But still keeps following me until I can get far away, where it's lose speed until it stops, then it goes back to chasing.
Right now I think my priority is making it keep going forward until it can turn back and chase me again.


///movement

event_inherited();

//moving
//stays idle until player aproaches, then chases. If player go across, keep going forward for a while before turning


switch(state)
{
case ENEMY_STATE.chase: //chases player
{
if(can_turn)
{
xspeed = player_position * 2;
}

if(distance_to_object(obBlue) < 80)
{
xspeed = player_position * 4;
}


if(distance_to_object(obBlue) > 120) //if player goes behind enemy, goes to turning state
{
if(sign(obBlue.x) < x)
{
if(facing = 1)
{
state = ENEMY_STATE.turn;
}
}
}


}
break;

case ENEMY_STATE.idle: //stands still until player gets close
{
xspeed = 0;
if(distance_to_object(obBlue) < 200)
{
state = ENEMY_STATE.chase;
}
}
break;


case ENEMY_STATE.turn: //turns to the other side to go after player
{

xspeed -= 0.5;

if(facing = 1)
{
if(xspeed <= 0)
{
xspeed = 0;
}
}
if(facing = -1)
{
if(xspeed >= 0)
{
xspeed = 0;
}
}



if(xspeed = 0)
{
facing = sign(obBlue.x - x)
state = ENEMY_STATE.chase;
}
}
break;

}
 
S

Sylveax

Guest
without spitting out code, I'll try to describe how you should go about it:

-check if the player is close enough to the enemy to start chasing
-check on which side of the player the enemy is
-check if enemy is already moving
--if the enemy isn't moving, start chasing the player

--if the enemy is already moving, either slow down or exit, depending on which side of the player the enemy is.

if you're still stuck, I'll help with code, but for learning it would be better if you'd write the code yourself ;)

hope it helped
 
V

VicoZann

Guest
without spitting out code, I'll try to describe how you should go about it:

-check if the player is close enough to the enemy to start chasing
-check on which side of the player the enemy is
-check if enemy is already moving
--if the enemy isn't moving, start chasing the player

--if the enemy is already moving, either slow down or exit, depending on which side of the player the enemy is.

if you're still stuck, I'll help with code, but for learning it would be better if you'd write the code yourself ;)

hope it helped
I was trying to add and change stuff, and the more I changed, the more messed and confusing it was getting, so I deleted the whole code and I'm doing everything again, with more attention and being as organized as possible, keeping your hints in mind as I go. It's not like there was that much of code to redo anyway. ~When~ If I get stuck again, I'll post here and, if I get to a solution, I'll get it here too, it could help someone else with a similar problem
 
V

VicoZann

Guest
Alright, I remade everything and it's still pretty much exactly the way it was. I really need help with this

===================
EDIT
==================

HOLY CANNOLI I DID IT! I'll keep messing with it to se what else I can do, but right now it's doing exactly what I wanted. Here's the code, if anyone needs it in the future.




///movement

event_inherited();

//moving
//stays idle until player aproaches, then chases. If player go across, keep going forward for a while before turning



switch(state)
{
case ENEMY_STATE.idle:
{
xspeed = 0;

if(distance_to_object(obBlue) < 250)
{
can_turn = true;
facing = player_position;
state = ENEMY_STATE.chase;
}
}
break;

case ENEMY_STATE.chase:
{
can_turn = false;
xspeed = facing * 4;




if(distance_to_object(obBlue) <100)
{
xspeed = facing * 6;
}


if(distance_to_object(obBlue) > 150)
{
if(grounded)
{
state = ENEMY_STATE.turn;
}
}

}
break;


case ENEMY_STATE.turn:
{
if(xspeed > 0)
{
if(facing = 1)
{
xspeed -= 0.2;
if(xspeed <= 0)
{
xspeed = 0;
}
}
}

if(xspeed < 0)
{
if(facing = -1)
{
xspeed += 0.2;
if(xspeed >= 0)
{
xspeed = 0;
}
}
}

if(xspeed = 0)
{
can_turn = true;
facing = player_position;
state = ENEMY_STATE.chase;
}

}





}
 
Last edited by a moderator:
V

VicoZann

Guest
Alright, I take back what I said. It's not working perfectly. I noticed that while in the chase state and going in it's slowerd speed, the enemy isn't moving smoothly like it should. Instead it's moving in small bursts of speed. Any idea why?
 
P

ph101

Guest
You could try putting your code examples using the [ code ] system, it's v hard to read your code. Look around on the forum you will see what I mean. You also do not indent any of the clauses in IF statements also making it *very hard to read* at a glance.

Fix that and you will probably have more responses. One thing I have seen is that your enemy state cases are all in different variables - eg. enemy_state.chase, enemy_state.turn - why is that? Surely in a state system you each state to be a constant value? Case 0: is idle, case 1: is chase. These are just some suggestions.
 
Top