How to Move Enemy Towards a Moving Player

How to move enemy towards a moving player?

You have to update enemy position and zRotation property in each update: method call.

Seeker and a Target

Okay, so lets add some nodes to the scene. We need a seeker and a target. Seeker would be a missile, and target would be a touch location. I said you should do this inside of a update: method, but I will use touchesMoved method to make a better example. Here is how you should setup the scene:

import SpriteKit

class GameScene: SKScene, SKPhysicsContactDelegate {

let missile = SKSpriteNode(imageNamed: "seeking_missile")

let missileSpeed:CGFloat = 3.0

override func didMoveToView(view: SKView) {

missile.position = CGPoint(x: frame.midX, y: frame.midY)

addChild(missile)
}
}

Aiming

To implement the aiming you have to calculate the how much you have to rotate a sprite based on its target. In this example I will use a missile and make it point towards the touch location. To accomplish this, you should use atan2 function, like this ( inside touchesMoved: method):

if let touch = touches.first {

let location = touch.locationInNode(self)

//Aim
let dx = location.x - missile.position.x
let dy = location.y - missile.position.y
let angle = atan2(dy, dx)

missile.zRotation = angle

}

Note that atan2 accepts parameters in y,x order, rather than x,y.

So right now, we have an angle in which missile should go. Now lets update its position based on that angle (add this inside touchesMoved: method right below the aiming part):

//Seek
let vx = cos(angle) * missileSpeed
let vy = sin(angle) * missileSpeed

missile.position.x += vx
missile.position.y += vy

And that would be it. Here is the result:

seeking missile

Note that in Sprite-Kit the angle of 0 radians specifies the positive x axis. And the positive angle is in the counterclockwise direction:

polar coords

Read more here.

This means that you should orient your missile to the right missile nose points to the right rather than upwards Sample Image. You can use the upwards oriented image as well, but you will have to do something like this:

missile.zRotation = angle - CGFloat(M_PI_2)

How to make enemies turn and move towards player when near? Unity3D

change the look at target:

void Update () {
Vector3 lookAt = Player.position;
lookAt.y = transform.position.y;
transform.LookAt(lookAt);
}

this way the look at target will be on the same height as your object.

How can I move my enemy by following my Player position with only 1 coordinate

if (Vector2.Distance(transform.position, target.position) > 200)
{
transform.position = Vector2.MoveTowards(transform.position, target.position, speed * Time.deltaTime);
}
else
{
// i want my enemy following my player with only Y coordinate right here, not moving forward anymore
transform.position = Vector2.MoveTowards(transform.position, new Vector2(transform.position.x, target.position.y), speed * Time.deltaTime);
}

Game enemy move towards player

Create a vector in the direction that you want the enemy to move. That's easy:

dir.x = player.x - enemy.x;
dir.y = player.y - enemy.y;

Now normalize this vector. That means divide the terms by the magnitude (the hypotenuse) of the vector.

hyp = sqrt(dir.x*dir.x + dir.y*dir.y);
dir.x /= hyp;
dir.y /= hyp;

Now you just need to add that vector to the enemy's position, multiplied by the speed you want the enemy to move:

enemy.x += dir.x*speed;
enemy.y += dir.y*speed;

Here's how it works - if you add that initial vector to the enemy's position it will instantly be transported to the player. You obviously want to enemy to move at a slower speed. When you normalize the vector, you make it's magnitude (essentially the hypotenuse of the triangle it forms) equal to 1. So now, adding the direction vector moves the enemy by one unit. Multiply that 1 unit by the enemy's speed, and now it's moving at the correct speed.

Edit: all of this extends to 3D as well. You just need a z-component.

Further edits to comment on your code:

You are doing a lot of extra work. You have enough information once you calculate the hypotenuse to move the enemy towards the player. You don't need to use any trig at all - see my code above. You are also calculating (sort of) the magnitude twice:

float hypotenuse = sqrt((xDistance * xDistance) + (yDistance * yDistance));
...
(playerX - enemyX)*(playerX - enemyX)+(playerY - enemyY)*(playerY - enemyY)

The second time it's the distance squared which is a nice optimization, but unnecessary here because you've already calculated the distance and the distance squared.

Here's what I would do:

float xDistance = playerX-enemyX;
float yDistance = playerY-enemyY;
float hypotenuse = sqrt((xDistance * xDistance) + (yDistance * yDistance));

if(hypotenuse < 400){

YPos += timeFactor*200*(yDistance/hypotenuse);
XPos += timeFactor*200*(xDistance/hypotenuse);
}

You'll notice that by removing the abs() I've also managed to remove the if(playerY > enemyY), etc parts.

Problems with moving an enemy towards a character in pygame

Since pygame.Rect is supposed to represent an area on the screen, a pygame.Rect object can only store integral data.

The coordinates for Rect objects are all integers. [...]

The fraction part of the movement gets lost when the movement is add to the position of the rectangle.

If you want to store object positions with floating point accuracy, you have to store the location of the object in separate variables and to synchronize the pygame.Rect object. round the coordinates and assign it to the location (e.g. .topleft) of the rectangle:

hunter_rect = pygame.Rect(500, 500, 48, 60)
hunter_x, hunter_y = hunter_rect.topleft

# [...]
while True:
# [...]

hunter_x -= xchange
hunter_y -= ychange
hunter_rect.topleft = round(hunter_x), round(hunter_y)

# [...]

Problems making enemy follow moving player

Ok, so it was actually Premier Bromanov who answered this, thanks, but I can't accept a comment, which it was, so I will just do this to make it more clear, if anyone should come by and want the answer too.
The math i did was a bit wrong, and here is how my code ended up looking like:

this.UpdateAngle = function() {
this.dx = player.x - this.x;
this.dy = player.y - this.y;
this.distance = Math.sqrt((this.dx*this.dx) + (this.dy*this.dy));
this.angle = Math.atan2(this.dy,this.dx) * 180 / Math.PI;
}
this.UpdateSpeed = function() {
this.speedX = this.speed * (this.dx/this.distance);
this.speedY = this.speed * (this.dy/this.distance);
}
this.Move = function() {
this.UpdateAngle();
this.UpdateSpeed();
this.x += this.speedX;
this.y += this.speedY;
}

Thanks again to Premier Bromanov, this is his answer, and also to everyone else, this was my first post and i am glad how fast i got a response! (I was the slowest one here) :D



Related Topics



Leave a reply



Submit