This site requires JavaScript, please enable it in your browser!
Greenfoot back
igthife
igthife wrote ...

2016/8/7

Enemys that shoots back

igthife igthife

2016/8/7

#
Hello, Can anybody either point me in a direction on how to make an enemy's that shoot and follow you for a space dogfight simulation? I have spend a while looking around on this site but cant find anything tat seems to be what I am looking for. Thanks
igthife igthife

2016/8/7

#
So I manage to mostly solved this problem with this coding which based off of this post . My slightly modified version is attached below.
int dist = 500;
      Actor closest = null;
      if(!getObjectsInRange(dist, Rocket.class).isEmpty())
      {
        for (Object obj: getObjectsInRange(dist, Rocket.class))
        {
            Actor ship = (Actor) obj;
            int shipDist = (int) Math.hypot(ship.getX() - getX(), ship.getY() - getY());
            if (closest == null || shipDist< dist)
            {
                closest = ship;
                dist = shipDist;
            }
        }
        turnTowards(closest.getX(),closest.getY());
        shoot();

      }else{
          if(atWorldEdge())
       {
           turn(Greenfoot.getRandomNumber(180)-90);
        }
          move(3);
        }
    }
This seems to work plenty well for my current purposes. My only dissatisfaction with this method is the enemy ship which uses this section will whip back and forth if you closely pass it and instantly follow you. Is there a way to only let it rotate at a certain speed so that the game looks smoother? Thank You,
danpost danpost

2016/8/7

#
To make the rotation a smooth one, you need to determine the direction of turning and then turn in increments. My Zombie Shooter Demo scenario has the "zombies" (Chaser objects) act with this sort of behavior. The class is, however, assisted by extending my QActor class which provides an even smoother, more precise action. The Chaser class code does contain the main part you would need (the part that determines the direction of turn and the incremental turning). The main line there is:
turn(16*rate*(int)Math.signum((getRotation()-(int)(Math.atan2(dy, dx)*180/Math.PI)+540)%360-180));
where 'dx' and 'dy' are the offsets in the coordinates between the two actors. You could probably just remove "16*rate*" and use something like this:
int dx = getX()-closest.getX();
int dy = getY()-closest.getY();
turn((int)Math.signum((getRotation()-(int)(Math.atan2(dy, dx)*180/Math.PI)+540)%360-180));
igthife igthife

2016/8/7

#
Thank you very much this works perfectly. Here is my code now for anyone who reads this and is curious. .
 private void followRocket()
    {
        int dist = 500;
        Actor closest = null;
        if(!getObjectsInRange(dist, Rocket.class).isEmpty())
        {
           shoot();
           for (Object obj: getObjectsInRange(dist, Rocket.class))
           {
             Actor ship = (Actor) obj;
             int dx = getX()-ship.getX();
             int dy = getY()-ship.getY();
             turn((int)Math.signum((getRotation()-(int)(Math.atan2(dy, dx)*180/Math.PI)+540)%360-180));
           }  
         }else{
           move(3);
          if(atWorldEdge())
          {
            if (Greenfoot.getRandomNumber(100)>50)
            {
               turn(20);
            }else{
               turn(-20);
            } 
          }
       }
    }
My only question now would be is their a way to adjust the turning rate easily with this code? I don't understand all the math in this as of yet and I tried playing around with it some but I only seem capable of breaking it. Oh as I am writing this and re-reading this I looked at the first section of code that you posted. would using that in what I have make the adjustment possible?
danpost danpost

2016/8/7

#
igthife wrote...
My only question now would be is their a way to adjust the turning rate easily with this code?
You can multiply the turn amount (as in the first section of code that I posted) by any whole number, thereby doubling, tripling, etc. the turn rate. You can slow down the turn rate by turning on every second, third, etc. act cycle, thereby cutting the turn rate in half, third, fourth, etc.. For any other rate of turning, you will need to apply some type of smooth turning system (like that which my QActor class provides within the demo).
igthife igthife

2016/8/7

#
Now that you said that it makes perfect sense. Here is what I have now for line 13 for anyone else reading this.
turn(3/2*(int)Math.signum((getRotation()-(int)(Math.atan2(dy, dx)*180/Math.PI)+540)%360-180));
Thank you yet again
danpost danpost

2016/8/8

#
igthife wrote...
Here is what I have now for line 13 for anyone else reading this.
turn(3/2*(int)Math.signum((getRotation()-(int)(Math.atan2(dy, dx)*180/Math.PI)+540)%360-180));
I did not say anything about multiplying by anything other than a whole number (you are multiplying by '3/2', which is '1.5', and evaluated to '1' when rounded). For the given line to work as intended, the actor must be using some sort of smooth turning system (either coded directly within the class or by use of a superclass like my QActor class, where the 'turn' method is overridden to adjust a field tracking the rotational value within the class).
igthife igthife

2016/8/9

#
Oh I didn't see the part about any whole number. And also yes I am using a smooth turner superclass that works like Your Q actor class and this portion of the project seems to be running smoothly now. Thank you for pointing this out and not letting my continue with my misunderstanding. -igthife
You need to login to post a reply.