Enemy Chasing the Player (another beginner question )

Started by Grilled, February 03, 2015, 04:50:44

Previous topic - Next topic

Grilled

Hello again! :D

I'm having trouble getting my character move towards the player. So far I've tried to use the distance formula to calculate the distance between the player and the enemy, but after calculating that, I don't know what to do with that information.

Here's my code:

public class Enemy {

	private static float x,y;
	private static float xVEL,yVEL,nxVEL, nyVEL; 
	
	public Enemy(){
		
		x=620;
		y=420;
		nxVEL=1;
		
	}

	public static void enemyBrain(){
				
				
			
		x+=xVEL;
		y-=yVEL;
		x-=nxVEL;
		y+=nyVEL;
						
		}
	
			

	public void drawEnemy(){
			
		enemyBrain();
		
		glPushMatrix();
		glTranslated(x, y,0);
		glBegin(GL_QUADS);
		glColor3f(0.9f, 0.3f, 0.2f);
		glVertex2d(-8,0);
		glVertex2d(8,0);
		glVertex2d(8,16);
		glVertex2d(-8, 16);
	
		glEnd();
	
		glLoadIdentity();
		
		glPopMatrix();



	}

	public static float getX() {
		return x;
	}

	public static void setX(float x) {
		Enemy.x = x;
	}

	public static float getY() {
		return y;
	}

	public static void setY(float y) {
		Enemy.y = y;
	}

	}


Thanks!

Kai

Your problem statement leaves a lot of questions unanswered:

- what "distance formula" did you use, euclidean distance?
- what restrictions do you impose on the movement? (manhattan, arbitrary, ...)?
- does the enemy have to move around things, or can it just go straight?
- should the enemy move with constant speed or should its position be interpolated non-linearly (accelerate, decelerate)?

These must be getting straight before an answer can be given. :)

Grilled

Assuming by "Euclidean" you mean d=√(x1, x2)^2+(y2, y2)^2, which is the formula I used. To address the other questions, I want my enemy to be able to follow the character and if the character and the enemy collide, both their speeds reduce by half. The only collision objects in my game are the window boarders and the enemy and the player.

Kai

Well, in that case, you simply need to compute the vector 'from enemy to player'.

You get that by computing: V = (player.x - enemy.x, player.y - enemy.y)
This is the "direction" in which your enemy needs to move.

Now, all you need to do is normalize this vector, by dividing its components by the length of the vector.
This is the square-root of its dot-product, or simply length(V) = sqrt(V.x^2 + V.y^2).

This will be your normalized vector 'Vn', still pointing in the direction from-enemy-to-player, but having a unit-length.

Then, you use a time-based interpolation in which you compute the new enemy position by offsetting it by (i.e. adding to it) a scaled version of 'Vn'.
And the scaling factor, by which you multiply each component of 'Vn' is the elapsed time delta since the last frame (be it in seconds) and another factor that gives the speed in "units of length per second".

Simple as that. :)

Grilled

I got lost after "You get that by computing: V = (player.x - enemy.x, player.y - enemy.y). This is the "direction" in which your enemy needs to move. lol  :-[

Kai

Oh... well.  :) I am very sorry about that. It probably was my fault.  ;)
As a first advice, you could first have a look on the math topic of "what is a vector" and a very tiny bit on "linear algebra".
You are going to need that at least at the very basic level.
But it's both too a basic and a broad topic to be explained here in a single post. :)

Grilled


david37370

A Vector is just a list of numbers. to understand what's going on, make it simple first - suppose you have a constant speed, V. it would be a double.
double angle = Math.atan2((player.y-enemy.y), (player.x/enemy.x)); x += V*Math.cos(angle); y += V*Math.sin(angle);
that's it!
now the vector way mentioned above, is supposedly the "right way"- instead of messing around with angles, you could make functions for vectors, that could be more than 2D. V would be a 2d vector here: first component is x axis speed, second is y axis speed. direction of the vector would be y/x. doing what Kai mentioned, V = (player.x - enemy.x, player.y - enemy.y), will leave you with the right direction, but magnitude(length, speed, whatever) will depend on distance. you don't want that, so you divide each component by the length of the vector - length(V) = sqrt(V.x^2 + V.y^2). you just multiply this vector by the speed scalar now and you're good to go

Grilled

OK so I tried the first thing you said, which was pretty easy to follow. But when I ran my program & my enemy kept moving down. I did  the second way and I got lost on the length(V) = sqrt(V.x^2 + V.y^2). Where does the length(V) method come from? And even if it is a method, I couldn't set it equal to something.

I don't know if this would help, but the type of game I'm making is a top down shooter (essentially no jumping) with waves of enemies in which you have to shoot in order to clear the wave.

I just need to know how to make the enemy chase the player no matter where it is.

Do you think you could show me how you would write this?

Thanks.


EDIT: Figured I'd show you what I have so far:
public static void enemyBrain(){
		double V;
		
		V = atan2((Player.y-Enemy.y), (Player.x/Enemy.x)); 		

		V=sqrt(pow(x, 2)+pow(y, 2));
		
		x+=V*VEL; //VEL being the constant speed of the Enemy 
		y+=V*VEL;
		
		
		}

Kai

I will just comment on the good and working trigonometry solution:
It should be:
  V = atan2((Player.y - Enemy.y), (Player.x - Enemy.x));
instead of:
  V = atan2((Player.y - Enemy.y), (Player.x / Enemy.x));

Plesse stick with david's solution and do not mix both solutions. ;)

Grilled

I figured it out. I read some articles on how sin and cos relates to programming and I got it to work. Thank you guys so much for your help!  :-*