How do i make an AI Enemy shoot at the player?

P

Player12Coconut

Guest
How do i make an AI enemy shoot at the player? The AI enemy isn't suppose to move and only just shoot something at the player. I am new to Gamemaker so i don't really know much.
 
O

orSQUADstra

Guest
I assume you want to shoot an object at the player at random times, so it's a bit less mechanic. I'd say you should set up a timer and when it reaches 0, create the object, and set the timer to a random number.

Upon reaching 0 with the timer, you should create your object then with instance_create. Since you didn't tell us anything specific, there isn't anything specific I can say about that part, but using timers should do the trick.
 
Last edited:
P

Player12Coconut

Guest
I assume you want to shoot an object at the player at random times, so it's a bit less mechanic. I'd say you should set up a timer and when it reaches 0, create the object, and set the timer to a random number.

Upon reaching 0 with the timer, you should create your object then with object_create. Since you didn't tell us anything specific, there isn't anything specific I can say about that part, but using timers should do the trick.
Yup, I do want it to shoot at random times. It's a spaceship game where the enemy's are moving past the spaceship making it look like the spaceship is moving forward. But the Enemy is not suppose to move around and only just rotate and shoot at the player every few seconds.
 

Bentley

Member
If you want the bullet to move towards the player when shot, but not follow the player:

obj_enemy
Create Event
Code:
alarm[0] = room_speed * 5; // Shoot every 5 seconds
obj_enemy
Alarm[0] Event

Code:
var bullet = instance_create(x, y, obj_bullet); // Create a bullet and store its ID in the variable "bullet". We need its ID b/c we want to do a few more things with it.
with (bullet)
{
   direction = point_direction(x, y, obj_player.x, obj_player.y); // Give the bullet a direction
   speed = 6;
}
alarm[0] = room_speed * 5; // Reset this alarm so the enemy will shoot after 5 more seconds. This will loop.
If you want the bullet to be homing, you can use the function "move_towards_point" in the bullet's Step Event.

Edit: I just read you want to shoot at random times. Just vary the alarm. For example: alarm[0] = irandom_range(3, 6) * room_speed;
 
Last edited:
P

Player12Coconut

Guest
F3A7C664-C391-4548-AA73-065A76C7DED4.jpeg 4F6C5659-823F-49EB-86E7-7D00969EC5B5.jpeg
If you want the bullet to move towards the player when shot, but not follow the player:

obj_enemy
Create Event
Code:
alarm[0] = room_speed * 5; // Shoot every 5 seconds
obj_enemy
Alarm[0] Event

Code:
var bullet = instance_create(x, y, obj_bullet); // Create a bullet and store its ID in the variable "bullet". We need its ID b/c we want to do a few more things with it.
with (bullet)
{
   direction = point_direction(x, y, obj_player.x, obj_player.y); // Give the bullet a direction
   speed = 6;
}
alarm[0] = room_speed * 5; // Reset this alarm so the enemy will shoot after 5 more seconds. This will loop.
If you want the bullet to be homing, you can use the function "move_towards_point" in the bullet's Step Event.

Edit: I just read you want to shoot at random times. Just vary the alarm. For example: alarm[0] = irandom_range(3, 6) * room_speed;
In the photos is it suppose to look like this or this?
Also where am i suppose to put alarm[0] = irandom_range(3, 6) * room_speed;
 

Bentley

Member
View attachment 15762 View attachment 15761
In the photos is it suppose to look like this or this?
If you're using GM2, the function is called: instance_create_layer. So you'd code:
Code:
instance_create_layer(x, y, "Instances", obj_bullet);
Also, is WinterShipFighter the name of a ship or the name of the bullet? You want to create a bullet, not a ship, so put the name of the bullet inside instead of WinterShipFighter.

Also, did you set the alarm in the enemy's Create Event?

Edit: you'd put: alarm[0] = irandom_range in place of the other alarm code. But only do that if you want a randomized time between enemy shots. Also, I just arbitrarily wrote 3, 6. Use any numbers that suit your game.

The function irandom_range(n1, n2) returns a random whole number between the two numbers. So irandom_range(3, 6) would return one of the following: 3, 4, 5, or 6.
 
Last edited:
P

Player12Coconut

Guest
If you're using GM2, the function is called: instance_create_layer. So you'd code:
Code:
instance_create_layer(x, y, "Instances", obj_bullet);
Also, is WinterShipFighter the name of a ship or the name of the bullet? You want to create a bullet, not a ship, so put the name of the bullet inside instead of WinterShipFighter.

One last thing: did you set the alarm in the enemy's Create Event?
I just realized where i was suppose to put the 2 codes. It works now but the lasers aren't shooting at the ship. I think i know what i did wrong but i'm not fully sure.
 

Bentley

Member
Hmm. Are you sure the direction is:
Code:
direction = point_direction(x, y, obj_player.x, obj_player.y);
The idea is that we assign the bullet a direction. The direction is from the bullet's x and y to the player's x and y. Then you just give the bullet speed and it should go in that direction at that speed.
 

Bentley

Member
is obj_player the bullet or the ship?
Well, that's up to you. You can name things anything you want. But I'd think you'd want obj_player to be the player, and obj_bullet to be the bullet.

You can name resources anything you want in the resource tree. For objects, I use the "obj" prefix. For sprites, I use "spr". That way, when looking at my code, I know what I'm dealing with. Without some sort of naming system, you wouldn't know the difference between the ship's sprite and the ship's object index. GameMaker won't even allow you to name two resources the same.
 
P

Player12Coconut

Guest
Well, that's up to you. You can name things anything you want. But I'd think you'd want obj_player to be the player, and obj_bullet to be the bullet right. Change any names you want in the resource tree. I use the "obj" prefix so that I know, when looking at my code, that I'm dealing with an object. Without a prefix, how would you know the difference between the ship's sprite and the ship's object index. So the prefix is just to make your life easier.
Nvm it seemed to be the ship. Now it goes for me but not in a way a bullet would go. i can't send the video but there is a bunch of enemies and they shoot the bullet towards the player but it doesn't shoot it from the front side. And when the laser hits the player it just stays there when i move to the left all of the bullets follow me to the left. I also want the enemy to turn at the ship then shoot.
 

Bentley

Member
Well, I got to go in a sec, but I try to help you before I do.

If you want the laser to destroy when it hits the player:
obj_player
Collision Event with obj_bullet

Code:
instance_destroy(other); // "other" holds the ID of the bullet that hit you. So we're destroying that bullet.
You may want to take away player HP or something else in this event.

Anyway, best of luck. Sorry if I wasn't very much help.
 
Simply using point_direction etc won't work, as presumably the target they are aiming for will be moving.

If you go to GMLscripts.com and look under 'gameplay' : 'artificial intelligence' - you will find a script called 'intercept course'. This script shows whether a bullet moving at "x" speed can hit an object moving at "x" speed, and if so returns the necessary direction it must travel in. When paired with 'instance closest approach' (found under 'gameplay' : 'instances') it will give you the means to know how long it will take for the bullet to reach the target. Both of these are very useful scripts.

They have lots of other useful scripts for you to use, and although some are no longer needed since GMS now supports them as functions - the examples given here are ones that you must still do by yourself.

Having bullets appear in a place relevant to a ships direction will use the 'lengthdir' functions - which can be found by looking in the manual. For a ship to appear facing the direction it's shooting is simple:
image_angle = point_direction(x , y, target.x, target.y)

or :
image_angle = direction (if you have already set direction to be 'point_direction(x, y, etc)' )
 
P

Player12Coconut

Guest
Well, I got to go in a sec, but I try to help you before I do.

If you want the laser to destroy when it hits the player:
obj_player
Collision Event with obj_bullet

Code:
instance_destroy(other); // "other" holds the ID of the bullet that hit you. So we're destroying that bullet.
You may want to take away player HP or something else in this event.

Anyway, best of luck. Sorry if I wasn't very much help.
Ok. It was helpful but when you return how do i make the enemy shoot a laser from the front of the enemy only and make the enemy rotate to the player? And when the laser goes isn't in the screen anymore how do i make it destroy itself?
 

Bentley

Member
And when the laser goes isn't in the screen anymore how do i make it destroy itself?
There is an Outside Room event. I'd open up the obj_laser object and add that event. Inside that event code: instance_destroy();

how do i make the enemy shoot a laser from the front of the enemy only and make the enemy rotate to the player?
You can rotate the enemy using image_angle. So in the enemy's Step Event code:
Code:
image_angle = point_direction(x, y, obj_player.x, obj_player.y) // Make the enemy point towards the player
This second part, "shoot a laser from the front" is a bit harder. There's a tutorial on here called "Shooting from a rotating object". But you need to use the lengthdir functions.

Make sure the sprite is facing right in the image editor. You'd have to see how far the tip of the gun is from the center of the sprite. Let's say it's 5 pixels away:

Code:
var dx, dy;
dx = lengthdir_x(5, image_angle);
dy = lengthdir_y(5, image_angle);
instance_create_layer(x + dx, y + dy, "Instances", obj_laser);
I think that's right. You can mouse-middle-click to see what a function does.
 
Last edited:
P

Player12Coconut

Guest
There is an Outside Room event. I'd open up the obj_laser object and add that event. Inside that event code: instance_destroy();


You can rotate the enemy using image_angle. So in the enemy's Step Event code:
Code:
image_angle = point_direction(x, y, obj_player.x, obj_player.y) // Make the enemy point towards the player
This second part, "shoot a laser from the front" is a bit harder. There's a tutorial on here called "Shooting from a rotating object". But you need to use the lengthdir functions.

Make sure the sprite is facing right in the image editor. You'd have to see how far the tip of the gun is from the center of the sprite. Let's say it's 5 pixels away:

Code:
var dx, dy;
dx = lengthdir_x(5, image_angle);
dy = lengthdir_y(5, image_angle);
instance_create_layer(x + dx, y + dy, "Instances", obj_laser);
I think that's right. You can mouse-middle-click to see what a function does.
Ok. I think this is the last thing, how do you make the bullet stop moving around after its shot? the bullet follows after the ship after its shot.
 
P

Player12Coconut

Guest
It shouldn't follow the player. Is there any code in the bullet's Step Event?
In the step event it there is
x += 0;
y += 3;
I added that so that way the bullets would go out of the screen if they missed the ship, because earlier they would follow the ship where ever it goes. It still follows the ship but it's also going down out of the screen. And there is
instance_destroy();
in the outside room event.
I also keep on getting this message.
 

Attachments

Last edited by a moderator:

Bentley

Member
In the step event it there is
x += 0;
y += 3;
I added that so that way the bullets would go out of the screen if they missed the ship, because earlier they would follow the ship where ever it goes. It still follows the ship but it's also going down out of the screen. And there is
instance_destroy();
in the outside room event.
I also keep on getting this message.
You still need to change "instance_create" to: instance_create_layer(x, y, "Instances", object_name_here); Also, I would remove that x+= 0, y += 3 code. That is why your laser leaves the room. Changing the y position in a positive direction moves it downwards. You can simply destroy the laser when it hits the player. For example, if in the player object:
Collision Event with Enemy Laser
instance_destroy(other); // Destroy the laser that hit this object.
That way, you don't even have to worry about moving the laser off-screen.
 
P

Player12Coconut

Guest
You still need to change "instance_create" to: instance_create_layer(x, y, "Instances", object_name_here); Also, I would remove that x+= 0, y += 3 code. That is why your laser leaves the room. Changing the y position in a positive direction moves it downwards. You can simply destroy the laser when it hits the player. For example, if in the player object:
Collision Event with Enemy Laser
instance_destroy(other); // Destroy the laser that hit this object.
That way, you don't even have to worry about moving the laser off-screen.
In the game your suppose to dodge the lasers. And i already changed instance_create to
instance_create_layer(x, y, "Instances", RedLaser);
 
Last edited by a moderator:

Bentley

Member
In the game your suppose to dodge the lasers. And i already changed instance_create to
instance_create_layer(x, y, "Instances", RedLaser);
In your earlier post, you were saying that the lasers follow the player after they collide with the player. If you don't want that to happen, all you need to do is destroy the laser in a collision event (check my earlier posts). Also, as I was saying above, I'd prefix your resources. So all your objects could be "obj_something", all your sprites could be "spr_something". That way you know what resource your dealing with in your code. For example:



I think you'd be much better off naming it: obj_WinterShipFighter.
 
P

Player12Coconut

Guest
In your earlier post, you were saying that the lasers follow the player after they collide with the player. If you don't want that to happen, all you need to do is destroy the laser in a collision event (check my earlier posts). Also, as I was saying above, I'd prefix your resources. So all your objects could be "obj_something", all your sprites could be "spr_something". That way you know what resource your dealing with in your code. For example:



I think you'd be much better off naming it: obj_WinterShipFighter.
Ohh i already changed it so when the lasers hit the ship the lasers disappear. I renamed the ship to obj_WinterShipFighter. Basically now the lasers are going out of the screen but the problem is, if a enemy shoots a laser and it goes down aiming for the ship, the laser goes for the ship even after its show. Basically i want to freeze the laser from going anywhere except down after its shot. I decided not to turn the enemy and just make the laser a circle
 

Bentley

Member
Basically i want to freeze the laser from going anywhere except down after its shot.
Ah ok, so you decided you just want the laser to go down? Change the direction code to:
Code:
direction = 270;
You can google "gamemaker directions images" or something like that. You'll see that 270 is straight down.

if a enemy shoots a laser and it goes down aiming for the ship, the laser goes for the ship even after its show.
What exactly do you mean by this. If you mean you want the laser to go straight down but it chases the player, you must have kept some code in the lasers step event that makes it follow.
 
P

Player12Coconut

Guest
Ah ok, so you decided you just want the laser to go down? Change the direction code to:
Code:
direction = 270;
You can google "gamemaker directions images" or something like that. You'll see that 270 is straight down.


What exactly do you mean by this. If you mean you want the laser to go straight down but it chases the player, you must have kept some code in the lasers step event that makes it follow.
I wanted the laser to go straight down earlier but anyways. I also mispelled shot*. And that’s what I mean it’s following the player.
 
P

Player12Coconut

Guest
Ah ok, so you decided you just want the laser to go down? Change the direction code to:
Code:
direction = 270;
You can google "gamemaker directions images" or something like that. You'll see that 270 is straight down.


What exactly do you mean by this. If you mean you want the laser to go straight down but it chases the player, you must have kept some code in the lasers step event that makes it follow.
It Works, Thank you! But i think i change my mind, this is what it looks like.
The circle things are the enemy/turrets and the red thing is the ship. The camera is looking above the ship. i kind of want the enemy to shoot from almost any side as the ship dodges them, but I'm not sure how to do that.
 

Attachments

Bentley

Member
It Works, Thank you! But i think i change my mind, this is what it looks like.
The circle things are the enemy/turrets and the red thing is the ship.
Your game looks cool : ) Congrats.
i kind of want the enemy to shoot from almost any side as the ship dodges them, but I'm not sure how to do that.
In the pic, the enemies are on the right side. Do you mean that want enemies on the left side as well?
 
P

Player12Coconut

Guest
Your game looks cool : ) Congrats.

In the pic, the enemies are on the right side. Do you mean that want enemies on the left side as well?
Thanks :). Where the enemies are is fine. i change my mind about the laser shooting down. So i thought the laser will only come out of one side like the top of the enemy. so when the enemy appears in the screen it will rotate towards the ship and shoot at the ship from the top of it.
 

Bentley

Member
So i thought the laser will only come out of one side like the top of the enemy. so when the enemy appears in the screen it will rotate towards the ship and shoot at the ship from the top of it.
So your enemy has a gun barrel, and you want the gun to rotate towards the player, and then shoot at the player?
 

Bentley

Member
Ok. What you should do is:
obj_turret // Or whatever you named the enemy
Step Event
Code:
image_angle = point_direction(x, y, obj_player.x, obj_player.y);
In the sprite editor, make sure your turret is pointing to the right. You can use mirror flip or rotate to get it there.
 
P

Player12Coconut

Guest
Ok. What you should do is:
obj_turret // Or whatever you named the enemy
Step Event
Code:
image_angle = point_direction(x, y, obj_player.x, obj_player.y);
In the sprite editor, make sure your turret is pointing to the right. You can use mirror flip or rotate to get it there.
how do i use mirror flip or rotate?
 

Bentley

Member
Oh ok. Open up the sprite. Go to the IDE (at the very top of the screen). Click on "image". After that, scroll down to "Rotate All Frames Clockwise (90 Degrees)". That should make the turret face right (it's pointing up, so rotating 90 degrees clockwise should make it face right).
 
P

Player12Coconut

Guest
Oh ok. Open up the sprite. Go to the IDE (at the very top of the screen). Click on "image". After that, scroll down to "Rotate All Frames Clockwise (90 Degrees)". That should make the turret face right (it's pointing up, so rotating 90 degrees clockwise should make it face right).
I can't seem to find IDE. What does it look like?
 
P

Player12Coconut

Guest
From there, hit "edit image". Then you will see "image" at the top center/right of the screen.
It worked, Thanks! But the same problem happened, the laser is following the ship after it came out of the turret. It didn’t when I did the direction code but I stopped using the direction code to shoot the lasers down. Basically the laser spawned out of the turret then later on as the ship moves away the laser will turn then follow the ship.
 

Bentley

Member
the laser is following the ship after it came out of the turret
If the laser is following the ship, there must be some code in its Step Event. If you want, post all the laser's code: it's Create, Step, etc. Then, if you tell me exactly what you want the laser to do and not do, I think I'll be able to help you better.
 
P

Player12Coconut

Guest
If the laser is following the ship, there must be some code in its Step Event. If you want, post all the laser's code: it's Create, Step, etc. Then tell me exactly what it is you do and don't want the laser to do. I think I'll be able to help you better if we do it like that.
Well it has only one event which is the Outside Room event and in it is.
instance_destroy();
 

Bentley

Member
Well it has only one event which is the Outside Room event and in it is.
instance_destroy();
Oh. Then the code that makes the laser follow the player must be in some other object. Which object do you think it's in? The player object? I'd look through the likely causes. It's probably some code like: move_towards_point(...). I have to go for the moment, but I'll check back. Good luck!
 
P

Player12Coconut

Guest
Oh. Then the code that makes the laser follow the player must be in some other object. Which object do you think it's in? The player object? I'd look through the likely causes. It's probably some code like: move_towards_point(...). I have to go for the moment, but I'll check back. Good luck!
Ok,Thanks! I tried looking into the player/ship but there isn't anything having to do with the laser i think, except the collision with the laser, but all there is inside is.
instance_destroy(other);
 

Bentley

Member
Ok,Thanks! I tried looking into the player/ship but there isn't anything having to do with the laser i think, except the collision with the laser, but all there is inside is.
instance_destroy(other);
Well, I don't know then. But it's got to be in some object. I'd take a second look. Best of luck, let me know if you have anymore questions.
 
P

Player12Coconut

Guest
Well, I don't know then. But it's got to be in some object. I'd take a second look. Best of luck, let me know if you have anymore questions.
I'll try and find out what it is.
 
Last edited by a moderator:
Top