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

2018/3/9

Remove an arraylist of the same actor in order

cycv5 cycv5

2018/3/9

#
The code is about a game in which you press a key and then the Enemy actor will be removed. I would like to use an ArrayList and put a bunch of the same Enemy actor inside so that all them are "numbered". When a key is pressed, the first item of that actor in the list will be removed.
int random = Greenfoot.getRandomNumber(100); //lower the chance of the appearance of the Enemy
        List<Enemy> ene = new ArrayList<Enemy>();
        if(rand == 1)
        {
            eX = Greenfoot.getRandomNumber(460)+20;//choose a x location for the enemy randomly 
            enemy = new Enemy();
            ene.add(enemy);
            addObject(enemy, eX, 0);
            
        }
This is how I create the Enemy object in the World in act().
if(Greenfoot.isKeyDown("1"))
        {
            int i = 0;
            removeObject(ene.get(i));
            i++;
            
        }
This is where I want to remove the first object in the array when "1" is pressed and i++ so that it moved onto the next one. When i run this, it says: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 How do I fix that?
cycv5 cycv5

2018/3/9

#
Some issues with the code above. This is a better version.
int rand = Greenfoot.getRandomNumber(100);//Lower the chance of the appearance of the enemy actor
        List<Enemy> ene = new ArrayList<Enemy>();
        if(rand == 1)
        {
            eX = Greenfoot.getRandomNumber(460)+20;//choose a x location for the enemy randomly 
            enemy = new Enemy();
            ene.add(enemy);
            addObject(enemy, eX, 0);
            
        }
---------
int i = 0;
        if(Greenfoot.isKeyDown("1"))
        {
            
            removeObject(ene.get(i));
            i++;
            
        }
danpost danpost

2018/3/9

#
You will not need to index the elements if you remove the actor from the list as well. However, you will probably need to track the state of the "1" key. The following should be sufficient:
// add a field
private boolean oneDown;

// in code
if (oneDown != Greenfoot.isKeyDown("1"))
{
    oneDown = !oneDown;
    if (oneDown && !ene.isEmpty()) removeObject(ene.remove(0));
}
I also added a safeguard against the IndexOutOfBoundsException.
cycv5 cycv5

2018/3/9

#
danpost wrote...
You will not need to index the elements if you remove the actor from the list as well. However, you will probably need to track the state of the "1" key. The following should be sufficient:
// add a field
private boolean oneDown;

// in code
if (oneDown != Greenfoot.isKeyDown("1"))
{
    oneDown = !oneDown;
    if (oneDown && !ene.isEmpty()) removeObject(ene.remove(0));
}
I also added a safeguard against the IndexOutOfBoundsException.
I added them to my code but it seems my problem here is that the Enemy Actors are not added to the ArrayList properly. So when I added the "safeguard" against outofbounds, nothing happened as I pressed "1". Here is my entire code in my world act(), see if there are some other problems? Thank you!!
    public void act()
    {
        //create enemies
        int rand = Greenfoot.getRandomNumber(100);
        List<Enemy> ene = new ArrayList<Enemy>();
        if(rand == 1)
        {
            eX = Greenfoot.getRandomNumber(460)+20;//choose a x location for the enemy randomly 
            enemy = new Enemy();
            ene.add(enemy);
            addObject(enemy, eX, 0);
            
        }
        //count act everytime it runs
        action++;
        //every 25 act, update the score bar once
        if(action%25 == 0)
        {
            score.update(scoreP);
        }
        //remove the hearts for health 
        if(removeH1)
            removeObject(h1);
        if(removeH2)
            removeObject(h2);
        if(removeH3)
            removeObject(h3);
        

        //if score is at 400, then game stop and player wins
        if(scoreP == 400)
        {
            Greenfoot.stop();//stop the game
            youWSound.Sound();//add the you win sound effect
            yw = new youW();
            addObject(yw, 230, 370);//add the "You win!" picture to the assigned coordinate
        }
        //if gameover, then game stop and player lose (Gameover!)
        if(gameOver)
        {
            //stop the game
            gameOSound.Sound();//add the gameover sound effect
            go = new gameO();
            addObject(go, 250, 370);//add the "Gameover!" picture to the assigned coordinate
            t9 = new ScoreBoard(450, 20);
            addObject(t9, 250, 630);
            t9.update("(Press space to go back to the menu.)");
            if(Greenfoot.isKeyDown("space"))
            {
                Greenfoot.setWorld(new Instruction());
            }
        }
        
            if (oneDown != Greenfoot.isKeyDown("1"))
            {
                oneDown = !oneDown;
                if (oneDown && !ene.isEmpty()) removeObject(ene.remove(0));
            }
        
    }
danpost danpost

2018/3/9

#
Line 5 assigns a new List object to 'ene' every act. You need to move that line outside of the method for it to remain persistent as long as the World object exists.
Yehuda Yehuda

2018/3/9

#
You can also remove one enemy from the world with the follownig one line of code (but I don't know if it's the first one that was added to the world, not "numbered"):
if (!getObjects(Ground.class).isEmpty()) removeObject(getObjects(Ground.class).remove(0));
// I think it's unnecessary to remove it from the list, but I did 'remove' instead of 'get' just in case
cycv5 cycv5

2018/3/11

#
danpost wrote...
Line 5 assigns a new List object to 'ene' every act. You need to move that line outside of the method for it to remain persistent as long as the World object exists.
Thank you very much, really helpful!!
You need to login to post a reply.