Tower Defence Target Tracker

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
BlackShark
Posts: 11
Joined: Fri Mar 02, 2007 5:06 pm
Contact:

Tower Defence Target Tracker

Post by BlackShark »

Hello,

I am making a tower defense like game and have gotten to a point were i know crash when making the tower. Ive been testing the tracker out with the mouse cursor, so the towers had to follow that, (Which worked out greatly, thanks to some good people at psp-programming for their help)


but now ive added enemy AI, and so i need to have the towers follow them, now I've made what i thought were the necessary adjustments, but now when i make a tower, it crashes, I've added some benchmarks in the code, now, if I don't make an enemy appear on the screen, or have some on the screen with some left over it crashes Right After the "Bench 5a", However if i have all of your enemy's depleted (and/or out of range?), it Crashes after, "Bench 6", I think it either has a problem with tempDist/curDist or

Code: Select all

 s_gunner[i].range
variables, but i can't seem to spot the error.

here is the function/cause of my pain,

Code: Select all

void attackNearestEnemy(int i)
{
     int e;
     int enemyIndex; // index to the enemy with the smallest distance
    
     float curDist, tempDist; // smallest distance; temporary distance to compare to curDist
     
     if(tower_guntop1->angle > 359) {
                             tower_guntop1->angle = 0;
                             }
     // loop through all the enemies
     for&#40;e=0;e<MAX_ENEMIES-1;e++&#41; &#123; //is only one because im testing it with the cursor, &#40;which there is only one of&#41;
        //got rid of sqrtf for speed as it is not needed unless you need to know the exact value
		//but since we are just checking if its in range we dont need it  
		oslDebug&#40;"bench 1"&#41;;
		float tempDist = &#40;&#40;&#40;s_gunner&#91;i&#93;.x+Map.offSet_x&#41; - enemy&#91;e&#93;.x&#41; * &#40;&#40;s_gunner&#91;i&#93;.x+Map.offSet_x&#41; - enemy&#91;e&#93;.x&#41;&#41; + &#40;&#40;&#40;s_gunner&#91;i&#93;.y+Map.offSet_y&#41; - enemy&#91;e&#93;.y&#41; * &#40;&#40;s_gunner&#91;i&#93;.y+Map.offSet_y&#41; - enemy&#91;e&#93;.y&#41;&#41;;
           //square the check as multiplying is wayy faster than sqrtf
           oslDebug&#40;"bench 2"&#41;;
          if&#40;tempDist < &#40;s_gunner&#91;i&#93;.range*s_gunner&#91;i&#93;.range&#41;&#41; &#123;
                      oslDebug&#40;"bench 3"&#41;;
          // if this is the first time through, equalize the distances so that they can compare
          oslDebug&#40;"enemy 'e' = %d",e&#41;;
             if&#40;e = 0&#41; &#123;
                  oslDebug&#40;"bench 4"&#41;;
               enemyIndex = 0;
               curDist = tempDist;
               
             &#125; else &#123;
                    oslDebug&#40;"bench 5a"&#41;;
               // if the new distance is less than the current smallest distance
               if&#40;tempDist < curDist&#41; &#123;      
                           oslDebug&#40;"bench 5b"&#41;;  
                    // the new distance becomes the current smallest distance
                    curDist = tempDist;     
                    oslDebug&#40;"bench 5c"&#41;;                                                                                                                                             
                    // record the enemy's index number
                    enemyIndex = e;
                    oslDebug&#40;"bench 5d"&#41;;
               &#125;
               oslDebug&#40;"bench 5e"&#41;;
               oslDebug&#40;"enemy = %d",enemyIndex&#41;;
             &#125;
             oslDebug&#40;"bench 5f"&#41;;
          &#125;
          oslDebug&#40;"bench 5g"&#41;;
      &#125;//end of for loop
     

     // get the direction the enemy is from the tower &#40;it could be enemy - tower too and you'll get the same result&#41;
oslDebug&#40;"bench 6"&#41;;
     if&#40;curDist < &#40;s_gunner&#91;i&#93;.range*s_gunner&#91;i&#93;.range&#41;&#41; &#123;
                oslDebug&#40;"bench 7"&#41;;
     s_gunner&#91;i&#93;.angle = &#40;&#40;atan2f&#40;&#40;s_gunner&#91;i&#93;.x+Map.offSet_x&#41; - enemy&#91;enemyIndex&#93;.x, -&#40;&#40;s_gunner&#91;i&#93;.y+Map.offSet_y&#41; - enemy&#91;enemyIndex&#93;.y&#41;&#41; + GU_PI&#41; * 180&#41;/GU_PI;  
     //s_gunner&#91;i&#93;.angle/ 57.1139;//converts Radians to degrees  
     &#125;else&#123;
           oslDebug&#40;"bench 8"&#41;;
     // your enemy is done for...
     //attack&#40;rot&#41;; // attack here
          s_gunner&#91;i&#93;.angle += 1;
     &#125;
     
     oslDebug&#40;"bench 9"&#41;;
     tower_guntop1->angle = s_gunner&#91;i&#93;.angle;
     
&#125;;
it is there along with the "oslDebug("bench #");" so you know what/where im talking about.

Help would be very much appreciated, thank you for your time!
Programmer van der C
jimparis
Posts: 1145
Joined: Fri Jun 10, 2005 4:21 am
Location: Boston

Post by jimparis »

Hi,
Just run the code in psplink, find out why it's crashing (get the exact address and reason), then use a debugger or psp-addr2line to find out the cause.
memon
Posts: 63
Joined: Mon Oct 03, 2005 10:51 pm

Post by memon »

I'm pretty sure the variable 'i' is out of range. You write to the gunner array the first time just after the 'bench 6'. Often reading out of bounds will just read off garbage, but writing there is nastier.

Random nit-pickings ;)
- It is a good habit to initialize your variables
- You can remove a couple of extra comparisons and special cases if you initialize the curDist to gunner range*range
- tempDist defined twice
- your code is likely to be more readable, if you would a pointer to the gunner instead of that array indexing all the time.
- the arguments for atan2 are in order y and x
- I dont quite understand the MAX_ENEMIES-1 on that enemy loop
BlackShark
Posts: 11
Joined: Fri Mar 02, 2007 5:06 pm
Contact:

Post by BlackShark »

memon wrote:I'm pretty sure the variable 'i' is out of range. You write to the gunner array the first time just after the 'bench 6'. Often reading out of bounds will just read off garbage, but writing there is nastier.

Random nit-pickings ;)
- It is a good habit to initialize your variables
- You can remove a couple of extra comparisons and special cases if you initialize the curDist to gunner range*range
- tempDist defined twice
- your code is likely to be more readable, if you would a pointer to the gunner instead of that array indexing all the time.
- the arguments for atan2 are in order y and x
- I dont quite understand the MAX_ENEMIES-1 on that enemy loop
thank you very much for your response, (and nit picking), what do you mean i is out of range?
Programmer van der C
memon
Posts: 63
Joined: Mon Oct 03, 2005 10:51 pm

Post by memon »

Bu out of range I mean that the you are indexing outside the gunner array. A common way to do that is off by one, say, you have 3 gunners and pass i=3 to the function. Or calling function with uninitialized variable, etc. Make sure i >= 0 && i < maxgunners.
BlackShark
Posts: 11
Joined: Fri Mar 02, 2007 5:06 pm
Contact:

Post by BlackShark »

O, ok
Programmer van der C
Post Reply