|
Artificial Intelligence |
|
Welcome to Dave's AI tutorial, Part 1. In this tutorial we will go over platformer AI. This tutorial will start with D&D alternatives, but code will be required for the more advanced AI.
What is AI? AI, or Artificial Intelligence, is the controlling of characters or things by the computer or game, instead of being controlled by a user. AI is important in many single player games, as the user needs someone, or something, to fight. And it can also be used to add interesting features, such as a weapon that fires homing missiles.
Why should I put AI in my platform game? Without an enemy, there is no skill needed in playing the game. When AI is implemented into a game, it suddenly adds the requirement of reflexes, and planning. This means the user must plan when to jump down in front of the AI, or attack it if it is not looking. After attacking, or if the AI has discovered you there, the user needs quick reflexes to shoot or attack the enemy before it kills them.
--oOo--
Simple AI The most simple platform AI includes a stopper or reverser, and an enemy that reverses its direction when in contact with this stopper/reverser. This is achieved by taking an object for your enemy, and giving it a sprite. Next, create a new sprite for the reverser. make it of a decent size, say 16x16. We will make this invisible later. In the enemy object, add a create event.
Drag and Drop: Under the move tab, choose the action with red arrows on it. Drag it into the action list to place it in the create event. In the window that pops up, click the arrows that point to the left and right, and leave the others unpressed. This will make the enemy move either left or right at random when it is created. In the speed entry field, enter a speed that you would like the enemy to travel at. I like 4.
-------------------------------------------------------------------------------------
Code: To set the direction we will first find 0 or 1 at random, then multiply it by 180. This will give us either 0 or 180 as the direction to move in. 0 being right, and 180 being left. To find a random number between 0 and 1, we first use the random function, like so: random(2). This will find a number between 0 and 1.99999999999999. Now if we want just 0 or 1, we can remove the decimals (which is the same as rounding down to the nearest number), floor(random(2)). now we want to set it as the direction, and also multiply by 180:
And we need to set the speed:
--------------------------------------------------------------------------------------
Now we have our enemy moving, we need to place it in the room. Where ever you want the enemy to stop and start heading back, put a reverser.
Now we need to make the enemy reverse its direction when it hits it, so first, add a collision event with the reverser.
Drag and Drop: In this event, drag the reverse horizontal direction action, under the move tab. It looks like a curved arrow. That’s all there is to it.
--------------------------------------------------------------------------------------
Code: All we need to do is reverse the horizontal speed. The horizontal speed is stored in the variable hspeed. To reverse it, we multiply it by -1.
So now we have the most basic platform AI. To make the reversers invisible, open the object, and uncheck the visible checkbox, on the left.
--oOo--
Player attacking homing missile: To create a homing missile, we will use the technique which involves setting the missiles gravity direction towards its target. This is to create a missile which heads towards the player. See the next portion for missiles that head towards the nearest enemy.
First create a sprite for the missile. Now an object. Assign the sprite to the object.
In the new object, add a step event.
Drag and Drop: Drag the set gravity action into the action list, from the move tab. For direction, we want the direction to the player. This can be achieved with the function point_direction(...). Assuming the player object is called objPlayer: To use, we first enter x,y for our co-ordinates, then objPlayer.x and objPlayer.y. So in the direction entry field we put:
This finds the direction from our position to the players position. In the gravity box put a number to set the strength it is pulled towards the object. I like 0.2. -----------------------------------------------------------------------------------
Code: See above for explanation of point_direction(...) function. We set the gravity direction like so:
And the gravity strength like this:
You may wish to make the missile shoot upwards at the start, to prevent it hitting the ground before reaching its target. To do this, just give it a negative vspeed in the create event, or use the vertical speed action.
Making a homing missile that attacks the nearest enemy is slightly more difficult. For this we must first find the nearest enemy. If you have more than 1 type of enemy, make a new object called enemy_parent, and make it the parent of all enemy objects.
-------------------------------------------------------------------------------------
Drag and Drop: This can be done in drag and drop, but it is not worth it, and it's more of a hassle than code.
-------------------------------------------------------------------------------------
Code: To find the nearest enemy we use instance_nearest(...).
This finds the id of the nearest instance of enemy_parent (or its child objects) and stores it in the variable 'inst'. We can now make the missile move towards the position of the nearest enemy.
And then we set the gravity strength
-------------------------------------------------------------------------------------
As with the other homing missile, you may wish for it to go up when created. To do this, just give it a negative vspeed in the create event, or use the vertical speed action.
More advanced enemies:
You may wish for the enemy to move towards you if close enough, and shoot if at an even smaller distance from you. Lets do that like so:
If the player's x is bigger than the enemies x, and the player is less than 300 pixels away from it, we will move right (step event). The same for left. And if the distance is less than 100 we will stop.
Lets look at a new function: distance_to_object(...). This returns the distance to the first instance of the object you put between the brackets.
-------------------------------------------------------------------------------------
Code:
--------------------------------------------------------------------------------------
You can put any shooting code in the last for statement, where stated. This is not a shooting tutorial.
To make the enemy stop when it hits a reverser or stopper (so it wont go off a cliff and hover in mid-air, etc), just add a collision event in the enemy object. In collision with reverser objet, set hspeed to 0:
-------------------------------------------------------------------------------------
Code:
Dangerous_Dave - Revision #1 |