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

2013/10/25

Worldswap with shift

1
2
Baenefin Baenefin

2013/10/25

#
Hi there, I am trying something daring (for me) What I am trying to do is, when the imput is shift I would like to transfer to another level (Level0). I want to place the player in the same coords as in Level1. And when shift is pressed again, I would like to return to Level1. So what I think i need is: -2 world -shift input goes to Level0(if in Level1) or Level1(if in level0) and no shift input stays in the current world. -Remember coords. Sofar I have this
public class Level1 extends SWorld
{

    public Level1()
    {    
        this (new Alice());

    }

    public Level1(Alice alice)
    {    
        super(800, 400, 1, 2400); 

        //Player
        setMainActor(new Alice(),10,340);
        mainActor.setLocation(200, 340);
        
        //Background
        GreenfootImage bg = new GreenfootImage("Test.jpg");
        setScrollingBackground(bg);
        
        //Counter
        addObject(new Score(), 30, 10, false);
        addObject(new ShroomScore(), 130, 10, false);

        //Level blocks
        for(int i=1;i<75;i++)
        {
            addObject(new Block(), i*30-15, 384,true);
        }

}
public class Level0 extends SWorld
{


        public Level0()
    {    
        this (new Alice());

    }
    
    public Level0(Alice alice)
    {    
        super(600, 400, 1, 2400); 
        setMainActor(new Alice(),600,340);
        mainActor.setLocation(200, 340);
        
        //Background
        GreenfootImage bg = new GreenfootImage("Forest.jpg");
        setScrollingBackground(bg);
        
        //Counter
        addObject(new Score(), 30, 10, false);
        addObject(new ShroomScore(), 130, 10, false);

        
        //Blocks
                for(int i=1;i<75;i++)
        {
            addObject(new Block(), i*30-15, 384,true);
        }
    }
}
My character has:
private int level;

    public void act() 
    {
checkKeys();
checkFall();
CheckCollisionBlock();
}

 private void checkKeys()
    {
if (Greenfoot.isKeyDown("shift") )
        {
            if (level != 1) {
                level = 0;
                Greenfoot.setWorld(new Level1a(this));
            }
            else {
                level = 1;
                getWorld().removeObject(this);
                Greenfoot.setWorld(new Level1(this));
            }
        }
private void checkFall()
    {
        if (onGround()) {
            setVSpeed(0);          
        }
        else {
            fall();
        }
    }
public void CheckCollisionBlock()
    {
        // check below the actor
        while(getOneObjectAtOffset(0, getImage().getHeight()/2+1, Block.class)!=null)
        {
            setLocation(getX(), getY()-1); 
            onGround=true; 
            vSpeed=0;
        }
        // check above the actor
        while(getOneObjectAtOffset(0, -getImage().getHeight()/2-1, Block.class)!=null) 
        {
            setLocation(getX(), getY()+1);
            vSpeed = 0;
        }
        // check to right of actor
        while(getOneObjectAtOffset(getImage().getWidth()/2+1, 0, Block.class)!=null)
        {
            setLocation(getX()-1, getY());
            vSpeed = 0;
        }
        // check to left of actor
        while(getOneObjectAtOffset(-getImage().getWidth()/2-1, 0, Block.class)!=null)
        {
            setLocation(getX()+1, getY());
            vSpeed = 0;
        }
}
If the input is shift, I transport to another world on given coords (setLocation in Level0) So if I want to teleport back to Level1, what would be the way to go. Make a shift counter and every shift teleports to the other world or does anybody have another idea?
davmac davmac

2013/10/25

#
I may be confused about what you want. The code you have looks like it already allows the shift key to switch between two levels (well, kind of).
            if (level != 1) {  
                level = 0;  
                Greenfoot.setWorld(new Level1a(this));  
            }  
            else {  
                level = 1;  
                getWorld().removeObject(this);  
                Greenfoot.setWorld(new Level1(this));  
            }  
The main thing I see that's wrong with this is the initial check:
            if (level != 1) {  
                level = 0;  
So if level doesn't equal 1, then you set it to 0. So: If the level is already 0, then you set it to 0. And then you set the world to a "Level1a" instead of "Level0" anyway. I think the condition probably needs to be changed:
            if (level != 0) {  
                level = 0;  
Then, you pretty much have what you want - the ability to switch between two different levels. You just need to save the actor's location before switching and set it again afterwards. I'm assuming that the setMainActor(...) method adds the actor into the world (you haven't posted the code for the SWorld class).
Baenefin Baenefin

2013/10/25

#
Hi and thanks for the input. My SWorld is from danpost superscrolling world. My level1 and Level1a(now called level0) set the MainActor. If I change the code to
        if (Greenfoot.isKeyDown("shift") )  
        {  
            if (level != 0) {    
                level = 0;    
                Greenfoot.setWorld(new Level0(this));    
            }    
            else {    
                level = 1;    
                getWorld().removeObject(this);    
                Greenfoot.setWorld(new Level1(this));    
            }     
        }
I get an error 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 interted, or it has been removed. If i keep it as it was. I teleport to level0 and shift again stays in level0 (as the code implies, I had no clue as how to switch back)
davmac davmac

2013/10/25

#
If I change the code to ... I get an error 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 interted, or it has been removed.
Where exactly do you get that error, what is the stack trace?
Baenefin Baenefin

2013/10/25

#
davmac wrote...
If I change the code to ... I get an error 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 interted, or it has been removed.
Where exactly do you get that error, what is the stack trace?
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 interted, or it has been removed. at greenfoot.Actor.failIfNotInWorld(Actor.java:663) at greenfoot.Actor.getOneObjectAtOffset (Actor.java:867) at Mover.onGround(Mover.java:29) at Alice.checkFall(Alice.java:85) at Alice.act(Alice.java:21) The onGround code
     public boolean onGround()
    {
    Block a = (Block) getOneObjectAtOffset(0,32,Block.class);
    return a !=null;
    }
The Alice code
private void checkFall()
    {
        if (onGround()) {
            setVSpeed(0);          
        }
        else {
            fall();
        }
    }
Alice act code public void act() { checkKeys(); checkFall(); }
danpost danpost

2013/10/25

#
In the act method, after 'checkKeys', insert the following line:
if (getWorld == null) return;
The 'shift' key can only be detected by the 'isKeyDown' method which by itself will register true for multiple act cycles while the key is in the down state. This would cause your worlds to toggle back and forth quickly until the key is released. If you insist on using the 'shift' key, you will need a boolean field to track the state of the key. A method called from act in the Alice class would be something like this:
// instance field
boolean shiftDown;
// method
public void checkShiftDown()
{
    if (shiftDown && !Greenfoot.isKeyDown("shift")) shiftDown = false;
    if (shiftDown) return;
    if (Greenfoot.isKeyDown("shift"))
    {
        shiftDown = true;
        int x = getUnivX(), y = getUnivY();
        int xOffset = getX()-x, yOffset = getY()-y;
        SWorld sworld;
        if (getWorld() instanceof Level1) sworld = new Level0(this);
        if (getWorld() instanceof Level0) sworld = new Level1(this);
        sworld.mainActor.setLocation(sworld.mainActor.getX()+xOffset, sworld.mainActor.getY()+yOffset);
    }
}
Baenefin Baenefin

2013/10/25

#
danpost wrote...
In the act method, after 'checkKeys', insert the following line:
if (getWorld == null) return;
The 'shift' key can only be detected by the 'isKeyDown' method which by itself will register true for multiple act cycles while the key is in the down state. This would cause your worlds to toggle back and forth quickly until the key is released. If you insist on using the 'shift' key, you will need a boolean field to track the state of the key. A method called from act in the Alice class would be something like this:
// instance field
boolean shiftDown;
// method
public void checkShiftDown()
{
    if (shiftDown && !Greenfoot.isKeyDown("shift")) shiftDown = false;
    if (shiftDown) return;
    if (Greenfoot.isKeyDown("shift"))
    {
        shiftDown = true;
        int x = getUnivX(), y = getUnivY();
        int xOffset = getX()-x, yOffset = getY()-y;
        SWorld sworld;
        if (getWorld() instanceof Level1) sworld = new Level0(this);
        if (getWorld() instanceof Level0) sworld = new Level1(this);
        sworld.mainActor.setLocation(sworld.mainActor.getX()+xOffset, sworld.mainActor.getY()+yOffset);
    }
}
cannot find symbol - method getUnivX()
danpost danpost

2013/10/25

#
Sorry, I forgot the arguments. Change line 11 to:
int x = getUnivX(getX()), y = getUnivY(getY());
Baenefin Baenefin

2013/10/25

#
Now I get cannot find symbol - method getUnivX(int)
danpost danpost

2013/10/25

#
Sorry, again. This code is not in the world class, but in an Actor class. So, it needs changed to this:
int x = ((SWorld)getWorld()).getUnivX(getX());
int y = ((SWorld.getWorld()).getUnivY(getY());
Baenefin Baenefin

2013/10/25

#
Ok so it asks for a bracket behind int y = ((SWorld.getWorld()).getUnivY(getY()). int x works fine. int y gives an error. Asks for a bracket behind and if i add it, it says cannot find symbol - method getWorld()
danpost danpost

2013/10/25

#
Just had a dot in place of a closing paren:
int x = ((SWorld)getWorld()).getUnivX(getX());
int y = ((SWorld)getWorld()).getUnivY(getY());
Baenefin Baenefin

2013/10/25

#
Ok that works, now it gives me an error cannot find symbol - variable getWorld (in the act, if (getWorld == null) return; )
danpost danpost

2013/10/25

#
I must be half asleep this morning (missing parens):
if (getWorld() == null) return;
Baenefin Baenefin

2013/10/25

#
danpost I am just happy I am getting help. I'm getting this error now variable sworld might not have been initialized the first sworld is highlighted red.
sworld.mainActor.setLocation(sworld.mainActor.getX()+xOffset, sworld.mainActor.getY()+yOffset);
There are more replies on the next page.
1
2