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

2013/1/31

Getting location of an actor from an actor

1
2
3
student101 student101

2013/2/1

#
Thanks davmac, the code worked when I tested it on my actor. I tried to use it for something else but it came up with an error. Essentially, what I want to happen is that there is a world change (to the battle world) when the player hits another actor. Answering a question correctly would then lead to a AnswerCorrectWorld which is basically a world with the words 'correct, please press enter to continue' in it. Pressing enter would take take them back to the world and position they were in before they hit the actor. The actor that is getting transported has this code:
 public void CheckCollision()
    {
        Actor snake = getOneObjectAtOffset(0, 0, Snake.class);
        if (snake != null)
        {
            int battle = 1;
            World nextWorld = new AnswerCorrectWorld();
            Actor mouse = (Actor)getWorld().getObjects(Mouse.class).get(0);
            nextWorld.addObject(mouse, 50, 50);
            Greenfoot.setWorld(new BattleFight());
As you can see the mouse actor is transported to a different world and the game loads the Battle world. I did this because the mouse actor has methods inside it that I don't want activating in the battle world. So I sent the mouse to another world where I can store it temporarily in a sense. However, when the game finally gets to the AnswerCorrectWorld, the mouse isn't there? Just in case it was hidden beneath the text that's in the world, I carried on with the code and implemented it into the 'PressEnterToContinue' class where upon pressing the enter key, the user is transported back to the first world.
public class PressEnterToContinueCorrectAnswer extends PressEnterToContinue
{
    /**
     * Act - do whatever the PressEnterToContinueCorrectAnswer wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        setImage(new GreenfootImage("Press Enter to Continue", 35, Color.WHITE, Color.BLACK));
        World World  = getWorld();
        if ("enter".equals(Greenfoot.getKey())) 
        {
            World nextWorld = new GameWorld(); 
            Actor mouse = (Actor)getWorld().getObjects(Mouse.class).get(0);  
            nextWorld.addObject(mouse, 391, 209);  
            Greenfoot.setWorld(nextWorld);
        }
        
        } 
        
    }    
davmac davmac

2013/2/1

#
However, when the game finally gets to the AnswerCorrectWorld, the mouse isn't there?
Are you setting the same world as you added the mouse to, or are you creating a new world? Each time you use 'new' in the code you get a new object, distinct from any others you may have created previously.
student101 student101

2013/2/1

#
I think I'm creating a new world davmac. Would I have to implement your code into the the class where it says to change to the new world?
davmac davmac

2013/2/1

#
Either that, or use the same world that you added the mouse to.
student101 student101

2013/2/1

#
Okay, that didn't work. I'm thinking of tackling this from another angle. How about the mouse is carried over to the next world but it's invisible? It only then becomes visible again when the player returns to the original world. But then that means that the mouse would constantly have to check worlds, which I don't know how to do yet.
danpost danpost

2013/2/2

#
If you are worried about the code in Mouse being execute while a world it is not in is active, don't. The act methods are only executed on the active world and any actor objects in that (active) world. Also, when you return to that same world that the mouse is in, everything that you did not specifically change will be as it was when you left it. You may want to take a look at the code in my Crayon Babies scenario. It has multiple uses of changing worlds. And the GameWorld world is the only thing I think you have to pass. The snake and the mouse are not really active in any world except the GameWorld. Is that not correct?
student101 student101

2013/2/2

#
I think what you're saying is true. The GameWorld is where the player can move and interact with other actors. The next worlds contain new instances of the mouse and the snake but they're using arrows to choose options instead of making the mouse move etc. I think I've managed to make the mouse check worlds using the instanceof code, so what I've done is made it check which world it is in and set its transparency to zero until it reaches the initial world again. However, once it does end back in GameWorld, there are two instances of the mouse in the world when there should only be one. So I thought that I should create a code where the world checked if an instance of the mouse is at a specific location, and if it is it is removed from the world. I'm thinking of using the instanceof code again but i don't know how to use it in relation to actors. But what I have so far is that once the mouse is finally transported back to the GameWorld with its new location, the actor beneath it (the snake) is removed. However it doesn't seem to be working. I'm wondering if instead of trying to remove the snake from the world class I should try to do it from another actor class? Using the removeObject command doesn't work in actors though.
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class GameWorld here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class GameWorld extends World
{

    /**
     * Constructor for objects of class GameWorld.
     * 
     */
    public GameWorld()
    {    
        // Create a new world with 600x400 cells with a cell size of 1x1 pixels.
        super(600, 400, 1); 
        setBackground("sand.jpg");

        prepare();
        Actor mouse = (Actor)getObjects(Mouse.class).get(0);
        
        
        
    }

    /**
     * Prepare the world for the start of the program. That is: create the initial
     * objects and add them to the world.
     */
    private void prepare()
    {
        Shrubs shrubs = new Shrubs();
        addObject(shrubs, 498, 93);
        Shrubs shrubs2 = new Shrubs();
        addObject(shrubs2, 479, 276);
        Shrubs shrubs3 = new Shrubs();
        addObject(shrubs3, 296, 356);
        Shrubs shrubs4 = new Shrubs();
        addObject(shrubs4, 316, 42);
        Mouse mouse = new Mouse();
        addObject(mouse, 128, 188);
        Snake snake = new Snake();
        addObject(snake, 427, 192);
        snake.setLocation(388, 209);
        snake.setLocation(391, 209);
        if (mouse.getX()==391 && mouse.getY()==209)
      {
            removeObject(snake);
            
       }
        
    }
}
danpost danpost

2013/2/2

#
Well, all I was trying to convey, is that you can code the 'checkCollision' method in the Mouse class as follows:
public void checkCollision()
{
    Actor snake = getOneObjectAtOffset(0, 0, Snake.class);
    if (snake != null)
    {
        getWorld().removeObject(snake);
        setLocation(391,209);
        Greenfoot.setWorld(new BattleWorld(getWorld()));
    }
}
The last three statements can be coded in any order with the same result.
student101 student101

2013/2/2

#
Oh my, I didn't even think of removing the object at that part! It's a lot simpler now, however the code won't compile because something's wrong with the '(new BattleWorld(getWorld()))' part of the code?
danpost danpost

2013/2/2

#
I was showing the example of passing the GameWorld object in the constructor; but your BattleWorld constructor needs to be adjusted to recieve it.
student101 student101

2013/2/2

#
For a while I was wondering what you meant but after looking at the crayon babies code I finally understood what you meant by the constructor. I need arguments etc. But what would those arguments be? I have no idea? Essentially, danpost, I just want to know if there's away to switch between different worlds without having to create new instances of it, because removing/adding objects become pointless if in the end, the entire world gets resetted.
danpost danpost

2013/2/2

#
I guess you did not look close enough. The main world in my aforementioned scenario is the same world throughout. I think InfoWorld and MenuWorld are create anew each time, but not so with the main world. You may want to look at again, and take special note as to the state of the world when MenuWorld is called, and compare that with the state of the world when you return to it. It continues right where it left off, as if paused; which is exactly what happens. The argument would be the world you want to return to. Then BattleWorld constructor should look something like this:
public class BattleWorld extends World
{
    World gameWorld;

    public BattleWorld(World world)
    {
        super(....)// whatever
        gameWorld=world;
        // etc.
//  pass it the same way to next world
// when returning to main world
Greenfoot.setWorld(gameWorld);
student101 student101

2013/2/3

#
I'm understanding certain parts of what you're saying but generally I'm still quite confused. I've implemented your code into the worlds necessary as can be seen here:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class AnswerCorrectWorld here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class AnswerCorrectWorld extends World
{
    World gameWorld;
    /**
     * Constructor for objects of class AnswerCorrectWorld.
     * 
     */
    public AnswerCorrectWorld(World world)
    {    
        // Create a new world with 600x400 cells with a cell size of 1x1 pixels.
        super(600, 400, 1); 
        gameWorld = world;
        addObject (new PressEnterToContinueCorrectAnswer(), 306, 230);
        prepare();
         if ("enter".equals(Greenfoot.getKey())) 
        {
         Greenfoot.setWorld(gameWorld);  
        }
    }

    /**
     * Prepare the world for the start of the program. That is: create the initial
     * objects and add them to the world.
     */
    private void prepare()
    {
        CorrectAnswerWorldText correctanswerworldtext = new CorrectAnswerWorldText();
        addObject(correctanswerworldtext, 301, 199);
    }
}
I think all of that is correct. However, when I try to compile there is a problem with the actor that makes the player go to the next world in the first place:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class BattleArrow here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class BattleArrow extends Arrow
{
    /**
     * Act - do whatever the BattleArrow wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        BattleKeys();
        CheckEnterBattle();
        
    }
    
     public void CheckEnterBattle()    
    {    
         if (getX()==41 && getY()==332 && "enter".equals(Greenfoot.getKey())) 
         { 
            World nextWorld = new AnswerCorrectWorld(); // there is apparently a problem with this line, something to do with no arguments.  
            Greenfoot.setWorld(nextWorld);
        }
    }        
}
davmac davmac

2013/2/3

#
Your AnswerCorrectWorld constructor requires an argument. You've declared it as:
    public AnswerCorrectWorld(World world)  
... this is so you can pass it another world, which it then should set once enter is pressed. However, in BattleArrow, you construct a new AnswerCorrectWorld, but you don't give it an argument:
World nextWorld = new AnswerCorrectWorld( /* argument goes here! */ );
See how they don't match? Your constructor requires an argument, but you don't supply one when you create a new world. You need to pass the world that you want to restore as the argument to the constructor.
student101 student101

2013/2/3

#
Yeah, I see that now, but I don't know what arguments the world should have? I just want to make the player switch to a saved state of GameWorld really.
There are more replies on the next page.
1
2
3