A lot of this week has been spent attempting to design AI that looks vaguely clever. I’ve not really done much in the way of AI in the past. The smartest of Gun Bastard’s enemies would occasionally fly diagonally (Shock!) but that was about it. I’ve got some really basic slug monsters in too, but all they do is go back and forth in a set area, and kill the player on contact.
What I’d like to have is enemies that patrol normally most of the time, but change to “chase” mode when they see the player, are able to jump up ledges and over gaps to get to the player, and generally act like a real monster rather than an animated sliding kill trigger. This is proving much harder than I’d hoped!
One thing I have got working is the ability to “see” the player. There are three parts to it:
First we use some trigonometry to determine whether the player is within the enemy’s angle of vision. I get the angle the enemy is facing, and then work out the angle between the enemy and the player:
ATan2(Y( "Player" ) - Y( "Enemy" ), X( "Enemy" ) - X( "Player" ))
If the angle between the enemy and the player is within 45 degrees either side of that, I turn a flag on to say that the player is within a seeable angle. If the player is above, behind or below the enemy, they can’t see me.
Second, I work out the distance between the enemy and the player using a formula for finding the Euclidean distance:
Sqr( ((X( "Player" )-X( "Enemy" )) Pow 2)+((Y( "Player" )-Y( "Enemy" )) Pow 2) )
If this is less than 320 pixels, I turn on another flag. This way, even if I’m in the viewing angle, if I’m more than 320 pixels away, the enemy can’t see me.
Finally, and only if both of those flags are on, I check to see if there’s an obstacle in the way. If the player is within seeable distance and viewing angle, I use the built-in Box2D raycaster to cast a ray from the enemy to the player. If this ray hits the player, we turn the third flag on. If it hits collision, we know that there’s a wall in the way or something, so the enemy can’t see the player.
That in itself was a fair bit of work, but the result is a fairly realistic line-of-sight system for my enemies. So now I have enemies that can be standing around idle, or can go hostile when they see the player. That’s all fine, but the much bigger challenge is to actually get the enemies to move, pathfind, generally behave realistically. To solve this, I think I may need to set up a navigation grid for the tiles in each level, to give the enemy some idea of how to traverse it’s environment. However I solve it, I think this is going to be the most challenging part of making this game.
In the meantime, I’ve also set up a few more physics puzzle objects, including this “windmill” that swings round and hacks you to bits:
So that was fun! 😀