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

2014/7/17

How do I delete one of many actors?

1
2
3
Evil_Lan Evil_Lan

2014/7/17

#
I am a new programmer so the solution to this might be simple. Its just that I don't know how to do this. Okay, well I am trying to make this game that has falling Blue and Red dots. The goal is to remove the balls with the Right and Left arrows keys. My problem is that when I press Right/Left it removes all of the balls of the corresponding color. I would like it to remove just the lowest ball on the screen (The ball with the biggest Y) here is my code for removing the balls: (This is the code for the Blue Dot)
boolean alive = true;

//300 is a Line on the screen. The balls must have passed this line so that it can be removed.
 if (getY() >= 300) {
           //If you press RIGHT ARROW remove the BLUE DOT
           if(Greenfoot.isKeyDown("right") == true) {
               //This is the code that removes the balls (I would like it to remove just 1, the lowest ball on the screen)
               getWorld().removeObjects(getWorld().getObjects(BlueDot.class));
                alive = false;
              
           }
           
       }
  
        
        if( alive == true ) {
        //If the Dot reaches the end of the screen then GAME OVER
        if (getY() > 600){
            Greenfoot.stop();
            System.out.println("GAME OVER!");
        }

       }
I have a similar code for the Red Dot which has the same problem.
NikZ NikZ

2014/7/17

#
Line 8 doesn't specify a BlueDot with the greatest Y, it takes all BlueDots
Evil_Lan Evil_Lan

2014/7/17

#
Thats what I dont understand. I know that I have to use the getY() but the thing is there are many dots falling at the same time... and is there a function that gives me the greatest Y?
NikZ NikZ

2014/7/17

#
You can use getObjects(BlueDot.class) and save it into a List (you'll have to import java.util.List). After that, use a for loop to count every BlueDot in the List. Then you can use a variable and an if statement to get the highest Y.
NikZ NikZ

2014/7/17

#
Another way is to have an invisible Actor (can be a line) that travels upward using setLocation(getX(), getY - x). The first BlueDot it hits will be the farthest BlueDot (use isTouching() or getIntersectingObject()). Refer to the API for more.
Evil_Lan Evil_Lan

2014/7/17

#
Huh? I don't quite understand. How do I use Lists and a for loop?
erdelf erdelf

2014/7/17

#
if i am right, the code u provided is in the dot, just change line 8 to
getWorld().removeObject(this);
Evil_Lan Evil_Lan

2014/7/17

#
I tired the second method. I created a class called BottomLine that travels upward:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

public class BottomLine extends Actor
{

    public void act() 
    {
        // Add your action code here.
        setLocation(getX(), getY() - 1);
        
        if (getY() == 300) {
            setLocation(getX(), 600);
        }     
    }    
}
And in my BlueDot.class, I wrote:
if (getY() >= 300) {
           //If you press RIGHT ARROW remove the BLUE DOT
           if(Greenfoot.isKeyDown("right") == true) {
               //Is the Dot touching the Bottom line
               if (isTouching(BottomLine.class)) {
               int y = getY();
               getWorld().removeObject(this);
               //getWorld().removeObjects(getWorld().getObjects(BlueDot.class));
               alive = false;
              }
                
           }
           
       }
And it works but I would like to be able to remove the dot where ever it is above the 300Y and not just when the Dots touch the invisible line. (Because the player can't always remove the dots because the dots are not touching the line)
Evil_Lan Evil_Lan

2014/7/17

#
erdelf wrote...
if i am right, the code u provided is in the dot, just change line 8 to
getWorld().removeObject(this);
I just tried that and I have the same problem. All of the blue dots disappear when they are above 300 Y
if (getY() >= 300) {
           //If you press RIGHT ARROW remove the BLUE DOT
           if(Greenfoot.isKeyDown("right") == true) {
               
              getWorld().removeObject(this);
              alive = false;            
                  
           }
           
       }
erdelf erdelf

2014/7/17

#
ok, maybe u should change the location of this method, i think the world class is a much more suitable class for that
if(Greenfoot.isKeyDown("right") == true)
{
     List blueDots = getObjects(BlueDot.class);
     if(!blueDots.isEmpty())
     {
        Actor dot = blueDots.get(1);
        for(int i = 0; i<blueDots.size(); i++)
        {
          Actor tempDot = blueDots.get(i);
          if(tempDot.getY()>dot)
          {
               dot = tempDot;
          }
        }
        removeObject(dot);
     }
 }
NikZ NikZ

2014/7/17

#
The for loop checks every component in the List blueDots. As you can see, the variable i increases by one (++) every time the loop runs. The loop only runs if i is less than (<) the size of the List (blueDots.size()). Then, tempDot (an Actor variable) is set to a BlueDot in the List (get(i). This basically means it is getting every component in the List for i is always increasing). The an if checks if the Y.
NikZ NikZ

2014/7/17

#
As for the second method, only have BottonLine go up if "right" is pressed.
NikZ NikZ

2014/7/17

#
Another method is instead of a line traveling upward, have a rectangle on the area in which dots can be removed. It won't need to move, making it more simple.
danpost danpost

2014/7/17

#
Line 10 of the code erdelf gave should be 'if (tempDot.getY() > dot.getY())'. Also, using 'isKeyDown' without any control will cause multiple dots to be removed (one per act, as long as the key is down). If you want only one to be removed per keystroke (press AND release of the key), then use 'getKey' instead of 'isKeyDown'. This can be coded to work for both keys/classes by using the following in your World subclass act method (or a method it calls):
Class clss = null;
String key = Greenfoot.getKey();
if ("left".equals(key)) clss = BlueDot.class;
if ("right".equals(key)) clss = RedDot.class;
if (clss != null)
{
    Actor dot = null;
    for (Object obj : getObjects(clss)) if (dot == null || dot.getY() < ((Actor)obj).getY()) dot = (Actor)obj;
    if (dot != null) getWorld().removeObject(dot);
}
and there is no need to import the List class.
NikZ NikZ

2014/7/17

#
danpost wrote...
Also, using 'isKeyDown' without any control will cause multiple dots to be removed (one per act, as long as the key is down). If you want only one to be removed per keystroke (press AND release of the key), then use 'getKey' instead of 'isKeyDown'.
if (Greenfoot.isKeyDown("right") {
                    while (Greenfoot.isKeyDown(Integer.toString(value))) {
                        
                }                
                //here is where you execute your code
            }
This might work--correct me if I'm wrong.
There are more replies on the next page.
1
2
3