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

2017/11/19

variable won`t get transfered to other class

1
2
BananaJoe BananaJoe

2017/11/19

#
The variable "placed" in class "Bin" doesn`t get changed even tho "placedyet" in class "Cannon" is changed. I`ve tried to find the problem with the inspect tool and before that I changed the code and added an extra variable to exclude the problem in the "Cannon-"class, but everything works except that "placed" gets changed. Can you guys take a look. I think i`m just overseeing something. Here`s the code from "Bin-"class:
import greenfoot.*;
public class Bin extends FixedPoints
{
    private GreenfootImage baseImg = new GreenfootImage("Bin.png");
    GreenfootImage image = new GreenfootImage(baseImg);
    int x = 50;
    int y = 50;
    boolean placed = true;
    Cannon placedyet;
    public void act() 
    {
        placedyet = getWorld().getObjects(Cannon.class).get(0);
        placed = placedyet.placedyet();
        if(placed)
        {
            setImage("Bin.png");
            if(isTouching(Cannon.class)) //wird größer
            {
                x = 60;
                y = 60;
                image.scale(x, y);
                setImage(image);
            }
            else //wird kleiner
            {
                x = 50;
                y = 50;
                image.scale(x, y);
                setImage(image);
            }
        }
        else
        {
            setImage("Invisible.png");
        }
    }    
}
and here`s the code from "Cannon-"class:
import greenfoot.*; 
public class Cannon extends Actor
{
    int mx;
    int my;
    boolean a = false;
    boolean placed = false;
    public boolean placedyet;
    private GreenfootImage cannondrag = new GreenfootImage("Cannondrag.png");
    public boolean placedyet()
    {
        return placedyet;
    }
    
    public void act() 
    {
        if(a)
        {
            placedyet = true;
        }
        else
        {
            placedyet = false;
        }
        if(!placed)
        {
            notplaced();
        }
        if(placed)
        {
            placed();
        }
    }
    
    public void notplaced() // Man kann die Kanone setzen
    {
        setImage("Cannondrag.png");
        a = true;
        MouseInfo mouse = Greenfoot.getMouseInfo();
        if(mouse != null)
        {
            mx = mouse.getX();
            my = mouse.getY();
        }
        setLocation(mx, my);
        if(Greenfoot.mouseClicked(this) && getY() < 550 && !isTouching(Trennwand.class) && !isTouching(Cannon.class) && !isTouching(Weg.class) && !isTouching(Spawn.class) && !isTouching(Finish.class))
        {
            placed = true;
        }
    }
    
    public void placed() //Die Kanone steht
    {
        setImage("Cannon.png");
        a = true;
        if(Greenfoot.mouseClicked(this))
            {
                
            }
    }
}
danpost danpost

2017/11/19

#
Its looks like it should work, provided you only have exactly one Cannon object in the world. Adding extra fields can have there use, but not in your case for what you are using it for (referring to the pair 'a' and 'placedyet'). Other obvious (to me) pitfalls are lack of making use of constructors; creating object references without using them; multiple scaling of images; and use of fields where variables are sufficient. You can ask what I mean about each of these, one at a time, for clarification.
BananaJoe BananaJoe

2017/11/19

#
Ok, thank you for responding in the first place! I think the problem is, that I can and have more than one cannon after some time. But it doesnt work for the first cannon aswell. Is there a way I can make that work with multiple cannons or do I have to create a new class for that? (I had 2 classes, one for the "notplaced" and one for the "placed" part, but I wanted to use as less actors as possible to reduce the amount of actors I have to add/remove again and again.) Ok, and what do you mean with "lack of making use of constructors"?
danpost danpost

2017/11/19

#
BananaJoe wrote...
Is there a way I can make that work with multiple cannons or do I have to create a new class for that?
A new class would probably make things more complicated and probably not what you want to do anyway. Maybe I should ask what exactly a Bin object is and for what is it used.
what do you mean with "lack of making use of constructors"?
Well, a constructor should contain initialization codes for your object. Every act step, you are calling either 'placed' or 'notplaced', both of which starts with setting an image to the actor. However, the image only changes once or twice. The initial image can be set in the constructor and the final image given once, when the actor is placed.
BananaJoe BananaJoe

2017/11/19

#
danpost wrote...
Maybe I should ask what exactly a Bin object is and for what is it used.
I make a tower-defense game. And when you select a tower you either place it or delete it by pressing "s" (not programmed yet) or by clicking on the "Bin-"class. To indicate that you are on the "Bin-"class it gets bigger when touching it. But I dont want it to be shown all the time, only when I select a cannon. I think I fixed the problem with the constructors.. a beginner mistake.
BananaJoe BananaJoe

2017/11/19

#
To terminate missunderstandin, I fixed the:
danpost wrote...
Well, a constructor should contain initialization codes for your object. Every act step, you are calling either 'placed' or 'notplaced', both of which starts with setting an image to the actor. However, the image only changes once or twice. The initial image can be set in the constructor and the final image given once, when the actor is placed.
I didn`t fix my main problem. I expressed that bad, sorry. And with "beginner mistake" I mean that I don`t know thoose details yet.
danpost danpost

2017/11/19

#
Maybe it would be best to have the world (which is what should control your game, in general) control the cannon selection process. It can then keep a reference to a selected cannon which the Bin class can then have access to.
BananaJoe BananaJoe

2017/11/19

#
Oh, I just add actors in the world class. I didnt know you could and should control things from the world. I`m a bit confused now, what excatly should I do in the world and what not? *edited. I think its to late for that anyway, this may help in my next project. So how can I make that with the bin happen? I realy appreciate your effort!
danpost danpost

2017/11/19

#
It looks like your cannons are added into the world in the state that they are being placed. A more simplified class might be this:
import greenfoot.*;

public class Cannon extends Actor
{
    public boolean placed;
    
    public Cannon()
    {
        setImage(new GreenfootImage("Cannondrag.png"));
    }
    
    public boolean isPlaced()
    {
        return placed;
    }
    
    public void act()
    {
        if (placed)
        {
            placed();
        }
        else
        {
            notplaced();
        }
    }
    
    public void notplaced() // Man kann die Kanone setzen
    {
        if (Greenfoot.mouseMoved(null))
        {
            MouseInfo mouse = Greenfoot.getMouseInfo();
            int mx = mouse.getX();
            int my = mouse.getY();
            setLocation(mx, my);
        }
        if(Greenfoot.mouseClicked(this) && getY() < 550 && !isTouching(Trennwand.class) && !isTouching(Cannon.class) && !isTouching(Weg.class) && !isTouching(Spawn.class) && !isTouching(Finish.class))
        {
            placed = true;
            setImage("Cannon.png");
        }
    }
     
    public void placed() //Die Kanone steht
    {
        // action when placed
    }
}
I changed the name of the 'placed(yet)' getter method from 'placedyet' to 'isPlaced' to have it describe what the method is for more clearly. Notice that there is only one ffield in the entire class (much easier to work with). It the only information that needs to be retained from one act step to the next (so far, in this class). The constructor sets the initial image and the image is change once at the time the cannon is 'placed'. I also move the MouseInfo reference and the 'setLocation' for dragging inside the (now) 'mouseMoved' 'if' block. The setting of its location only needs to be done if the mouse was moved (and not 'placed') and there is no need to get a reference to the MouseInfo object unless the mouse was moved.
danpost danpost

2017/11/19

#
BananaJoe wrote...
how can I make that with the bin happen? I realy appreciate your effort!
With the Bin -- maybe a Cannon class field will solve the problem. This will allow a change throughout the class to this:
import greenfoot.*;
 
public class Cannon extends Actor
{
    public static Cannon dragged;
     
    public Cannon()
    {
        setImage("Cannondrag.png");
    }

    protected void addedToWorld(World world)
    {
        dragged = this;
    }
    
    public void act()
    {
        if (dragged == this)
        {
            notplaced();
        }
        else
        {
            placed();
        }
    }
     
    public void notplaced() // Man kann die Kanone setzen
    {
        if (Greenfoot.mouseMoved(null))
        {
            MouseInfo mouse = Greenfoot.getMouseInfo();
            int mx = mouse.getX();
            int my = mouse.getY();
            setLocation(mx, my);
        }
        if(Greenfoot.mouseClicked(this) && getY() < 550 && !isTouching(Trennwand.class) && !isTouching(Cannon.class) && !isTouching(Weg.class) && !isTouching(Spawn.class) && !isTouching(Finish.class))
        {
            dragged = null;;
            setImage("Cannon.png");
        }
    }
      
    public void placed() //Die Kanone steht
    {
        // action when placed
    }
}
Since no more than one of all your cannons can ever be dragged at a single time, a class field is used to track which cannon is being dragged. All classes have immediate access to this because it is a public class field. For example, in your Bin class, you can do this:
if (Cannon.dragged != null)
to see if a cannon is being dragged and 'Cannon.dragged' actually refers to what cannon is being dragged. Because class fields are only reset during re-compiling of the project, you should add the following line in your World subclass constructor:
Cannon.dragged = null;
I would advise caution when using class fields. You should understand how they behave and how they are best used before making use of them. This, however, is a perfectly good use of one.
BananaJoe BananaJoe

2017/11/19

#
Ok, that looks way better and easier to handle. But the Bin won`t show at any point. And when I inspect the 'Bin-'class in line 16 it doesnt interrupt the programm. So the 'placed' variable in 'Bin-'class never becomes true.
danpost danpost

2017/11/19

#
BananaJoe wrote...
Ok, that looks way better and easier to handle. But the Bin won`t show at any point. And when I inspect the 'Bin-'class in line 16 it doesnt interrupt the programm. So the 'placed' variable in 'Bin-'class never becomes true.
I think I am still a bit confused about the Bin class. As FixedPoint objects, are they set at locations throughout the world where a cannon can be placed? Maybe you can explain when and how many Bin objects are placed in the world and describe each part of its act method (giving when each part is relevant). This would give a better idea of what you might need to do.
BananaJoe BananaJoe

2017/11/19

#
A cannon can be placed in a certain area of the game (world(825, 800) and the cannon can get set under y = 500). The bin is around (700/700). There is exactly one Bin created by the start of the game, but it is "invisible" duo a blank image. It kinda worked when I had one extra actor for the cannonplacement but that were to complicated so I deleted that class to bring it together into one class. Here`s the script with my commentaries:
import greenfoot.*;
public class Bin extends FixedPoints
{
    private GreenfootImage baseImg = new GreenfootImage("Bin.png");
    GreenfootImage image = new GreenfootImage(baseImg);
    int x = 50;
    int y = 50;
    boolean placed;
    Cannon isPlaced;
    public void act() 
    {
        isPlaced = getWorld().getObjects(Cannon.class).get(0);
        placed = isPlaced.isPlaced();
        if(placed)
        {
            setImage("Bin.png");
            if(isTouching(Cannon.class)) // when you hover over the Bin it gets bigger to indicate you are able/going to delete the cannon.
            {
                x = 60;
                y = 60;
                image.scale(x, y);
                setImage(image);
            }
            else // here it gets smaller again, when you move the mouse with the cannon away.
            {
                x = 50;
                y = 50;
                image.scale(x, y);
                setImage(image);
            }
        }
        else
        {
            setImage("Invisible.png"); //the bin should get "deleted" so that you can only see it, when you have a cannon you want to place.
        }
    }    
}
The thing is I can`t realy work/test with this code, because the variable 'placed' from 'isPlaced' doesnt change(That is my main-problem and I think it is because I had multiple cannons(not sure tho), like you said. But in that case i dont realy know how I could fix that problem..). Therefor the Code is not finished yet. I can`t realy test it the way I want..
Super_Hippo Super_Hippo

2017/11/19

#
I think you can use
Cannon c = Cannon.dragged;
if (c != null && c.isPlaced())
{
    //...
at the start of the act method (lines 12-15). And with a change of the images:
private GreenfootImage[] image = {new GreenfootImage("Bin.png"), new GreenfootImage("Bin.png"), new GreenfootImage(1, 1)};

public Bin()
{
    image[0].scale(50, 50);
    image[1].scale(60, 60);
}

public void act()
{
    Cannon c = Cannon.dragged;
    if (c != null && c.isPlaced())
    {
        if (isTouching(Cannon.class)) setImage(image[1]);
        else setImage(image[0]);
    }
    else setImage(image[2]);
}
Super_Hippo Super_Hippo

2017/11/19

#
On the other hand, you could also make the Bin bigger when the Cannon is touching the Bin (in the 'notplaced' method, Cannon class)... so you don't repeatedly set an image there for no reason.
There are more replies on the next page.
1
2