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

2018/4/7

How to make add same objects that act seperately

snake_case snake_case

2018/4/7

#
Hi, I am currently making a game that has enemies that will attack the player if they have line of sight of the player. The problem arises, however, when multiple enemies are added at once. When this happens, the enemies all attack the player only if the first one has line of sight. Is there any way to fix this? Here's my code: Line of sight
public class lineOfSight extends Actor
{
    Actor Player; // This is the player actor
    Actor badGuy;
    int PlayerX;
    int PlayerY;
    int badGuyX;
    int badGuyY;
    GreenfootImage myImage;
    
    /**
     * Act - do whatever the lineOfSight wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public lineOfSight (Actor P, Actor bG)
    {
        Player = P;
        badGuy = bG;
        setImage(new GreenfootImage(1,1));
    }
    public void act() 
    {
        if(Player.getWorld()!=null && badGuy.getWorld()!=null)
        {
            PlayerX = Player.getX();
            PlayerY = Player.getY();
            badGuyX = badGuy.getX();
            badGuyY = badGuy.getY();
            int middleX = (PlayerX + badGuyX)/2;
            int middleY = (PlayerY + badGuyY)/2;
            setLocation(middleX, middleY);
            turnTowards(PlayerX,PlayerY);
            int xSquared = (PlayerX-badGuyX)*(PlayerX-badGuyX);
            int ySquared = (PlayerY-badGuyY)*(PlayerY-badGuyY);
            double distance = Math.sqrt (xSquared + ySquared);
            setImage (new GreenfootImage((int) distance,1));
            //System.out.println(badGuyX + "" + badGuyY);
             
            /*
            myImage = getImage();
            myImage.setColor(Color.BLACK);
            myImage.drawLine(0,0,(int) distance,0);
            */
            
            
        }
    }    
    public boolean clearLineOfSight ()
    {
        return(getOneIntersectingObject(Wall.class)==null);
    }
}
Enemy Code:
public class badGuy extends Actor
{
    Player playerOnScreen;
    lineOfSight los;
    long time = System.currentTimeMillis(); // This is the system's time in milliseconds
    long time2 = System.currentTimeMillis();
    // This controls the health of the enemy, or how many times it can get hit.
    int health = 100; // This is the health of the enemy
    int fireDelay = 250; // This is the time in milliseconds between firing a bullet.
    boolean isDead = false;

    public void addedToWorld(World myWorld)
    {
        if(myWorld instanceof MyWorld)
        {
            MyWorld world = (MyWorld)myWorld;
            los = world.getlos();
            playerOnScreen =world.getplayer();

        }
    }

    /**
     * The bad guy will fire at the play if he has a clear line of sight.
     */
    public void act() 
    {

        if (!isDead){
            checkLineOfSight();
            triggerHurt();
        }

    }

    public void checkLineOfSight()
    {
        long afterTime = System.currentTimeMillis(); // This is is the time in milliseconds
        if (!isDead)
        if(los!=null)
        {
            if(los.clearLineOfSight())
            {
                if(playerOnScreen !=null && playerOnScreen.getWorld()!=null)
                {
                    turnTowards(playerOnScreen.getX(),playerOnScreen.getY()); // The bad guy will turn towards the player if the player is on the screen, and if
                    // he has a clear line of sight.

                    if (afterTime >= time+fireDelay)
                    {
                        time = afterTime; // this updates the time that was previously counted for.
                        //for (int x = 0; x<=3; x++) {
                        fire();
                        // }
                        afterTime = 0; // this sets the time to zero

                    }
                }
            }

        }
        
    }
and the world code
public class MyWorld extends World
{
    Player player = new Player();  // Creates an instance of player in the world 
    badGuy bG = new badGuy(); // Creates an instance of badGuy in the world
    lineOfSight los = new lineOfSight(player,bG);

    /**
     * Constructor for objects of class MyWorld.
     * 
     */
    public MyWorld()
    {    

        super(600, 400, 1, false); // Create a new world with 600x400 cells with a cell size of 1x1 pixels.

        setPaintOrder(Player.class,friendlyBullet.class,badGuy.class,rifleCasing.class);

        // Places the player class into the world
        addObject(player,getWidth()/2,350);

        // Places a bad guy into the world

        addObject(bG,getWidth()/2,200);

        // Adds the line of sight.
        addObject(los,0,0);

    }

    public lineOfSight getlos()
    {
        return los;
    }

    public Player getplayer()
    {
        return player;
    }
}
danpost danpost

2018/4/7

#
All your enemies are using the same los without adjustment for each one. You create the los with the first enemy created as the enemy to get line of sight from. The lineOfSight object should not have any actions to perform on its own (no act method). You should have the parameters on the clearLineOfSight method and the code in the act method should be in it. You can remove the constructor altogether -- along with lines 3 through 8. Well, maybe you can keep line 3 and the constructor without the badGuy parameter.
snake_case snake_case

2018/4/7

#
Thanks for the quick response! I am, however getting several errors after making the adjustments. I removed all of the code frop the act method like you told me to. But getting rid of the badGuy parameter as well as lines 3 - 8 caused some problems.
public class lineOfSight extends Actor
{
    Actor Player; // This is the player actor
    Actor badGuy;
    int PlayerX;
    int PlayerY;
    int badGuyX;
    int badGuyY;
    GreenfootImage myImage;

    /**
     * Act - do whatever the lineOfSight wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public lineOfSight (Actor P, Actor bG)
    {
        Player = P;
        //badGuy = bG;
        setImage(new GreenfootImage(1,1));
    }

    //public void act() 
    // {
    //if(Player.getWorld()!=null && badGuy.getWorld()!=null)
    //{
    /*
    PlayerX = Player.getX();
    PlayerY = Player.getY();
    badGuyX = badGuy.getX();
    badGuyY = badGuy.getY();
    int middleX = (PlayerX + badGuyX)/2;
    int middleY = (PlayerY + badGuyY)/2;
    setLocation(middleX, middleY);
    turnTowards(PlayerX,PlayerY);
    int xSquared = (PlayerX-badGuyX)*(PlayerX-badGuyX);
    int ySquared = (PlayerY-badGuyY)*(PlayerY-badGuyY);
    double distance = Math.sqrt (xSquared + ySquared);
    setImage (new GreenfootImage((int) distance,1));
    /*
    //System.out.println(badGuyX + "" + badGuyY);

    /*
    myImage = getImage();
    myImage.setColor(Color.BLACK);
    myImage.drawLine(0,0,(int) distance,0);
     */

    //}
    //}    

    public boolean clearLineOfSight ()
    {

       

        PlayerX = Player.getX();
        PlayerY = Player.getY();
        badGuyX = badGuy.getX();
        badGuyY = badGuy.getY();
        int middleX = (PlayerX + badGuyX)/2;
        int middleY = (PlayerY + badGuyY)/2;
        setLocation(middleX, middleY);
        turnTowards(PlayerX,PlayerY);
        int xSquared = (PlayerX-badGuyX)*(PlayerX-badGuyX);
        int ySquared = (PlayerY-badGuyY)*(PlayerY-badGuyY);
        double distance = Math.sqrt (xSquared + ySquared);
        setImage (new GreenfootImage((int) distance,1));

        return(getOneIntersectingObject(Wall.class)==null);
        /*
        myImage = getImage();
        myImage.setColor(Color.BLACK);
        myImage.drawLine(0,0,(int) distance,0);
         */

    }
}
Whenever I run the program, I get a nullpointerexception error Thanks
danpost danpost

2018/4/7

#
snake_case wrote...
I am, however getting several errors after making the adjustments. I removed all of the code frop the act method like you told me to. But getting rid of the badGuy parameter as well as lines 3 - 8 caused some problems.
What I was trying to get across is that you need to supply both actors to the clearLineOnSight method when called:
public boolean clearLineOnSight(Actor actorA, Actor actorB)
and use actorA and actorB instead of Player and badGuy. Once you have that, you should not get errors removing those lines. I also mentioned that the player can still be done as you had it (keeping line 3 and 15 through 20, excepting line 18), in which case only the badGuy needs supplied, using:
public boolean clearLineOnSight(Actor badGuy)
-- and that would be easy enough with:
boolean seesPlayer = los.clearLineOfSight(this);
or, most probably:
if (los.clearLineOfSight(this))
in the class of the enemy.
snake_case snake_case

2018/4/7

#
Thanks so much! this is working perfectly now. I cannot express how relieved I am to have this issue finally be resolved. Again, thanks for the help!
You need to login to post a reply.