Make cannon ball follow target in tower defense game

I am developing a simple tower defense game and have been trying to think of a solution to this for a while: I have a cannon tower, of which I can get the X and Y in pixels and the games coordinates, and I also have it’s target who’s position moves every frame for it is running down the track. How would I make the cannon that the tower shoots “follow” the target. Picture it as a heat seeking missile, trailing behind it. Help would be much appreciated! Also, if anyone knows a simple way to maybe use slope to return which angle the tower should be pointing at? I have all the pictures on a sprite sheet, loaded up and ready. Thanks!
cMp

This may be of help
http://www.java-gaming.org/topics/creating-projection-of-a-projectile-using-linear-algebra/28310/msg/256834/view.html

One way would be to use atan2 to find the angle between the target and the cannonball. However, as the target changes, the angles starts to curve from the original start point. To make it more like a cannonball, you just would want to use atan2 when you initiate the cannonball and it will just go in that direction regardless. You probably would want to predict it before.

Usage:
double angle = Math.atan2(target.y - this.y, target.x - this.x)

Or if you don’t want to use all this trig, you can just get a vector direction and normalize it and multiply it by the speed of the cannon ball, and every update, add the direction vector to the cannonball’s position.

Easy. Learn vector math. Get the difference between two points, normalize it, multiply by the missile speed. More advanced movement is slightly more complicated, but that is not saying much assuming you know how to use vectors.

Make learning vector math your top priority before you continue.

Yeah, practically everything can be represented with vectors. :slight_smile:

This is just what I was looking for! Thanks guys, this is a great community.

Do you guys have any good sources for learning about vectors? that is something very lacking in my knowledge and i feel it is time to learn them!

Right, actually to use this value, where would I put it? I use g.drawImage() to draw my image, and I am not quite sure where to insert this variable…

I’m assuming you have a class to represent the Cannon. If you want to make it a linear line for the Cannon do this:

Pass in the position of the cannon and the position of the target to the Cannon class. Have a vector field that will represent the direction of the cannon. Define the direction as follows:


direction = new Vector2D(target.x - pos.x, target.y - pos.y);
direction.normalize();

direction.multiply(2);

Normalizing a vector is getting its length, and dividing the x and y component by the length. To get the length of your vector use this:


double length = Math.sqrt(x^2 + y^2);

In the update method(where you handle cannon logic):


pos.add(direction);

Actually, here is my definition of a vector, you’ll see how they work:

Alright, I have all that up and running, but I cant exactly add a vector to my x and y position for those are integers… do I add the length?

The vector values are in doubles, so you can just typecast it to an int.


x += (int) direction.x;
y += (int) direction.y;

Also, could you show me the code where you do your stuff? :slight_smile: It’ll be easier that way.

Oooh I understand! Right here is the code for the TowerCannon class. Keep in mind that in the constructor the methods I am calling are just setting the values needed in the super class, Tower.

package Engine;

import java.awt.Graphics;

public class TowerCannon extends Tower {

	public int fTime = 0;
	public int sTime = 500;

	public TowerCannon(int x, int y) {
		setRadius(200);
		setTowerId(Value.airTowerCannonUp);
		setResalePrice(10);
		setFirstUpgradePrice(5, 10, 15);
		setSecondUpgradePrice(5, 10, 15);
		drawTowerAt(x, y, Screen.room.block[y][x].x, Screen.room.block[y][x].y, this);
	}

	public void fight(Graphics g) {
		if (shooting) {
			if (fTime >= sTime) {
				//call shooting method to shoot and whatnot here....
				fTime = 0;
			} else {
				fTime += 1;
			}
		}
	}

	@Override
	public void physic() {
		if (shooting) {
			for (int i = 0; i < Screen.mobs.length; i++) {
				if (Screen.mobs[i].inGame) {
					if (Screen.mobs[i] != null && circle != null) {
						targetX = Screen.mobs[i].x;
						targetY = Screen.mobs[i].y;
					}
				}
			}
		}

		if (shotMob != -1 && circle.intersects(Screen.mobs[shotMob])) {
			shooting = true;
		} else {
			shooting = false;
		}

		if (!shooting) {
			if (Screen.room.block[y][x].airID == id) {
				for (int i = 0; i < Screen.mobs.length; i++) {
					if (Screen.mobs[i].inGame) {
						if (Screen.mobs[i] != null && circle != null) {
							if (circle.intersects(Screen.mobs[i])) {
								shooting = true;
								shotMob = i;
							}
						}
					}
				}
			}
		}
	}
}

Yeah, so pass in the information of the target to the constructor and calculate everything there for a linear cannonball.

Is this what you meant? Because it’s not exactly working…


	public void fight(Graphics g) {
		if (shooting) {
			// if (fTime >= sTime) {
			shoot(g);
			// fTime = 0;
			// } else {
			// fTime += 1;
			// }
		}
	}


	public void shoot(Graphics g) {
		direction = new Vector2D(targetX - Screen.room.block[y][x].x, targetY - Screen.room.block[y][x].y);
		direction.normalize();

		xPos += direction.x;
		yPos += direction.y;

		System.out.println("X: " + xPos + " :: Y: " + yPos);

		g.drawImage(Screen.tileset_res[Value.resCannonball], xPos, yPos, null);
	}

Is that in the cannon itself or the cannon tower shooter?

This is in the TowerCannon class. So your saying make a whole nother class for the cannon ball? Thats interesting, I never thought of that…

You dont have to do that although it might help; it is really your decision

I got it all working :slight_smile: so happy haha but now I gotta figure out which way to rotate the image to face its target… can you point me towards any resources or ideas?

For rotating or for finding the rotation angle?