AI for enemies in a platform game

GMACGMAC Member Posts: 4
edited June 2012 in Working with GS (Mac)
I'm creating a platformer and I want to create enemies that when they detect the player chase them throughout the level. I've been struggling with this forever since there seems to be no intuitive way for enemy AI to detect objects (ie. platforms) in the world and then respond by either jumping, climbing, etc.

Best Answer

  • NovicaStudioNovicaStudio Posts: 174
    Accepted Answer
    Well, do you want it to always follow it, or if it is in a certain distance? You could have two actors:
    Enemy and Player.
    Create a Game Real Attribute called 'distance between'.
    Create a self boolean attribute and call it 'insight'.
    Then create a real attribute called 'player x'.

    Create a Constrain Attribute in Player:

    Constrain Attribute
    Game.player x to self.position.x

    Now go into enemy and define the distance between player and enemy by creating this behavior:
    Constrain Attribute 'distance between'
    to
    game.player x-self.position.x
    this makes the difference between the two

    Create a rule that says when distance between is low enough that the AI can see you. For this example, it will see you from 300 pixels away:
    If All of the Conditions are Valid:
    Attribute 'distance between' is greater than -300
    and Attribute 'distance between' is less than 300,
    then
    change attribute insight=true
    OtherWise change attribute insight to false

    Then create another rule:
    if attribute insight=true
    move to
    attribute game.player x


    That should work! If it didn't I apologize, it worked well for me. If you have any questions feel free to ask. :)
    Thanks
    Novica Studio

Answers

  • MobileRocketGamesMobileRocketGames Member Posts: 128
    edited June 2012
    You would accomplish this by having them always track the user, but only move on the user when it comes within a certain magnitude of the user. Note: this is for an air enemy that is not restricted by ground obstacles. Once you create this you can modify it for ground enemies.

    Heres how to do it:
    Create 2 game attributes named PlayerX and PlayerY.
    On the user actor, set up two constrain attributes:
    game.PlayerX = self.Position.X
    game.PlayerY = self.Position.Y
    Then, on the enemy prototype, we set up a "accelerate to" behavior and plug in the game.PlayerX/Y attributes so it always moves towards the player at a set speed. Put that "accelerate to" inside a rule, leave the conditions blank for now.


    That's half the battle.

    Now on the enemy prototype we create a new boolean attribute, call it "Attack" and a new real attribute, call it "AtkDistance". Manually set that real attribute to 200 for now. This will be the distance away from the player you want it to start chasing.

    Create a Change Attribute behavior:
    Change self.Attack = true
    Put that Change Attribute behavior inside a rule that says:
    Attribute self.AtkDistance ≥ magnitude( self.Position.X - game.PlayerX , self.Position.Y - game.PlayerY )
    Then add another change attribute to the otherwise part of the rule saying:
    Change self.Attack = false
    Now go back to the rule with the "accelerate to" behavior and change the conditions of the Rule to:
    Attribute self.Attack = true
    So, when the distance between the the player and the enemy is LESS THAN or equal to whatever number you have set in "AtkDistance" it will turn ON the attack mode, sending it flying towards the player. Make sure not to set the speed of the enemy too high. You will need to play with the AtkDistance radius and the speed of the accelerate.
    Now they will keep moving until they collide with the player, that may be what you want, but if not you will need to add another calculation in to check if its within a certain magnitude of the enemy and if so to set linear X/Y velocity to 0. This way, it will stop, but once the player moves farther away, it will continue to chase them.
    Another benefit of this system is if the player manages to dodge and outrun the enemy the distance set in AtkDistance, the enemy will stop chasing the player, so its very realistic.

    Although when I wrote this I was thinking of a top down game, not a sidescroller so you may need to add in other effects to help your enemies stay on the ground (unless they are floating/flying enemies!).

    If they are ground enemies you will want to take out the game.PlayerY portion of this system and replace the accelerate to with a simple accelerate or whichever other method you choose to move the actors left and right. I can help you with that if you still need it.

    To get them over obstacles/up stairs:

    You are going to need to add invisible actors to the environment that when the enemies come in contact with it modifies their movements in specific ways.
    Don't feel bad, this is what we do with game engines like Unreal, it's called pathing. I would create a bunch of different actors and give them very specific names like Stairs100, Stairs200, etc etc. The 100/200 would be the distance you want it to travel and the name being the movement type. Then place these actors anywhere in the environment where you want your enemies to jump over things or climb up stairs.
    Then you would want to put one rule for each of these environment actors in your enemies actors:
    Create a rule that says:
    When collides or overlaps with Stairs100
    ----Interpolate self.Position.Y = self.Position.Y+100
    Just duplicate this and use the name/numbers to modify its position.
    Stairs would be just a simple interpolate Y up or down. Jumping would be an interpolate Y and X a little bit, to get it over the bump:

    Rule:
    When collides or overlaps with JumpL200
    ----interpolate self.Position.Y = self.Position.Y+200
    ----interpolate self.Position.X = self.Position.X-100
    (keep in mind that will not create a nice arc, but more of a diagonal jump. If you want to create a nice flowing arc, well, its not that much harder. play with the easing a bit to get a nicer motion)
    Once you've done this for one enemy actor, duplicate that actor as many times as you want to create all your enemies, just change the images/animations.

    This may look like a lot but it wont slow down your game at all, because I assume you wont have more than a few of these enemies on screen at once. Even if you did, you wouldn't notice much of a performance hit.


  • NovicaStudioNovicaStudio Member Posts: 174
    Oh, and for the part with how to detect jumping you can always create a rule that if it collides with a transparent actor right before a jump, then the AI would accelerate upwards for 2 seconds, and then fall down, while moving across. That is something I can't give you a perfect answer to. That would be your best bet. :D
  • The_Gamesalad_GuruThe_Gamesalad_Guru Member Posts: 9,922
    Great discussion guys and lots of great ideas!
  • Hybris_StudiosHybris_Studios Member Posts: 5
    awesome information guys, helped out a lot. I am going to try and refine it this week, I'll post back some questions.
Sign In or Register to comment.