Loading...
Logo
Processing Forum

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:
Copy code
  1.   void AI(ArrayList<Tank> targets,boolean side){
  2.     Vec2 target = new Vec2();
  3.     boolean hasTarget = true;      //changed to false if there is no enemy
  4.     float targetIDr = 0;           //stores the distance from a tank
  5.     float targetIDl = 0;
  6.     Vec2 targetIDrv = new Vec2();  //stores the actual position of a target
  7.     Vec2 targetIDlv = new Vec2();
  8.     Vec2 b = this.getCenter();     //its own postion;
  9.     if(side){
  10.       for (int i = targets.size()-1; i >= 0; i--) {  //runs through targets to find closest
  11.         Tank e = targets.get(i);
  12.         Vec2 a = e.getCenter();                      //get the center of the current tank
  13.         if(a.x > b.x){                               //sets different values based on the side it is
  14.           if(getDistance(a.x,a.y,b.x,b.y) < targetIDr || targetIDr == 0){  //sets values if it is closer that the previouse closest
  15.             targetIDrv = a;
  16.             targetIDr = getDistance(a.x,a.y,b.x,b.y);
  17.           }
  18.         }else{
  19.           if(getDistance(a.x,a.y,b.x,b.y) < targetIDl || targetIDl == 0){
  20.             targetIDlv = a;
  21.             targetIDl = getDistance(a.x,a.y,b.x,b.y);
  22.           }
  23.         }
  24.       }
  25.     }else{
  26.       for (int i = 0; i <= targets.size()-1; i++) {
  27.         Tank e = targets.get(i);
  28.         Vec2 a = e.getCenter();
  29.         if(a.x > b.x){
  30.           if(getDistance(a.x,a.y,b.x,b.y) < targetIDr || targetIDr == 0){
  31.             targetIDrv = a;
  32.             targetIDr = getDistance(a.x,a.y,b.x,b.y);
  33.           }
  34.         }else{
  35.           if(getDistance(a.x,a.y,b.x,b.y) < targetIDl || targetIDl == 0){
  36.             targetIDlv = a;
  37.             targetIDl = getDistance(a.x,a.y,b.x,b.y);
  38.           }
  39.         }
  40.       }
  41.     }
  42.     if(side){
  43.       if(targetIDr != 0){  //sets target if there is a tank to the right
  44.         target = targetIDrv;
  45.       }else if(targetIDl != 0){
  46.         target = targetIDlv;  //else set target to the left
  47.       }else{
  48.         hasTarget = false;    //if there isn't any tanks, it doesn't do anything
  49.       }
  50.     }else{
  51.       if(targetIDl != 0){  //reverce for the other direction
  52.         target = targetIDlv;
  53.       }else if(targetIDr != 0){
  54.         target = targetIDrv;
  55.       }else{
  56.         hasTarget = false;
  57.       }
  58.     }
  59.     if(hasTarget){  //if there is a tank, do the AI
  60.       if(target.x > this.getCenter().x){  //which way is the target
  61.         if(abs(target.x - this.getCenter().x) > 200){  //trys to get to best postion
  62.           this.setSpeed(-PI*2);
  63.         }else if(abs(target.x - this.getCenter().x) < 150){
  64.           this.setSpeed(PI*2);
  65.         }else{
  66.           this.setSpeed(0);
  67.         }
  68.       }else{
  69.         if(abs(target.x - this.getCenter().x) > 200){
  70.           this.setSpeed(PI*2);
  71.         }else if(abs(target.x - this.getCenter().x) < 150){
  72.           this.setSpeed(-PI*2);
  73.         }else{
  74.           this.setSpeed(0);
  75.         }
  76.       }
  77.       if(abs(target.x - this.getCenter().x) <= 300){  //is it within 300 pixels?
  78.         if(firetimer == 40){  //don't wana fire every tick
  79.           float temp_distance = target.x - this.getCenter().x;  //horizontal distance
  80.           float temp_deg;  //stores the angle of firing
  81.           if(temp_distance > 0){  //is it to the left or right?
  82.             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
  83.           }else{
  84.             temp_deg = map(temp_distance,-400,0,190,170) + map(constrain(target.y - this.getCenter().y,-200,200),-200,200,-70,60);
  85.           }
  86.           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)
  87.           if(sPlayers.size() < 30){  //is there less than 30 audio players?
  88.             sPlayers.add(minim.loadFile("shot.mp3", 2048));  //play the shot noise
  89.             AudioPlayer a = sPlayers.get(sPlayers.size()-1);
  90.             a.play();
  91.           }
  92.         }
  93.       }
  94.       firetimer++;  //increase fire timer;
  95.       if(firetimer >= 80){  //reset it after a while
  96.         firetimer = 0;
  97.       }
  98.     }
  99.   }
if you want an easy way to test it, here is the entire sketch:
note: you will need the library PBox2D

Replies(4)

Re: tank targeting AI

10 months ago

that is a pretty complex code and you are probably the person who understands it best...
So it is hard for us to install PBox2D, install your sketch and then try to understand it and then help you...

could you therefore tell us the line numbers (or edit your post and mark it bold in your code) that are relevant for your question?
Where is he aiming left?Are we talking about target setting?

Thank you!


Re: tank targeting AI

10 months ago
good point. I wasn't that clear

This part of the code is part of a Class called Tank.  Tank is a instance of one rectangle and two circles that are being simulated fully.  The code itself is called by the main loop every time the program executes provided the game is active (not in a menu) and not paused.  "Left" and "Right" refers to which side of the tank the target is located at.  So if the nearest tank is to the right, however its priority is set to Left, it will move towards and shoot at the nearest tank to the left.  The first part of the code detects the nearest tank to the left and to the right. Then it sets the target point to the nearest tank on the side it is prioritized to (set by the Boolean) and if there is no enemy on that side, it will go for the closest tank on the other side.  The second part of the code will cause the tank to set its motor speed (which controls two joints connecting the rectangle to the two circles) to drive in the direction of the enemy but not if it is too close and if it is too close, it reverses its direction to drive away.  The last part of the code calculates the angle to fire at and then fires provided the enemy is close enough.  

Let me know if there is anything else I forgot to explain

Re: tank targeting AI

10 months ago


first shot by a tank aiming left sometimes goes too far down.
line numbers?



Re: tank targeting AI

10 months ago
I have no idea what is the issue, but from some trouble shooting code, I think it may be the part where it finds the location of a target (don't take my word on it).  I suppose the lines would be 1 -59 but the problem could be anywhere in this part of my sketch. 

By-the-way: to clarify what I meant by "first shot by tank aiming left", I meant that the first shot fired by a tank that is aiming at an enemy to its left ( enemy X position < self X position ) will about half the time fire about 20 deg. to low.