I’m doing a 2D platform game (think Super Mario) and I need to make an AI that can control my NPCs. It would be quite boring if nothing ever attacked you after all.
However, I have absolutely no idea how to do something like that, I don’t know first thing about AI. However what I need is guing to be quite simple so if I could just get some tips to get me started I think I can make it work.
You could just make them move to the players position ( if(player.x > enemy.x) enemy.x++;
etc.) for the beginning.
At the end it is something that depends on the game.
Well, I want them to at least be able to notice if there is an obstacle in their way and in that case I want them to try and jump over it.
They will also use ranged attacks and I don’t want them to just shoot blindly when they have no chance of hitting me.
If you have a link to some webpage that gives tips to creating AI I’d be very grateful
The most basic approach is what the above post said, however if you want them to “find their way about” then you need to look into path finding, such as A*. For simpleness though, you can easily implement what you want by doing a couple of things.
To get them to approach the player simply apply a velocity towards the players position. In Mario the enemies are quite dumb. You will only really need to apply a velocity in the X axis
float angle = atan(enemy.y - player.y, enemy.x - enemy.x;
player.setVelocity(enemy.getMoveSpeed * cos(angle), 0)
For the range, that is fairly straight forward and there is 2 ways to do it.
You can either have each enemy hold a Bounding Box or something similar, basically what you would use for collisions, this will expand in 4 directions, it will be a certain size. If the players bounds intersects the enemies bounds, you are in range.
I would use a StateMachine for this, to make it easier to handle enemies.
if(player.getBounds.overlaps(enemy.getRangeBounds)
enemy.changeState(ATTACK_STATE);
You would need to ofc implement my psuedo made up methods and overlap test class and such but that is simple enough.
Secondly you can just constantly compare the position of the player to the enemy, say:
if(Math.abs(enemy.x - player.x || enemy.y - player.y) < 10)
enemy.changeState(ATTACK_STATE)
The first way is much simplier imo.
Thirdly for jumping when they get to an obstacle, this is also fairly simple but requires a little more thinking.
You want the enemy to jump BEFORE they get to the obstacle, this can be done by simply doing an if statement such as:
if(enemy.state != JUMP_STATE)
if(enemy.x + 1 > tile.x)
enemy.changeState(JUMP_STATE);
Finally put it all together for something like this:
ArrayList<Enemy> enemies = new ArrayList<Enemy>();
Tile tile[][] tiles = new Tile[][64];
Player player = new Player();
public void gameLoop(float delta){
for(Enemy enemy : this.enemies){
/** Grab the tile in the array that is to the left or right of the enemy, alternate way would be to constantly check the surrounding 4 tiles and store them in the enemy itself, this means the enemy can handle it's own jumping and it is not in here, we basically check if it is higher that the enemy, assuming origin is bottom left*/
if(tiles[enemy.x + 1][enemy.y].isHigher(enemy.y + enemy.height)){
enemy.jump();
}else if (tiles[enemy.x - 1][enemy.y].isHigher(enemy.y + enemy.height)){
enemy.jump();
}
if(player.getBounds.overlaps(enemy.getRangeBounds)){
enemy.changeState(ATTACK_STATE)
}
}
}
This is of course, rough as hell but I hope it sorta makes sense.
@Gibbo3771
Yes, it does make a lot of sense. I feel more confident with the “head towards the player when it’s in a certain range” than I do with the “jump before the obstacle and keep moving forward” but I hope I’ll be able to get it done.
If you have more tips, or the time to go in depth about it, you’re most welcome to comment again.