Reputation: 377
I am working on a game (just for my own fun) in Processing (a variant of Java), and have run into a problem. I have a projectile class that is created and managed by a Castle class, and it goes towards an Enemy class (which is a moving target). What I am trying to do (conceptually) is make this projectile find its intended target (Euclidian distance), say its 20 units away, and move 5 units along that line (i.e. 1/4 of the way there). My problem is that I don't know how to extract the x and y components of that vector to update this projectile's position. Here is my projectile class currently:
class Projectile{
private PImage sprite;
private Enemy target;
private int x;
private int y;
private int speed;
public Projectile(PImage s, Enemy t, int startx, int starty, int sp) throws NullPointerException{
if(t == null){
if(debug){
println("Null target given to Projectile(), throwing exception");
}
throw new java.lang.NullPointerException("The target of the projectile is null");
}
sprite = s;
target = t;
x = startx;
y = starty;
speed = sp;
if(debug){
println("Projectile created: " + t + " starting at position: " + startx + " " + starty);
}
}
public void update(){
if(target != null){
int goingToX = target.getCenterX() ;
int goingToY = target.getCenterY();
//find the total distance to the target
float d = dist(this.x, this.y, target.getCenterX(), target.getCenterY());
//divide it by the velocity vector
d /= speed;
//get the dx and dy components of the vector
}else{//target is null, i.e. already destroyed by something else
//destroy this projectile
//if the higher functions were correct, then nothing needs to go here
//this should be deleted as long as it checks for this.hitTarget()
return;
}
}
public void render(){
image(sprite, x, y, 10, 10);
}
//checks if it hit the target, but does a little bit of rounding because the sprite is big
//done this way in the interest of realism
public boolean hitTarget(){
if(target != null){
if(abs(x - target.getCenterX()) <= 5 && abs(y - target.getCenterY()) <= 5 ){
return true;
}else{
return false;
}
}
//this activates if the target is null, which marks this for deletion
return true;
}
}
I've been researching this for hours and realized my approach was unnecessarily complicated when I was looking into converting floats into strings, formatting them to some number of decimal places, then trying to convert that into a fraction which I would then reduce. I feel like this is far easier than I realize, but I am lacking the math background to do it. All necessary changes should only need to be done in Projectile.update(). Thanks!
Upvotes: 0
Views: 316
Reputation: 7624
Assuming that you want your projectile to 'track' the target, then you can use a simple bit of trig to work out the relative speeds in x and y:
//Calculate the differences in position
float diffX = target.getCenterX() - this.x;
float diffY = target.getCenterY() - this.y;
//Calculate the angle
double angle = Math.atan2(diffY, diffX);
//Update the positions
x += Math.cos(angle) * speed;
y += Math.sin(angle) * speed;
This essentially calculates the angle between the projectile and the target, then moves the projectile in that direction, based on the speed given.
Upvotes: 3