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

2016/11/28

How to search for objects and remove them.

MJBelmer MJBelmer

2016/11/28

#
While trying to write a function to reset my game's environment I'm running into a problem I'm not sure how to tackle. redDragon and blueDragon can each shoot up to 3 fireballs on screen at a time. I've found a static way to reset the dragons position after one is hit by a Fireball but I need to search the world for any and all fireballs and remove them from the world during this reset. I imagine I would use a loop to search for them but I'm unsure how to select them. Maybe there is a lesson in the book I can refer to.
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * DragonArena is a two player game of fire-breathing dragons.
 * 
 * @author (Mitch Belmer) 
 * @version (.01)
 */
public class DragonArena extends World
{
    private int redScore;
    private int blueScore;
    private Dragon redDragon, blueDragon;
    /**
     * Constructor for objects of class DragonArena.
     * 
     */
    public DragonArena()
    {    
        // Create a new world with 768x768 cells with a cell size of 1x1 pixels.
        super(768, 768, 1); 
        prepare();
        redScore = 0;
        blueScore = 0;
        showScore();
    }//end DragonArena

    /**
     * Prepare the world for the start of the program.
     * That is: create the initial objects and add them to the world.
     */
    private void prepare()
    {
        Wall wall = new Wall();
        addObject(wall,221,366);
        Wall wall2 = new Wall();
        addObject(wall2, 571, 366);
        redDragon = new Dragon("RedDragon.png");
        redDragon.turn(-90);
        addObject(redDragon,404,596);
        blueDragon = new Dragon("BlueDragon.png");
        blueDragon.turn(90);
        addObject(blueDragon, 404, 180);
    }//end prepare
    
    /**
     * Show Red and Blue Player score
     */
    public void showScore()
    {
        showText("Red Player: " + redScore, 80, 25);
        showText("Blue Player: " + blueScore, 675,25);
    }//end showScore
    
    /**
     * Accessor methods for each of the player objects
     */
    public Dragon getRedDragon() { return redDragon; }
    public Dragon getBlueDragon() { return blueDragon; }
    
    /**
     * roundOver method allows for the world to start a new round
     */
    public void roundOver(Dragon dragon)
    {
        //adjust the score
        if (dragon == redDragon) {
            //redDragon was hit so increase blue dragon score
            blueScore++;
        }//end if
        else {
            redScore++;
        }//end else
        showScore();
        locReset();
    }//end roundOver
    
    /**
     * Reset Dragons to start
     */
    public void locReset()
    {
        redDragon.setLocation(404,596);
        blueDragon.setLocation(404,180);
    }//end locReset
}//end DragonArena
Nosson1459 Nosson1459

2016/11/28

#
I think you would have to use Lists (in "Introduction to Programming with Greenfoot" it might start on page 127). First you have to put this as line 2:
import java.util.List;
then in the place that you want to remove the Fireballs you do this:
List<Fireball> fireball=getObjects(Fireball.class);
removeObjects(fireball);
the above code should remove all the Fireball.class actors in the world.
danpost danpost

2016/11/28

#
You can simplify what Nosson1459 supplied. You do not need to import the List class with the following line:
removeObjects(getObjects(Fireball.class));
MJBelmer MJBelmer

2016/11/28

#
Oh wow that's really awesome! I got it to work perfectly or at least do what I want it to do but now it's causing an issue with the other actions being called on the fireballs when they are removed. I believe the problem lies in the order of my methods being called but not sure if it's possible to not get a conflict here. The error first occurs when bounce() is enacted.
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Fireballs are weapons for the Dragons.
 * 
 * @author (Mitch Belmer) 
 * @version (.01)
 */
public class Fireball extends Actor
{
    public int life = 200;
    private Dragon creator;
    
    /**
     * Constructor - allows fireball to know which dragon object created it
     */
    public Fireball(Dragon creator) 
    {
        this.creator = creator;
    }//end Fireball Constructor
    
    /**
     * Act - do whatever the Fireball wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        bounce();
        fireHit();
        lifespan();
    }//end act
    
    /**
     * Make Fireball bounce when hitting a wall.
     */
    public void bounce()
    {
        int originalX = getX();
        int originalY = getY();
        move(8);
        if (getOneIntersectingObject(Wall.class) != null)
        {
            setLocation(originalX, originalY);
            setRotation(getRotation() - 45);
        }//end if
    }//end bounce
    
    /**
     * Countdown lifespan of Fireball and remove.
     */
    public void lifespan()
    {
        life = life - 1;
        if (life == 0)
        {
            remFire();
        }//end if
    }//end lifespan
    
    /**
     * Detect Fireball Collision and reset players & Adjust Score
     */
    public void fireHit()
    {
        Dragon dragon = (Dragon)getOneIntersectingObject(Dragon.class);
        if (dragon != null && life < 195)
        {
            ((DragonArena)getWorld()).roundOver(dragon);
            remFire();
        }//end if
    }//end fireHit
    
    /**
     * getLife method returns the current life value (int)
     */
    public int getLife()
    {
        return life;
    }//end getLife
    
    /**
     * getCreator provides the reference to the dragon that created this fireball object
     */
    public Dragon getCreator()
    {
        return creator;
    }//end getCreator
    
    /**
     * Remove a fireball and adjust numFireballs
     */
    public void remFire()
    {
        getWorld().removeObject(this);
        creator.fireAdd();
    }//end remFire
}//end Fireball Actor
danpost danpost

2016/11/28

#
Yeah, you have two different methods that call 'remFire', which removes the actor from the world. You can insert the following line between the calls to those methods:
if (getWorld() == null) return;
MJBelmer MJBelmer

2016/11/28

#
At first I thought you meant to place the code between the two methods in the act() method which didn't fix the issue but I place it before the code in the if statements which did fix it. Just so that I understand it conceptually... we're saying if the object is not in the world anymore "return". What does return do? I haven't been over this in class.
MJBelmer MJBelmer

2016/11/28

#
Also thank you for all the help you guys provide! I have a passion for this and being able to get help and answers rather than waiting for my next class is un-measurably valuable to me.
Nosson1459 Nosson1459

2016/11/28

#
return, I think will exit the method without doing the rest of the code after it.
danpost danpost

2016/11/28

#
Nosson1459 is correct in that the execution breaks out of the method and back to the step after where the method was called. Where did you try to insert the line between the methods in the act method? Show what you tried (it should have worked where I intended you to place it).
MJBelmer MJBelmer

2016/11/28

#
First I tried to place it between fireHit(); and lifespan();
    /**
     * Act - do whatever the Fireball wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        bounce();
        fireHit();
        lifespan();
    }//end act
What did end up working was this:
    /**
     * Countdown lifespan of Fireball and remove.
     */
    public void lifespan()
    {
        life = life - 1;
        if (life == 0)
        {
            if (getWorld() == null) return;
            remFire();
        }//end if
    }//end lifespan
    
    /**
     * Detect Fireball Collision and reset players & Adjust Score
     */
    public void fireHit()
    {
        Dragon dragon = (Dragon)getOneIntersectingObject(Dragon.class);
        if (dragon != null && life < 195)
        {
            ((DragonArena)getWorld()).roundOver(dragon);
            if (getWorld() == null) return;
            remFire();
        }//end if
    }//end fireHit
MJBelmer MJBelmer

2016/11/28

#
I just removed the line from lifespan() and it still works with no error and fireHit() is before lifespawn() so I imagine that must be what you meant by between them.
danpost danpost

2016/11/28

#
The one at line 23 should not do anything (it should always return false). You can remove that line. The one at line 9, on the other hand, is placed okay; however, it would be better placed between lines 8 and 9 in the act method code above.
You need to login to post a reply.