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

2016/4/4

Calling private variables from a class to another one

MrSandwich MrSandwich

2016/4/4

#
Hello, in order to follow my teacher orders and to use encapsulation I mustn't have any public variables so I'm trying to declare them as private in one class but I'm in owe to use them in another class. How would I should i proceed in orther to do this? Example of what I'm trying to do:
1
2
3
public class Tank extends Actor{
private static bullets =40;
}
Then in the tank class i want to be able to access the bullets variable like so:
1
2
3
public class Tank extends Actor{
Bullet.bullets ... // do something
}
So if I had the variable declared has public static this would work, but since I need to declare them all private (teacher request) I don't know what should I do, if that's even possible in Greenfoot. Thanks
danpost danpost

2016/4/4

#
First, if you want each Tank object created from the Tank class to have its own set of bullets (or a unique bullet value) then the field should not be made 'static'. Now, as 'private', you will need what is called a public "getter" method that returns the value of the field. You will not be able to access the field itself from outside the class, but you will be able to get the value of the field indirectly through the method.
MrSandwich MrSandwich

2016/4/4

#
The first class was named wrong, it should have been read "class Bullet" . The thing is I only have one type of bullets, and no class other than the Tank class uses those bullets. For the second part I did some more research and can I use this?
1
2
3
4
public Bullet getBullet()  //in the MyWorld class
    {        
        return bullets;
    }
then in the tank class use this
1
2
3
4
5
MyWorld world = (MyWorld)getWorld();
         Bullet bullets = world.getBullet();
//...
 
  bullet.getBullet();
Would this return the number of bullets the variable contains? Or am I still missing something?
danpost danpost

2016/4/4

#
There is indeed something very important you are missing. Your declaration of the 'bullets' field is missing the type of field that 'bullets' is to be. Since its value will always be a non-negative whole number, 'int' would be an appropriate type:
1
private int bullets = 40;
The "getter" method should be in the same class as where the field is and it should show a return type that is the same as the type of the field whose value is to be returned. Therefore,
1
2
3
4
public int getBulletCount()
{
    return bullets;
}
would be sufficient (I adjusted the name of the method to more signify what the method does). The Bullet class is not where the field should be, though. A bullet does not have a bullet count; a tank has a bullet count. The field and the "getter" method should both be in the Tank class. You may only create one Tank object now; but if you decide to add more later, it would be best to have things where they really belong. Each time a Tank object fires a bullet (creates a new Bullet object and adds it into the world), it should decrease the value of the field. The field can also be used to regulate the firing of the shots (only shoot while bullets are available (the value of the field is greater than zero).
MrSandwich MrSandwich

2016/4/5

#
I'm still not making it work. Here's what I have following your instructions (i probably followed them wrong though). In the tank class I have:
1
2
3
4
5
6
7
8
private static int bullets = 40;
 
//then I have the method getBulletCount
 
public void decreaseBullets()
{
    bullets--;
}
then in my world i call it:
1
2
3
4
public Tank getBulletCount()
{
    return bullets;
  }
so when I want to call it in another class I do the following:
1
2
MyWorld world = (MyWorld) getWorld();
Tank bullets = world.getBulletCount();
Is something missing? I know if I want to decrease the bullet number ( when the tank fires for expample) I just need to call the decreaseBullets method like so ->> tank.decreaseBullets(); What about if I want to make the bullets go back to it's initial value, would I need to create a new method that does that?
Super_Hippo Super_Hippo

2016/4/5

#
Why did you adjust the code danpost gave you? 'bullets' should not be static and the return type of 'getBulletCount' has to be same as the variable 'bullets' which is an 'int' and no 'Tank'. Last but not least, the 'getBulletCount' should be in the Tank class and not in the world class. I guess you should re-read what danpost wrote and try again.
MrSandwich MrSandwich

2016/4/5

#
Super_Hippo wrote...
Why did you adjust the code danpost gave you? 'bullets' should not be static and the return type of 'getBulletCount' has to be same as the variable 'bullets' which is an 'int' and no 'Tank'. Last but not least, the 'getBulletCount' should be in the Tank class and not in the world class. I guess you should re-read what danpost wrote and try again.
I totally misread, I thought i needed to add the int to the static, sorry. I got it to have no syntax errors when I compile it, but now if I pretended to change the number of bullets by for example grabbing munition, should i proceed as the following:
1
2
3
4
5
6
Tank tank= new Tank();
int bullets = tank.getBulletCount();
 
//in the method  pretend to use this
 
bullets= 40; // I intend to bring the number of bullets back to 40
Sorry again for all the questions, and for bothering you.
Super_Hippo Super_Hippo

2016/4/5

#
You create a new Tank (line 1) which is not tank already in the world. You create a new variable bullet (line 2) which is set to the value of the new tank (so bullets will be 40 if you removed the 'static'). If you change bullets now (line 6), you change the new variable but not the variable in the Tank class. Just as the getBulletCount-method, you can add another method:
1
2
3
4
public void setBulletCount(int num)
{
    bullets = num;
}
However, the code for grabbing up munition will be in the Tank's act-method (or called by that method), so you don't need that. It will just look like that:
1
2
3
4
5
6
7
if (isTouching(Munition.class))
{
    removeTouching(Munition.class);
    bullets = 40;
    //or if you want to increase the variable instead of resetting it to 40
    bullets += 40;
}
One question to the getBulletCount-method again: Which class needs to know how many shots the tank has left? Won't it just be something like the following?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private int delay = 0;
private int bullets = 40;
 
public void act()
{
    //move around, pick up munition etc.
     
    if (delay > 0) delay--;
    if (delay == 0 && bullets > 0 && if (Greenfoot.isKeyDown("space"))
    {
        delay = 55; //about one shot per second possible. Smaller number = faster shots
        bullets--;
        Bullet b = new Bullet();
        getWorld().addObject(b, getX(), getY());
        b.setRotation(getRotation());
        b.move(5); //moves the bullet before it appears so it doesn't starts in the middle of the tank, adjust this value for your needs
    }
}
MrSandwich MrSandwich

2016/4/5

#
Super_Hippo wrote...
You create a new Tank (line 1) which is not tank already in the world. You create a new variable bullet (line 2) which is set to the value of the new tank (so bullets will be 40 if you removed the 'static'). If you change bullets now (line 6), you change the new variable but not the variable in the Tank class. Just as the getBulletCount-method, you can add another method:
1
2
3
4
public void setBulletCount(int num)
{
    bullets = num;
}
However, the code for grabbing up munition will be in the Tank's act-method (or called by that method), so you don't need that. It will just look like that:
1
2
3
4
5
6
7
if (isTouching(Munition.class))
{
    removeTouching(Munition.class);
    bullets = 40;
    //or if you want to increase the variable instead of resetting it to 40
    bullets += 40;
}
One question to the getBulletCount-method again: Which class needs to know how many shots the tank has left? Won't it just be something like the following?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private int delay = 0;
private int bullets = 40;
 
public void act()
{
    //move around, pick up munition etc.
     
    if (delay > 0) delay--;
    if (delay == 0 && bullets > 0 && if (Greenfoot.isKeyDown("space"))
    {
        delay = 55; //about one shot per second possible. Smaller number = faster shots
        bullets--;
        Bullet b = new Bullet();
        getWorld().addObject(b, getX(), getY());
        b.setRotation(getRotation());
        b.move(5); //moves the bullet before it appears so it doesn't starts in the middle of the tank, adjust this value for your needs
    }
}
Thank you very much it's working as indeed now! I was adding the methods in the wrong places, and thinking about it the wrong way on how it should work.
Super_Hippo Super_Hippo

2016/4/5

#
Well, I hope you saw that you had to remove the second "if (" in line 9. ;)
MrSandwich MrSandwich

2016/4/5

#
Super_Hippo wrote...
Well, I hope you saw that you had to remove the second "if (" in line 9. ;)
Yeah, I already had that part sorted out ( different code from the one you providded though) the thing is I though that I needed to declare the bullets in the bullet class itself and tha'ts where the error was coming from so thank you again.
MrSandwich MrSandwich

2016/4/5

#
Double post, ignore
You need to login to post a reply.