tank targeting AI
in
Programming Questions
•
11 months ago
For one of my sketches, I have some tanks that fire at the opposing side. To do this I wrote an AI for the tank that controls firing and wheel movement. The issue is that the first shot by a tank aiming left sometimes goes too far down. Can anyone figure it out?
the AI:
- void AI(ArrayList<Tank> targets,boolean side){
- Vec2 target = new Vec2();
- boolean hasTarget = true; //changed to false if there is no enemy
- float targetIDr = 0; //stores the distance from a tank
- float targetIDl = 0;
- Vec2 targetIDrv = new Vec2(); //stores the actual position of a target
- Vec2 targetIDlv = new Vec2();
- Vec2 b = this.getCenter(); //its own postion;
- if(side){
- for (int i = targets.size()-1; i >= 0; i--) { //runs through targets to find closest
- Tank e = targets.get(i);
- Vec2 a = e.getCenter(); //get the center of the current tank
- if(a.x > b.x){ //sets different values based on the side it is
- if(getDistance(a.x,a.y,b.x,b.y) < targetIDr || targetIDr == 0){ //sets values if it is closer that the previouse closest
- targetIDrv = a;
- targetIDr = getDistance(a.x,a.y,b.x,b.y);
- }
- }else{
- if(getDistance(a.x,a.y,b.x,b.y) < targetIDl || targetIDl == 0){
- targetIDlv = a;
- targetIDl = getDistance(a.x,a.y,b.x,b.y);
- }
- }
- }
- }else{
- for (int i = 0; i <= targets.size()-1; i++) {
- Tank e = targets.get(i);
- Vec2 a = e.getCenter();
- if(a.x > b.x){
- if(getDistance(a.x,a.y,b.x,b.y) < targetIDr || targetIDr == 0){
- targetIDrv = a;
- targetIDr = getDistance(a.x,a.y,b.x,b.y);
- }
- }else{
- if(getDistance(a.x,a.y,b.x,b.y) < targetIDl || targetIDl == 0){
- targetIDlv = a;
- targetIDl = getDistance(a.x,a.y,b.x,b.y);
- }
- }
- }
- }
- if(side){
- if(targetIDr != 0){ //sets target if there is a tank to the right
- target = targetIDrv;
- }else if(targetIDl != 0){
- target = targetIDlv; //else set target to the left
- }else{
- hasTarget = false; //if there isn't any tanks, it doesn't do anything
- }
- }else{
- if(targetIDl != 0){ //reverce for the other direction
- target = targetIDlv;
- }else if(targetIDr != 0){
- target = targetIDrv;
- }else{
- hasTarget = false;
- }
- }
- if(hasTarget){ //if there is a tank, do the AI
- if(target.x > this.getCenter().x){ //which way is the target
- if(abs(target.x - this.getCenter().x) > 200){ //trys to get to best postion
- this.setSpeed(-PI*2);
- }else if(abs(target.x - this.getCenter().x) < 150){
- this.setSpeed(PI*2);
- }else{
- this.setSpeed(0);
- }
- }else{
- if(abs(target.x - this.getCenter().x) > 200){
- this.setSpeed(PI*2);
- }else if(abs(target.x - this.getCenter().x) < 150){
- this.setSpeed(-PI*2);
- }else{
- this.setSpeed(0);
- }
- }
- if(abs(target.x - this.getCenter().x) <= 300){ //is it within 300 pixels?
- if(firetimer == 40){ //don't wana fire every tick
- float temp_distance = target.x - this.getCenter().x; //horizontal distance
- float temp_deg; //stores the angle of firing
- if(temp_distance > 0){ //is it to the left or right?
- temp_deg = map(temp_distance,0,400,-10,10) + map(constrain(target.y - this.getCenter().y,-200,200),-200,200,70,-60); //maps vertical and horizontal distance to angle
- }else{
- temp_deg = map(temp_distance,-400,0,190,170) + map(constrain(target.y - this.getCenter().y,-200,200),-200,200,-70,60);
- }
- particles.add(new Particle(this.getCenter().x,this.getCenter().y-35,cos(radians(temp_deg))*20,sin(radians(temp_deg))*20,3,10)); //spawn partical with velocity , Args: (posX,posY,velocityX,velocityY,partical size, damage it will cause)
- if(sPlayers.size() < 30){ //is there less than 30 audio players?
- sPlayers.add(minim.loadFile("shot.mp3", 2048)); //play the shot noise
- AudioPlayer a = sPlayers.get(sPlayers.size()-1);
- a.play();
- }
- }
- }
- firetimer++; //increase fire timer;
- if(firetimer >= 80){ //reset it after a while
- firetimer = 0;
- }
- }
- }
if you want an easy way to test it, here is the entire sketch:
note: you will need the library PBox2D
1