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

2016/10/21

Getting the coordinates of an object

1
2
LimeLava LimeLava

2016/10/21

#
I am trying to find the coordinates of the Ball class and if the equal 0 then i want to remove a certain object from the world. This following code is in the world class and i keep getting the cannot find symbol error and i think the problem is that it doesn't know what the Y coordinate is for that object but i don't know how to let it know what the coordinates are.
public void removeCatcher()
    {
        if (getY(Ball.class) == 0)
        {
            removeObject();
        }
    }
danpost danpost

2016/10/21

#
A class does not have a coordinate in the world because a class is never in a world. Only objects created from an Actor subclass can be in a world. Also, the 'getX' method of the Actor class does not use any parameters -- the parenthesis after its name must remain empty. To get the y-coordinate of an Actor object in a world, you need a reference to it. While greenfoot executes the act method for that object, the 'this' keyword refers to it, which is, by default, what any method that does not follow an explicit reference is executed for (or on). At any rate, in the Catcher class, you need a reference to the Ball object. For example:
Ball ball = (Ball) getWorld().getObjects(Ball.class).get(0);
if (ball.getY() == 0)...
The first line will fail if no Ball object is in the world. However, you could check the size of the list returned before getting the reference to the ball:
if (!getWorld().getObjects().isEmpty()) // is a ball in world
{
    Ball ball = (Ball) getWorld().getObjects(Ball.class).get(0); // get reference to ball
    if (ball.getY() == 0)...
LimeLava LimeLava

2016/10/24

#
I did this and it works but when I try to start the game it automatically stops it. I also get this error java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 and it selects this line
Ball ball = (Ball)getObjects(Ball.class).get(0);
danpost danpost

2016/10/24

#
LimeLava wrote...
I did this and it works but when I try to start the game it automatically stops it. I also get this error java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 and it selects this line
Ball ball = (Ball)getObjects(Ball.class).get(0);
Well, I did write this:
The first line will fail if no Ball object is in the world. However, you could check the size of the list returned before getting the reference to the ball:
if (!getWorld().getObjects().isEmpty()) // is a ball in world
{
    Ball ball = (Ball) getWorld().getObjects(Ball.class).get(0); // get reference to ball
    if (ball.getY() == 0)...
LimeLava LimeLava

2016/10/24

#
I put that but I'll try again. The only thing I changed about it is that I removed the ! And getworld because I ended up putting it in the world
danpost danpost

2016/10/24

#
LimeLava wrote...
I put that but I'll try again. The only thing I changed about it is that I removed the ! And getworld because I ended up putting it in the world
You should not remove the '!'. But, also, I forgot to but 'Ball.class' in for the parameter of 'getObjects' on that same line. It should read like this for in a World subclass:
if (!getObjects(Ball.class).isEmpty())
LimeLava LimeLava

2016/10/25

#
So I have 3 Catcher Objects on top of each other which gives me some side area to "catch" the ball before it touches the ground it is also so that i will have some other chances after the first ball touches the ground to keep playing (Each catcher is respectively named Catcher, Catcher2, and Catcher3). What I have been trying to accomplish is when the ball touches the ground it removes on of them so that i only have 2 left. I have this for the code to remove one of them.
public void removeCatcher()
    {
        if (!getObjects(Ball.class).isEmpty())
        {
            Ball ball = (Ball)getObjects(Ball.class).get(0);
            Catcher catcher = (Catcher)getObjects(Catcher.class).get(0);
                if (ball.getY() == 400)
                {
                    removeObject(catcher);
                }
        }
    }
But nothing happens when a ball touches the ground ( Y == 400). What is wrong? ( this is in the world class )
danpost danpost

2016/10/25

#
LimeLava wrote...
But nothing happens when a ball touches the ground ( Y == 400). What is wrong? ( this is in the world class )
If your world is 400 pixels high, then the highest 'y' value is '399', not '400' (zero is the first possible 'y' value).
LimeLava LimeLava

2016/10/25

#
I changed that but it doesn't remove the Catcher for some reason
danpost danpost

2016/10/25

#
Stop the scenario at the point where you believe that the catcher should be removed. Then, right-click on the Ball and select 'Inspect' from the pop-up menu. Check the value of the 'y (hidden)' field to ensure that it is indeed '399'. If not, adjust the code accordingly. If it is, then you may need to post the code for the Ball class for further enlightenment (at least, to start with).
LimeLava LimeLava

2016/10/26

#
This is the ball class.
public class Ball extends Dropper
{
        private long curTime, prevTime;
    private static final long DELAY_TIME = 10; // in milliseconds
    /**
     * Act - do whatever the Ball wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        curTime = System.currentTimeMillis();
         if (prevTime +DELAY_TIME > curTime) {
          return;
        } else {
        prevTime = curTime;
    }
       setLocation (getX(),getY());
       remove();
       move(1);
       setRotation(90);
    }    
    public void remove()
    {
        if (isTouching(Catcher.class) || atWorldEdge())
       {
        getWorld().removeObject(this);
       }      
    }
        public boolean atWorldEdge()
    {
        if(getX() < 20 || getX() > getWorld().getWidth() - 20)
            return true;
        if(getY() < 20 || getY() > getWorld().getHeight() - 20)
            return true;
        else
            return false;
    }
    protected void addedToWorld(World world)
    {
       if ( ! getObjectsInRange(107, Ball.class).isEmpty() )
       {
        world.removeObject(this);
       }
    }
    
    
}
The Time stuff is to delay the spawning of the ball because i don't want them to spawn super fast. The At world edge is to remove them when they touch the ground. addedToWold is to stop them from spawning to close to each other.
danpost danpost

2016/10/26

#
A couple of improvements before dealing with the removal of the Catcher object when touching it. There is no need for an 'else' at line 14. The following code will not execute if the method is exited from by the return statement. Line 17 is pointless and can be removed. Setting the location of an object to where it already is located makes no sense. Line 20 has the rotation of the actor being set continuously to the same value in the act method. Better would be to place that line in the 'addedToWorld' method, where it is set only once, permanently. Also, since your ball only moves down the screen, you can simplify the 'atWorldEdge' method. And for what appears to be a exceptional issue, calling 'remove', which could remove the ball from the world, before calling 'move', which requires the actor in the world. Reverse the order of these calls so that you are guaranteed that the actor is in the world when calling 'move'. Finally, I believe the timer can be removed. If I am not mistaken, it will elapse time long before a ball is allowed to spawn in the world due to closeness of another ball. This leaves the class looking like this:
public class Ball extends Dropper
{
    public void act() 
    {
        move(1);
        remove();
    }
    
    public void remove()
    {
        if  (isTouching(Catcher.class) || atWorldEdge())
        {
            getWorld().removeObject(this);
        }      
    }
    
    public boolean atWorldEdge()
    {
        return getY() > getWorld().getHeight()-20;
    }

    protected void addedToWorld(World world)
    {
        setRotation(90);
        if (!getObjectsInRange(107, Ball.class).isEmpty())
        {
            world.removeObject(this);
        }
    }
}
Now, your method 'atWorldEdge' is limiting your ball to a y-coordinate of 'getWorld().getHeight()-20'. At that point, the ball will remove itself from the world. So, the last chance for the world to "see" the ball in the world is at a y-coordinate value of '379'.
LimeLava LimeLava

2016/11/7

#
(This is off topic but i didn't want to explain how this game works to everyone and I couldn't find my old post that has everything explained int it and you already know) So when the ball touches the ground to remove the catcher I get this error. "java.lang.IndexOutOfBoundsException: Index: 0, Size: 0" and it points to line 75 and 64 of this code and i dont really know what is wrong.
import greenfoot.*;
import greenfoot.core.WorldHandler;
import javax.swing.*;
import java.awt.Cursor;
import java.awt.Point;
import java.awt.Toolkit;
/**
 * Write a description of class background here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class background extends World
{
    JPanel Pan = WorldHandler.getInstance().getWorldCanvas();  
    /** The new Cursor */
    Cursor NewCursor;
    private int score;
    public int getscore()
    {
        return score;
    }

    public void bumpscore(int points)
    {
        score += points;
        showText("Score:" + score,80,25);
    }   

    /**
     * Constructor for objects of class background.
     * 
     */
    public background()
    {    
        // Create a new world with 600x400 cells with a cell size of 1x1 pixels.
        super(800, 400, 1, false); 
        addObject( new Catcher(), 400,325);
        addObject( new Catcher2(), 400,350);
        addObject( new Catcher3(), 400,375);
        addObject( new Dropper() ,400,150);

        /** You need a toolkit to Create a completly new Cursor */
        Toolkit Tk = Toolkit.getDefaultToolkit();
        /** The Cursor Point, where the cursor have to click from the left uppon corner of the Cursor Picture */
        Point CursorPoint= new Point(0,0);
        /** Now you create the new Cursor */
        NewCursor = 
            /** With the Toolkit you can Create a new Cursor */
        Tk.createCustomCursor(
            /** The Image, the Cursor should have, if you wont to clear the Cursor it have to be an empty Image */
            new GreenfootImage(5,5).getAwtImage(),
            /** The Cursor Point */
            CursorPoint,
            /** A Name for the new Cursor */
            "Somehow");
        showText("Score:" + score,80,25);

        prepare();
    }

    public void act()
    {
        removeCatcher();
        /** Sets the Cursor Image to the New Cursor */
        Pan.setCursor(NewCursor);

    }

    public void removeCatcher()
    {
        if (!getObjects(Ball.class).isEmpty())
        {
            Ball ball = (Ball)getObjects(Ball.class).get(0);
            Catcher catcher = (Catcher)getObjects(Catcher.class).get(0);
            if (ball.getY() >= 380)
            {
                removeObject(catcher);
            }
        }
    }

    /** Or you use this Method: 
     * The image is the image, that you want the mouse to have.(The mouse has a maximum width and height for her image, if the image is too large it will be scaled on the right size)
     * XClick and YClick is the Location on the Picture where the mouse will Click */
    public void ChangeMouseImage(GreenfootImage image, int XClick, int yClick)
    {
        JPanel Panel = WorldHandler.getInstance().getWorldCanvas();
        Cursor Cursor;
        Toolkit Tk = Toolkit.getDefaultToolkit();
        Point CursorPoint= new Point(0,0);
        Cursor = Tk.createCustomCursor(image.getAwtImage(),CursorPoint,"Somehow");
        Panel.setCursor(Cursor);
    }

    /**
     * Prepare the world for the start of the program. That is: create the initial
     * objects and add them to the world.
     */
    private void prepare()
    {
    }
}

I put all the code because i figured the line number would be off is i did not.
danpost danpost

2016/11/7

#
It is possible that no Catcher object is in the world. Therefore, you must ensure that one is before you can 'get' one from the List object returned by 'getObjects'. Change line 72 to:
if (!getObjects(Ball.class).isEmpty() && !getObjects(Catcher.class).isEmpty())
LimeLava LimeLava

2016/11/8

#
Ok i got that thanks. Now if i wanted to remove the second and third catcher but only after the one before it was removed would i just replace all the places there it says catcher with the name of the second catcher (Catcher2) and then do it again for the third one (Catcher3)?
    public void removeCatcher()
    {
        if (!getObjects(Ball.class).isEmpty() && !getObjects(Catcher.class).isEmpty())
        {
            Ball ball = (Ball)getObjects(Ball.class).get(0);
            Catcher catcher = (Catcher)getObjects(Catcher.class).get(0);
            if (ball.getY() >= 380)
            {
                    removeObject(catcher);
                    removeObject(ball);
                    
            }
        }
    }
There are more replies on the next page.
1
2