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

2017/2/7

Finding one Specific object

BrownDwarf BrownDwarf

2017/2/7

#
In my balloon game, I am having trouble with the range aspect. if the tower sees a balloon within 200 units of it, it will turn towards it and start shooting. However, my problem is that as the balloons outpace the monkeys ability to shoot(which is what I want), the tower doesn't retarget on to a closer balloon, it keeps targeting the next closest balloon to the one already popped, even if the balloon is way out of range (obviously this isn't what I want). I want it to somehow see that this specific balloon is out of range so target one that is in range. I can provide the code if needed. Below is the tower code:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class DartMonkey here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class DartMonkey extends Actor
{
    /**
     * Act - do whatever the DartMonkey wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public boolean inRange;
    public boolean isShoot;
    private int timer = 60;
    public void act() 
    {
       lookAt();
       shoot();
    }    
    public void shoot()
    {
       if (timer > 0 && inRange)
        {
            timer --;
            if (timer == 0 && inRange)
            {
                getWorld().addObject(new Bullet(), getX(), getY());
                timer = 60;
            }
            else if (getWorld().getObjects(RedBloon.class).size() == 0)
            {
                int x = 0;
            }
        }
    }
    
    public void lookAt()
    {
        if(!getObjectsInRange(200, RedBloon.class).isEmpty())
        {
            Actor b = getWorld().getObjects(RedBloon.class).get(0);
            
            turnTowards(b.getX(), b.getY());
            setRotation(getRotation()+90);
           
            
            inRange = true;
        }
        else {
            inRange = false;
        }
        
    }
    
    
}
danpost danpost

2017/2/7

#
You are first checking to see if any red balloon is within range (line 42); but, then you use a different method, which gets a list of any and all red balloons in the world to pick a red balloon from to turn toward and shoot at (line 44).
BrownDwarf BrownDwarf

2017/2/8

#
Right so how would I target a specific balloon only when its in range i don't want you to give me the direct answer (jut because i want to try myself), but i am wondering if there is a way to parse through this list i make and see which balloons are and aren't in range. Thanks
BrownDwarf BrownDwarf

2017/2/8

#
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class DartMonkey here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class DartMonkey extends Actor
{
    /**
     * Act - do whatever the DartMonkey wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public boolean inRange;
    public boolean isShoot;
    private int timer = 60;
    public void act() 
    {
        lookAt();
        shoot();
    }    

    public void shoot()
    {
        if (timer > 0 && inRange)
        {
            timer --;
            if (timer == 0 && inRange)
            {
                getWorld().addObject(new Bullet(), getX(), getY());
                timer = 60;
            }
            else if (getWorld().getObjects(RedBloon.class).size() == 0)
            {
                int x = 0;
            }
        }
    }

    public void lookAt()
    {
        if(!getObjectsInRange(200, RedBloon.class).isEmpty())
        {
            Actor b = getWorld().getObjects(RedBloon.class).get(1);

            if (Math.sqrt(Math.pow(getX() - b.getX(), 2) + Math.pow(getY() - b.getY(), 2)) <200)
            {
                turnTowards(b.getX(), b.getY());
                setRotation(getRotation()+90);
                inRange = true;
            }    
            else {
                for (int i = 2; i < b.size(); i++)
                {
                    Actor c = getWorld().getObjects(RedBloon.class).get(i);
                    if(Math.sqrt(Math.pow(getX() - b.getX(), 2) + Math.pow(getY() - b.getY(), 2)) <200)
                    {
                        turnTowards(b.getX(), b.getY());
                        setRotation(getRotation()+90);
                        inRange = true;
                    }
                    else {
                        i += 0;
                    }
                }
            }

        }
        else {
            inRange = false;
        }

    }

}
I revised it to this, so that it goes through every item in the list until something is within range, but the size() function doesn't work it calls an error: cannot find symbol.
Super_Hippo Super_Hippo

2017/2/8

#
If you just want to target the first balloon in range, you can just use the list you got in line 42.
List<Actor> r = getObjectsInRange(200, RedBloon.class);
if (!r.isEmpty())
{
    Actor b = r.get(0);
    //...
}
If you want to target the latest balloon (there are some TD games where you can decide which balloons you want to target), you can simply change one line:
Actor b = r.get(r.size()-1);
To make this work, you have to import the List class (or you change List to java.util.List).
import java.util.List;
If you want to find the nearest balloon, you can use the list, calculate the distance between each balloon and the tower and find the one with the shortest range.
BrownDwarf BrownDwarf

2017/2/8

#
What does the get() function do exactly in this case?
Super_Hippo Super_Hippo

2017/2/8

#
It does the same thing as you used it. 'x.get(y)' gets the y object in the list x (with y from 0 to size-1).
BrownDwarf BrownDwarf

2017/2/8

#
Also where can I find the API for these list functions. (for example I never new you could get the size of a list, its not on the greenfoot API page).
BrownDwarf BrownDwarf

2017/2/8

#
Thanks BTW, you guys are really helpful :)
Super_Hippo Super_Hippo

2017/2/8

#
https://docs.oracle.com/javase/8/docs/api/java/util/List.html The Greenfoot API only contains everything inside the Greenfoot package (so everything which is imported with 'import greenfoot.*').
BrownDwarf BrownDwarf

2017/2/8

#
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.List;
/**
 * Write a description of class DartMonkey here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class DartMonkey extends Actor
{
    /**
     * Act - do whatever the DartMonkey wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public boolean inRange;
    public boolean isShoot;
    private int timer = 60;
    public void act() 
    {
        lookAt();
        shoot();
    }    

    public void shoot()
    {
        if (timer > 0 && inRange)
        {
            timer --;
            if (timer == 0 && inRange)
            {
                getWorld().addObject(new Bullet(), getX(), getY());
                timer = 60;
            }
            else if (getWorld().getObjects(RedBloon.class).size() == 0)
            {
                int x = 0;
            }
        }
    }

    public void lookAt()

    {
        List< Actor> c = getObjectsInRange(200, RedBloon.class);
        if(!c.isEmpty())
        {
            Actor b = c.get(0);

            turnTowards(b.getX(), b.getY());
            setRotation(getRotation()+90);
            inRange = true;

        }

        
        else {
            inRange = false;
        }


    }
}
I get an error, when I initiate the list with the objects in range it says "Incompatible types" when I execute the getobjectsinrange code and give it parameters (200, RedBloon.class)
BrownDwarf BrownDwarf

2017/2/8

#
I have a solution but I'm not sure if it is the best way:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.List;
/**
 * Write a description of class DartMonkey here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class DartMonkey extends Actor
{
    /**
     * Act - do whatever the DartMonkey wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public boolean inRange;
    public boolean isShoot;
    private int timer = 60;
    public void act() 
    {
        lookAt();
        shoot();
    }    

    public void shoot()
    {
        if (timer > 0 && inRange)
        {
            timer --;
            if (timer == 0 && inRange)
            {
                getWorld().addObject(new Bullet(), getX(), getY());
                timer = 60;
            }
            else if (getWorld().getObjects(RedBloon.class).size() == 0)
            {
                int x = 0;
            }
        }
    }

    public void lookAt()

    {
      List   c=   getObjectsInRange(200, RedBloon.class);
        if(!c.isEmpty())
        {
            Actor b = (Actor)c.get(0);

            turnTowards(b.getX(), b.getY());
            setRotation(getRotation()+90);
            inRange = true;

        }

        
        else {
            inRange = false;
        }


    }
}
Basically I instead made a list of objects (opposed to actors), then I casted it later on. Not sure if this is the way I should be doing this?
Super_Hippo Super_Hippo

2017/2/8

#
Theoretically the getObjectsInRange should even return a List<RedBloon>. Well, I always need to test this, too. Your solution is good.
You need to login to post a reply.