This site requires JavaScript, please enable it in your browser!
Greenfoot back
Back to discussions
NielsV5B
NielsV5B wrote ...

2017/11/14

Error when Enemy or Man is shooting

NielsV5B NielsV5B

2017/11/14

#
I've made a scenerio in which you have a class called Man, which the player can control and a class called Enemy. They're both shooting at each other, but when the Man is killed and the Enemy tries to shoot, there occurs an error: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 at java.util.ArrayList.rangeCheck(ArrayList.java:653) at java.util.ArrayList.get(ArrayList.java:429) at Enemy.randomShoot(Enemy.java:59) at Enemy.act(Enemy.java:29) at greenfoot.core.Simulation.actActor(Simulation.java:604) at greenfoot.core.Simulation.runOneLoop(Simulation.java:562) at greenfoot.core.Simulation.runContent(Simulation.java:221) at greenfoot.core.Simulation.run(Simulation.java:211) I thought that this was caused by the fact that if the Enemy shoots a bullet, the bullet will turn towards the x and y-coordinates of the Man, but as there is no Man anymore, it won't be able to turn towards its coordinates. So I made the Enemy only shoot if getWorld().getObjects(Man.class) != false. But the error still occurs when the man is killed. So here are the pieces of code (possibly) involved in the problem: (the class Movers is only the superclass of Bullet, Enemy and Man) Movers code:
public Movers()
    {
        
    }
    
    public void shoot(int toX, int toY, int fromX, int fromY, String sender)
    {
        String target = "unknown";
        if (sender == "Man")
        {
            target = "Enemy";
        }
        else if (sender == "Enemy")
        {
            target = "Man";
        }
        getWorld().addObject ( new Bullet(toX, toY, sender, target), fromX, fromY );
    }
    
    public boolean canGetWorldManEnemy()
    {
        if (getWorld() != null)
        {
            if (getWorld().getObjects(Enemy.class) != null && getWorld().getObjects(Man.class) != null)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        else 
        {
            return false;
        }
    }
Bullet code:
private int speed;
    private int goToX;
    private int goToY;
    private String myTarget;
    private String mySender;
    private boolean isTouchingBlock = false;
    private boolean hasToRemove = false;
    
    public Bullet(int targetX, int targetY, String senderClass, String targetClass)
    {
        getImage().scale(15,3);
        speed = 3;
        goToX = targetX;
        goToY = targetY;
        mySender = senderClass;
        myTarget = targetClass;
    }
    
    protected void addedToWorld(World MyWorld)
    {
        turnTowards(goToX, goToY);
        if ( mySender == "Man") { turn(Greenfoot.getRandomNumber(4)-2); }
    }
    
    public void act() 
    {
        move(10);
        hitSomeOne();
        
        if (hasToRemove == true)
        {
            getWorld().removeObject(this);
        }
    }
    
    private void hitSomeOne()
    {
        if (canGetWorldManEnemy())
        {
            if ( isTouching(Enemy.class) && myTarget == "Enemy" )
            {
                Enemy enemy = getWorld().getObjects(Enemy.class).get(0);
                enemy.hitEnemy();
                hasToRemove = true;
            }
            else if ( isTouching(Man.class) && myTarget == "Man" )
            {
                Man man = getWorld().getObjects(Man.class).get(0);
                man.hitMan();
                hasToRemove = true;
            }
            //
            else if (getOneIntersectingObject(Block.class) != null)
            {
                hasToRemove = true;
            }
            else
            {
                hasToRemove = false;
            }
        }
    }
    
    public String getSender()
    {
        return mySender;
    }
Man code:
private int speed = 1;
    private boolean permDoor = false;
    private int Health;
    private int hits = 0;
    
    public Man()
    {
        getImage().scale(15,15);
        Health = 3;
    }
    
    public void act() 
    {
        pickKey();
        passDoor();
        walk(speed);
        shootWhenClicked();
    }
    
    public void walk(int n)
    {
        int dx = 0;
        int dy = 0;
        if (Greenfoot.isKeyDown("d"))
        {
            dx++;
        }
        if (Greenfoot.isKeyDown("a"))
        {
            dx--;
        }
        if (Greenfoot.isKeyDown("s"))
        {
            dy++;
        }
        if (Greenfoot.isKeyDown("w"))
        {
            dy--;
        }
        
        for (int i = 0; i < n; i++)
        {
            setLocation(getX() + dx, getY());
            if (getOneIntersectingObject(Block.class) != null || passDoor() )
            {
                setLocation(getX() - dx, getY());
            }
            
            setLocation(getX(), getY() + dy);
            if (getOneIntersectingObject(Block.class) != null || passDoor() ) 
            {
                setLocation(getX(), getY() - dy);
            }
        }
    }
    
    private void pickKey()
    {
        if ( isTouching(Key.class) )
        {
            permDoor = true;
            removeTouching(Key.class);
        }
    }
    
    private boolean passDoor()
    {
        if (getOneIntersectingObject(Door.class) != null && permDoor != true)
        {
            return(true);
        }
        else
        {
            return(false);
        }
    }
    
    private void shootWhenClicked()
    {
        if ( Greenfoot.getMouseInfo() != null)
        {
            if ( Greenfoot.mouseClicked(null) )
            {
                int MouseX = Greenfoot.getMouseInfo().getX();
                int MouseY = Greenfoot.getMouseInfo().getY();
                shoot(MouseX, MouseY, getX(), getY(), "Man");
            }
        }
    }
    
    public void hitMan()
    {
        Health--;
        hits++;
        if ( Health == 0 )
        {
           getWorld().removeObject(this);
        }
    }
And the Enemy code:
private int Health;
    private int speed;
    
    private int maxX;
    private int minX;
    
    private int hits = 0;

    private boolean turnedAtWall = false;
    
    private boolean turned = false;
    
    public Enemy(int max, int min)
    {
        Health = 10;
        speed = 1;
        maxX = max;
        minX = min;
    }
    
    public void act() 
    {
        routine();
        move(speed);
        randomShoot();
    }
    
    private void routine()
    {
        if ( turned == false )
        {
            if (getX() > maxX)
            {
                turn(180);
                turned = true;
            }
            else if (getX() < minX)
            {
                turn(180);
                turned = true;
            }
        }
        else
        {
            turned = false;
        }
    }
    
    private void randomShoot()
    {
        if ( getWorld().getObjects(Man.class) != null)
        {
            if ( Greenfoot.getRandomNumber(1000) < 5 )
            {
                int ManX = ((Man) getWorld().getObjects(Man.class).get(0)).getX();
                int ManY = ((Man) getWorld().getObjects(Man.class).get(0)).getY();
                shoot(ManX, ManY, getX(), getY(), "Enemy");
            }
        }
    }
    
    public void hitEnemy()
    {
        Health--;
        hits++;
        if ( Health == 0 )
        {
           getWorld().removeObject(this);
        }
    }
danpost danpost

2017/11/14

#
NielsV5B wrote...
I made the Enemy only shoot if getWorld().getObjects(Man.class) != false.
This comparison is never 'false'. A List object is never a Boolean object. The 'getObjects' method always returns a List object and is never 'null' as well. It is either an empty list or it contains some number of elements. The 'size' or 'isEmpty' method of the List class can be used to make a comparison that makes sense.
NielsV5B NielsV5B

2017/11/14

#
Thanks, that's working now!
You need to login to post a reply.