0
\$\begingroup\$

Like in free-roam RPGs, like Skyrim, I want to make a super-rudimentary screen with just two objects: player and enemy. The enemy will walk around randomly through AI algorithms, and will only fight back gracefully when the player gets near them, and when the player runs away past a certain distance it will continue its AI walking cycle. How do I do this?

Any guidance would be nice.

\$\endgroup\$
1
  • 4
    \$\begingroup\$ What have you tried already? What exactly are you having trouble with? It sounds like you know what you want to do, but haven't tried it yet, why not? \$\endgroup\$
    – House
    Commented Dec 10, 2013 at 22:18

3 Answers 3

2
\$\begingroup\$

Here is a simple pseudo-code implementation that might give you some guidance, given the details you've described:

if ( length(playerPosition - enemyPosition) < enemyAttackRadius)
    enemy.attackPlayer()

if (enemy.isAttacking() && length(playerPosition - enemyPosition) > enemyDisengageRadius)
    enemy.stopAttacking()
\$\endgroup\$
2
  • \$\begingroup\$ I see what you mean, but its still incorrect. (playerPosition - enemyPosition < enemyAttackRadius), how do you compare 2D or 3D coordinates with a scalar exactly? You would rather be using a distance function or the length of the resulting vector in that operation.. \$\endgroup\$
    – Grimshaw
    Commented Dec 10, 2013 at 22:00
  • \$\begingroup\$ I agree with you. (playerPosition - enemyPosition) must resolve to a scalar; the subtraction operator wasn't meant to be taken literally. In my mind it was a distance function, I suppose I should have been more specific. \$\endgroup\$
    – Ryan
    Commented Dec 10, 2013 at 22:04
1
\$\begingroup\$

Here's one basic way to implement it.

if (distance from player to enemy < attack_distance)
{
   enemy_target = player_position;
}
else if (distance from enemy to enemy destination is small)
{
   enemy_destination = random_destination();
   enemy_target = enemy_destination;
}
else
{
   enemy_target = enemy_destination;
}

if (enemy can attack player)
{
  attack();
}
else
{
  move enemy towards enemy_target;
}

For this implementation, your game state consists of three positions - one each for the current position of the player and enemy, and one for the current enemy destination, which should be initialized to the enemy's position.

\$\endgroup\$
0
\$\begingroup\$

You can create an area/bounding box bound to the NPC, when player enters in the box, you start processing the data

The suggestions in the other answers are checking constantly checking the distance of the player and the NPC, while your game is small this is fine, but that can become slower and slower as you add NPCs.

So create an areabox class, and apply to all your NPC. Create events on the areabox, or thresholds inner boxes, on which you can attach other events, like: if is in this area : give up. This way you can also handle the NPC orientation cause I'm pretty sure you don't want it to attack if NPC is giving shoulders to your player.

Now depending what GL library you are using(OpenGl/DirectX), collision detection can be generalized and is way cheaper to run, also you don't need to do the math on the position all the time

//Pseudo code:  
function OnAreaColisionEvent(){
tryToAttack = true; // or whatever
};

function OnGiveUpAreaCollisionEvent(){
  stopChasing = true;
  ReturnToPatrol();
}

function InAttackAreaEvent(){
  if(closeEnough){
    performDamage();
  }
  else{
    runToPlayer();
  }
}

UPDATE
follow this link for more detailed info on how to speedup collision detection Opengl Collision detection methods

\$\endgroup\$
2
  • \$\begingroup\$ You do realize, you'd still have to check to see if the player is inside the bounding box on every update. Events are great, but they still need code checking when to fire them. \$\endgroup\$
    – House
    Commented Dec 10, 2013 at 23:42
  • \$\begingroup\$ performing checks on areabox is faster than checking on players, the volume takes more space, so if you process data on a player base search algorithm that can become real slow real fast, also compared to mesh collision which means now you need to check for every vertex or faces if there is a collision, with an areabox is only 6 faces math \$\endgroup\$
    – Sherlock
    Commented Dec 11, 2013 at 16:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .