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

2017/6/13

get one intersecting object confused me

lookaround lookaround

2017/6/13

#
Hello, I made a frogger, but came onto a problem wit getOneInterSectingObject, with trying somethings out, i made it work. But now i don't understand why it does work like this and not in the "original" way. Can someone enlighten me ? The part that doesn't work is my reference to log.getIsAtRightEdge()
    /**
     * Does Work !
     * If the frog is on a log
     * move with the log
     */
    private void moveOnTheLog()
    {
        Log log2 = (Log) getOneIntersectingObject(Log.class);
        if ( log2.getIsAtRightEdge() == true ){
            setLocation(getX()-Log.LOG_SPEED, getY());  
        }
        else {
            setLocation(getX()+Log.LOG_SPEED, getY()); 
        }
    }





    /**
     * Doesn't Work !
     * If the frog is on a log
     * move with the log
     */
    private void moveOnTheLog()
    {
        Actor log = getOneIntersectingObject(Log.class);
        if ( log.getIsAtRightEdge() == true ){
            setLocation(getX()-Log.LOG_SPEED, getY());  
        }
        else {
            setLocation(getX()+Log.LOG_SPEED, getY()); 
        }
}
Thanks in advance.
Super_Hippo Super_Hippo

2017/6/13

#
If you have 'log' as an actor, it can't find methods from the Log class. 'getOneIntersectingObject' will return an object of type actor (or null) no matter what class you use as the parameter. However, I am not really seeing what you are trying to achieve with the code and usually it should start like this:
Log log = (Log) getOneIntersectingObject(Log.class);
if (log != null)
{
    //...
}
lookaround lookaround

2017/6/13

#
Hi, The idea was to find out whether the boolean ( getIsAtRightEdge ) is stated true or false. Based on that statement, my frog had to go left or right. So i wanted to put the log that the frog was touching into "log" so i could find out if the log was coming from the right ( true ) or it was coming from the left ( false )
Yehuda Yehuda

2017/6/13

#
Your second method has 'log' being an instance of Actor where there is no method such as getIsAtRightEdge in the Actor class. Another problem is you didn't say what about it isn't working and you don't need the '== true' in the 'if' statement, just leaving it plain is the same thing. (What Hippo said is still/also true.)
lookaround lookaround

2017/6/13

#
@Yehuda, actually you cleared it a bit for me. By declaring log2 as an instance of log. I had to verify the boolean getIsAtRightEdge that is located in my Log.class to determine if my actor ( in this case Frog.class) needed to move left or right. That's the part that doesn't work in "log" and it does in "log2". I can't acces the boolean --------------------- Maybe this can help ---------------------- My frog is in the world If my frog is on the water and on a log, he needs to move with the log The log, when created in, gets a boolean determining if its going to the left or to the right If my frog is on a log, find out if its coming from the right, if so move with the log to the right, if not visa versa. so i want to see the boolean only for that one log i'm on.
// the boolean i'm referring to


    // boolean isAtRightEdge is given by the world : Crossing
    private boolean isAtRightEdge;

    public Log(boolean isItRight){
        isAtRightEdge=isItRight;
    }
    
    // Make the boolean accessible to other classes
    public boolean getIsAtRightEdge(){
        return isAtRightEdge;
    }
Yehuda Yehuda

2017/6/13

#
So is everything OK now or you still have a question?
lookaround lookaround

2017/6/14

#
Yes, if i put this Log log2 = (Log) getOneIntersectingObject(Log.class), why do i need the extra (Log), since i don't need it if i start the statement with Actor.
Super_Hippo Super_Hippo

2017/6/14

#
getOneIntersectingObject(Log.class) returns an Actor (or null). If you save it as a variable of type Actor, there is no problem. But if you are trying to save it as a variable of type Log, it has to be casted to a Log object because not every Actor is a Log. Even though having the Log class as the parameter for the method is making sure that the Actor is indeed a Log, but the method still returns an Actor. Maybe this will be changed in some future version of Greenfoot, but maybe there is also a reason why it is not the case.
Yehuda Yehuda

2017/6/14

#
Super_Hippo wrote...
Even though having the Log class as the parameter for the method is making sure that the Actor is indeed a Log, but the method still returns an Actor. Maybe this will be changed in some future version of Greenfoot, but maybe there is also a reason why it is not the case.
It's not possible to be changed in a later version of Greenfoot since Greenfoot doesn't know what to make the method return. How can they make a method return an extension of actor if that extension/child was created by you? (The closest they can get is type Actor.)
danpost danpost

2017/6/15

#
Yehuda wrote...
It's not possible to be changed in a later version of Greenfoot since Greenfoot doesn't know what to make the method return. How can they make a method return an extension of actor if that extension/child was created by you? (The closest they can get is type Actor.)
We know that it returns some type of Actor. It should be possible to use generics ( <? extends Actor> ) to return whatever type is called for. Something like this, for example:
public <A extends Actor> A getIntersector(Class clss)
{
    return (A) getOneIntersectingObject(clss);
}
Let us say you want to get a reference to any Brick object that intersects a Ball object. Then you would have the above method in the Ball class or any class it extends from and the following line:
Brick brick = getIntersector(Brick.class);
Note that there is no cast in this line and yet the method does not know what type you will use prior to it being invoked.
Super_Hippo Super_Hippo

2017/6/15

#
There are actually a lot of methods which do that already. And I think they added it with the new API (even though I am not sure). For example the getObjects method in World. It returns a List of the type you pass. So this one works without casting:
Counter counter = getWorld().getObjects(Counter.class).get(0);
However, it only works for methods which return a List, not for those which return one single object. So this line does not need a cast:
Enemy enemy = getIntersectingObjects(Enemy.class).get(0);
but this one does:
Enemy enemy = (Enemy) getOneIntersectingObject(Enemy.class);
That's why I think it could be improved in the future.
You need to login to post a reply.