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

2014/2/20

Transfering information between parent and child actors

Excelsior Excelsior

2014/2/20

#
Hello, i'm working on a top down shooter game for my school. I have a question: How to make a child actor return values to a parent? In this case, a Robo actor spawns a laser actor every step. If one of those lasers hit the player actor, laser actor updates its PlayerX and PlayerY coordinates to where the collision occured. How do I return these values to its parent Robo?
Excelsior Excelsior

2014/2/20

#
This is the code with which the Robo spawns lasers every step.
1
2
3
4
5
6
public void radar() {
       Robo laser = new RoboLaser();
       getWorld().addObject(laser, getX(), getY());
       laser.setRotation(getRotation());
       laser.parent = this;
   }
And this is the code with which the laser finds the player.
1
2
3
4
5
6
public void findPlayer() {
        if (isTouching(Player.class) == true) {
            PlayerX = getX();
            PlayerY = getY();
        }
    }
danpost danpost

2014/2/20

#
For one thing, RoboLaser should probably not extend Robo. Robo seems to be the emitter while RoboLaser is what is emitted (two separate things with totally different states and behaviors). The code is close, however; except that the value should probably be passed back with 'parent.playerX = getX();' and similar for Y.
Excelsior Excelsior

2014/2/20

#
It says "cannot find symbol - variable PlayerX", maybe im doing something wrong? Oh, and it cant set lasers parent if its not extending Robo
danpost danpost

2014/2/20

#
Excelsior wrote...
It says "cannot find symbol - variable PlayerX", maybe im doing something wrong?
You will need instance fields in the Robo class for 'int playerX' and 'int playerY'.
Oh, and it cant set lasers parent if its not extending Robo
Why not? You can create an object of any subclass of Actor from the Robo class -- it does not have to extend it. You could make RoboLaser an inner-class of Robo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Robo extends Actor
{
    private int playerX = -1, playerY = -1;
    // code for Robo class
    // using 'new RoboLaser(this)' and 'if (playerX != -1) ...'
 
    private class RoboLaser extends Actor
    {
        private Robo parent;
 
        public RoboLaser(Robo robo)
        {
            parent = robo;
            // rest of constructor
        }
        // code for RoboLaser class
        // using 'playerX = getX();' and similar for Y
    }
}
} Then the RoboLaser class will have immediate access to fields of the Robo class.
Excelsior Excelsior

2014/2/20

#
I already had ints for playerX and Y in Robo class. When i change lasers extender, it automatically does not compile Robo.class because it says that it cant find symbol - variable parent.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
 
/**
 * Write a description of class Robo here.
 *
 * @author (your name)
 * @version (a version number or a date)
 */
public class Robo extends Subjektai
{
    int Sveikata = 100;
    int ZaidejasX;
    int ZaidejasY;
    int turndelay = 0;
    Actor zaidejas;
    Actor savininkas;
    boolean GaliSuktis = false;
    public boolean zaidejasAptiktas = false;
    /**
     * Act - do whatever the Robo wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act()
    {
        ArGaliSuktis();
        if (zaidejasAptiktas == false){
            radar();
            if (GaliSuktis == true) {
                turn(1);
                GaliSuktis = false;
                turndelay = 0;
            }
        }
        if (zaidejasAptiktas == true) {
            turnTowards(zaidejas.getX(),zaidejas.getY());
            move(2);
        }
        turndelay++;
    }
 
    public void radar() {
        Robo laser = new Robo_Laser();
        getWorld().addObject(laser, getX(), getY());
        laser.setRotation(getRotation());
        laser.savininkas = this;
        laser.ZaidejasX = 0;
        laser.ZaidejasY = 0;
    }
 
    public void ZaidejasAptiktas() {
        zaidejasAptiktas = true;
    }
 
    void ArGaliSuktis() {
        if (turndelay % 5 == 0) {
            GaliSuktis = true;
        }
    }
    
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
 
/**
 * Write a description of class RoboLaser here.
 *
 * @author (your name)
 * @version (a version number or a date)
 */
public class Robo_Laser extends Robo
{
    /**
     * Act - do whatever the RoboLaser wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act()
    {
        move(30);
        aptiktiZaideja();
        if (isTouching(Objektai.class) == true) {
            getWorld().removeObject(this);
            return;
        }
        if (atWorldEdge() == true) {
            getWorld().removeObject(this);
            return;
        }
    }
 
    public void aptiktiZaideja() { 
        if (isTouching(Zaidejas.class) == true) { 
            ZaidejasX = getX(); 
            ZaidejasY = getY(); 
        
     }  
}
Here are the full classes of those two objects
danpost danpost

2014/2/20

#
Excelsior wrote...
I already had ints for playerX and Y in Robo class. When i change lasers extender, it automatically does not compile Robo.class because it says that it cant find symbol - variable parent.
The 'parent' field should be in the RoboLaser class. I edited my last post. Take a look.
danpost danpost

2014/2/20

#
Also, you have 'Actor savininkas;' which should be 'Robo savininkas' (or the fields will not be found).
Excelsior Excelsior

2014/2/20

#
Thanks, it finally worked. And including one in another wasnt necessary, though it said "modifier private is not allowed here"
davmac davmac

2014/2/24

#
danpost wrote...
You could make RoboLaser an inner-class of Robo:
This could work, but RoboLaser extends actor and so has its own co-ordinates, which getX() and getY() will return. Where you have in the code:
1
// using 'playerX = getX();' and similar for Y
... you would actually need to use 'parent.getX()' and 'parent.getY()'. Although, because you've made this a non-static inner class, parent is redundant and you could eliminate the variable altogether and just use "Robo.this", eg "Robo.this.getX()". All in all, however, I'd suggest to Excelsior to steer clear of inner classes unless you know exactly how they work. It's certainly correct, though, that RoboLaser should not extend Robo.
danpost danpost

2014/2/24

#
davmac wrote...
... you would actually need to use 'parent.getX()' and 'parent.getY()'.
If you notice what is happening here, the Robo object creates a RoboLaser object; the RoboLaser object moves and when finds a Player object, it reports back to the Robo object the coordinates of the Player (or where the RoboLaser object is when encountering the Player object. So, I believe the code I had was correct. The 'playerX' and 'playerY' fields (which are in the Robo class), are set to the coordinates of the RoboLaser object when the Player object is encountered. EDIT: I understand the redundancy part. Thanks.
davmac davmac

2014/2/24

#
If you notice what is happening here, the Robo object creates a RoboLaser object; {snipped for brevity} So, I believe the code I had was correct.
Yes, sorry, I think you're right. Because of the lines:
1
2
PlayerX = getX(); 
PlayerY = getY(); 
... I had assumed that the player was the Robo itself, but I see now that there is a separate Player class. I do think it's better to avoid inner classes, though.
Excelsior Excelsior

2014/3/26

#
I'm finally done with the project, here is the link : http://www.greenfoot.org/scenarios/11170 Sorry for bumping an old thread, couldn't figure out a way to PM you. Thanks for the help making this game! :D
You need to login to post a reply.