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

2016/4/12

Help With an Error?

nathanathan nathanathan

2016/4/12

#
I am trying to make it so when my play touches a platform, he gets teleported to the top of said platform, while retaining his x coordinate. There is also a gravity aspect to my game. However, when I run the program, I get this error: java.lang.IllegalStateException: Actor not in world. An attempt was made to use the actor's location while it is not in the world. Either it has not yet been inserted, or it has been removed. And when I click on it, it highlights this line of code:
  Actor plat = (Platform)getOneIntersectingObject(Platform.class); 
import greenfoot.*;
public class Player extends Actor
{    
    private int accel = 1;
    public int vSpeed = 0;
    public void act() 
    {
        onGround();
        moving();        
        checkFall();
    } 
    public void moving()
    {
        if(Greenfoot.isKeyDown("a"))
        {
            setRotation(180);
            move(3);
            setRotation(0);
        }
        if(Greenfoot.isKeyDown("d"))
        {
            setRotation(0);
            move(3);
        }
        if ("space"==(Greenfoot.getKey()))
        {
            jump();
        }
    }
    boolean onGround = false;   
    Actor plat = (Platform)getOneIntersectingObject(Platform.class);    
    int newY = plat.getY();
    public void onGround()
    {
        if(isTouching(Platform.class))
        {            
            setLocation(getX(), newY);
            onGround = true;
        } 
        else
        {
            onGround = false;
        }
    }    
    public void checkFall()
    {   
        if(onGround)
        {
            vSpeed = 0;
        }
        else
        {
            falling();
        }  
    }  
    public void falling()
    {
        setLocation(getX(), getY() + vSpeed);      
        vSpeed = vSpeed + accel;
    }
    public void jump()
    {
        if(onGround)
        {   
            vSpeed = -14;
            falling();
        }
    }
}
danpost danpost

2016/4/12

#
You have lines 31 and 32 outside of any method within the class. As such, they are executed when the object is created from the class -- long (in computer time) before the actor being created is added into any world. You cannot execute any methods like 'getOneIntersectingObject' or 'getX()' on any object that is not currently in a world without code failure. Lines with those type of methods must be called within the act method or within a method that is called by the act method and the calling of such methods must be done while the actor is still in the world (the actor cannot be removed from the world before calling any of those type methods). The two lines, lines 31 and 32, would be better placed as the first two lines in the 'onGround' method; however, you need to ensure that 'plat' is not 'null' before you try to get a location coordinate from it.
nathanathan nathanathan

2016/4/14

#
Hi Danpost, thank you for the response. I put the two lines of code in onGround(), as you suggested, however I am not sure how to ensure that "plat" is not equal to null. I am getting an error: java.lang.NullPointerException at Player.onGround(Player.java:34) at Player.act(Player.java:8) and as I said before, I think it is because I don't have plat != to null.
danpost danpost

2016/4/14

#
Actually, you do not need to check for null. Just move those lines (including the 'newY' assignment line inside the 'if' block.
nathanathan nathanathan

2016/4/14

#
Awesome! It works great. There is just one more thing. Every time it touches the platform, it re-sets the location back to the platform, making it impossible to jump. Do you have any ideas on how to prevent this? - Thank you for your help thus far!
danpost danpost

2016/4/14

#
nathanathan wrote...
Every time it touches the platform, it re-sets the location back to the platform, making it impossible to jump.
Will need to see the code of the player to see what you have going on.
nathanathan nathanathan

2016/4/15

#
Ok, here is my player class:
import greenfoot.*;
public class Player extends Actor
{    
    private int accel = 1;
    public int vSpeed = 0;
    boolean jumping;
    public void act() 
    {
        onGround();
        moving();        
        checkFall();
    } 
    public void moving()
    {
        if(Greenfoot.isKeyDown("a"))
        {
            setRotation(180);
            move(3);
            setRotation(0);
        }
        if(Greenfoot.isKeyDown("d"))
        {
            setRotation(0);
            move(3);
        }
        if ("space"==(Greenfoot.getKey()))
        {
            jump();
        }
    }
    boolean onGround = false;
    int count = 0;
    public void onGround()
    {               
        if(isTouching(Platform.class))
        {             
            Actor plat = (Platform)getOneIntersectingObject(Platform.class);
            int newY = plat.getY();
            setLocation(getX(), newY - 14);
            onGround = true;                       
        } 
        else
        {
            onGround = false;
        }
    }    
    public void checkFall()
    {   
        if(onGround)
        {
            vSpeed = 0;
        }
        else
        {
            falling();
        }  
    }  
    public void falling()
    {
        setLocation(getX(), getY() + vSpeed);      
        vSpeed = vSpeed + accel;
    }

    public void jump()
    {
        if(onGround)
        {
            vSpeed = -200;
            falling();            
        }
    }
}
I realized now, that when I increase vSpeed in the jump method:
public void jump()
    {
        if(onGround)
        {
            vSpeed = -200;
            falling();            
        }
    }
I no longer have the issue of not being able to leave the platform, but the jump isn't a normal jump, but rather a teleport. It will teleport off of the platform (the height it teleports depends on what I change vSpeed to in my jump() method), and will fall normally. I have looked at it but cannot figure out what is happening, so any help would be much appreciated!
danpost danpost

2016/4/15

#
Since I do not have your images, I would like you to try something. Change your 'onGround' method to the following and report back the results after a jump:
public void onGround()
{
    if(isTouching(Platform.class))
    {            
        Actor plat = (Platform)getOneIntersectingObject(Platform.class);    
        int newY = plat.getY();
        setLocation(getX(), newY-(plat.getImage().getHeight()+getImage().getHeight())/2);
        onGround = true;
        int dist = 0;
        while (intersects(plat))
        {
            dist++;
            setLocation(getX(), getY()-1);
        }
        System.out.println("Pixels inside platform:  "+dist);
    } 
    else
    {
        onGround = false;
    }
}
nathanathan nathanathan

2016/4/15

#
Ok, so first of all the console outputs: Pixels inside platform: 0 a bunch of times. In game, the player is bobbing up and down about a pixel really fast, and I can only jump occasionally (and when I do, it still teleports, however I fall normally).
danpost danpost

2016/4/15

#
nathanathan wrote...
Ok, so first of all the console outputs: Pixels inside platform: 0 a bunch of times.
Oh, drats. What I wanted to see was probably in the middle of the bunch of times. Try this then (hopefully it will stop when stopping on a platform):
public void onGround()
{
    if(isTouching(Platform.class))
    {            
        Actor plat = (Platform)getOneIntersectingObject(Platform.class);    
        int newY = plat.getY();
        setLocation(getX(), newY-(plat.getImage().getHeight()+getImage().getHeight())/2);
        int dist = 0;
        while (intersects(plat))
        {
            dist++;
            setLocation(getX(), getY()-1);
        }
        System.out.println("Pixels inside platform:  "+dist);
        setLocation(getX(), getY()+dist);
        Greenfoot.stop();        onGround = true;
    } 
    else
    {
        onGround = false;
    }
}
danpost danpost

2016/4/15

#
Btw, this is not an attempt to fix the issue. It is an attempt to find the cause.
nathanathan nathanathan

2016/4/15

#
Ok, so this is the exact output of the console:
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
Pixels inside platform:  0
danpost danpost

2016/4/15

#
It seems a bit better after switching the order of calls in the act method. First move, then check on-ground state.
danpost danpost

2016/4/15

#
The shaking (or the bobbing up and down issue) is due to the when you check for on ground and when you fall. First move, next fall, then check new on-ground state. I did not say to "check fall" -- I said "fall". This will allow the proper on-ground state to be detected. If you check before falling, it will result in a not on-ground state on one act cycle -- then on the next cycle, it will fall and find the ground, which will have the actor moved back off the ground again (hence the bobbing).
danpost danpost

2016/4/15

#
I forgot to mention, setting 'vSpeed' to zero should be done when found on ground (in the 'onGround' method); and for falling, use something like this:
public void fall()
{
    vSpeed = vSpeed+accel;
    setLocation(getX(), getY()+vSpeed;
}
You need to login to post a reply.