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

2022/8/28

Why are my if statements not working?

classictommy classictommy

2022/8/28

#
Hi all! Fairly new to greenfoot / programming, and I have hit a bit of a wall. I need my object to change direction after it has moved +10 on the y axis, but the if statement is completely ignored by the program
    public void act()
    {
    
     move(1);
    setRotation(45);
       if(getY() == getY() + 10){
           move(1);
           setRotation(110);
       
     
      
    
      
       
    }
}
Any assistance would be greatly appreciated. Cheers!
danpost danpost

2022/8/29

#
classictommy wrote...
if(getY() == getY() + 10){
Here, you are asking if some value is equal to 10 more than that value. That will never be true. Rethink your logic. Or, explain what you are attempting to check or compare for more assistance.
classictommy classictommy

2022/8/29

#
danpost wrote...
classictommy wrote...
if(getY() == getY() + 10){
Here, you are asking if some value is equal to 10 more than that value. That will never be true. Rethink your logic. Or, explain what you are attempting to check or compare for more assistance.
Hi. Thank you for your response. I am just trying to get a ball to move in the shape of a pyramid. I want it to, once it reaches a certain point, to change direction of movement. That in essence is my main issue
Super_Hippo Super_Hippo

2022/8/29

#
First, you need to understand what the act method does. Everything in the act method happens, then the actor’s position is visible updated for you to see and then this process is repeated. If you put the entire “move in a pyramid shape” as move/turn commands one after the other, then the actor might move an the pyramid shape, but you can’t see it because it happens in a single frame. How you could start is to only call the move method once. And then have conditions when you need to turn. A condition can for example be the current location or a number of act cycles (something like turn 120 degrees every five seconds). Side note: Especially if you move 1 step at a time, you will see that the rotation isn’t gonna be very accurate and the speed depends on the rotation too. This effect can be reduced with higher movement speed or by using the smooth mover class.
Spock47 Spock47

2022/8/30

#
There are several ways to realize a given predefined movement like you described. The maybe simplest approach would be step-counter-based: You do 10 steps in that direction, then you make 5 steps in that direction and so on. However, you already started with a waypoint-based approach: Moving until a position is reached, then changing direction. So, let's stick with that for now and repair it:
if(getY() == getY() + 10)
danpost already mentioned why this condition is always false. What you actually want from what you said is:
if (getY() == originalY + 10)
So, how do we tell the program what original-y is? We store it in a variable. You have to initialize that variable before the first movement. That means the program will always know what the y-value at the start was and therefore, you can then check anytime whether the value has increased by 10. Also, it makes sense to be a bit more lenient with the condition and use ">=" instead of "==". That way, it will still work in case we overstep a bit:
if (getY() >= originalY + 10)
Now, since we have to initialize the original-y value, the question is: When do you want to start the shaped-movement? If it shall start in the moment, the actor is added to the world, it could be done in the addedToWorld method, leading to this source code that will make the ShapeMover move down for 10 cycles and then changing direction to top-right.
public class ShapeMover extends Actor {
    private int originalY;
    
    @Override public void addedToWorld(final World world) {
        originalY = getY();
        setRotation(90);
    }
    
    @Override public void act() {
        move(1);
        if (getY() >= originalY + 10) {
            setRotation(315);
        }
    }
}
However, you already mentioned that you want a more complex shape in the future, e.g. more than one movement change. Therefore, keeping track about the current state is crucial as Super-Hippo mentioned, For now, we can just "deactivate" the if-check after the change of rotation. That way it won't interfere if you add the checks for later movement changes:
public class ShapeMover extends Actor {
    
    private Integer originalY = null;
    
    @Override public void addedToWorld(final World world) {
        originalY = getY();
        setRotation(90);
    }
    
    @Override public void act() {
        move(1);
        if (originalY != null && getY() >= originalY + 10) {
            setRotation(315);
            originalY = null;
        }
    }
}
Now, try to add the rest of the movements for your shape in a similar way. Remark: Normally, a pyramid is a 3-dimensional object, but Greenfoot is 2-dimensional. So what do you mean by "shape of a pyramid"? A triangle? Live long and prosper, Spock47
danpost danpost

2022/8/30

#
Something simple to have the ball go up and down while moving right, then reverse, repeating, might be this:
import greenfoot.*;

public class Ball extends Actor
{
    private static final int MAX_DIST = 10; // adjust as needed
    
    private int dist;
    
    public Ball()
    {
        setRotation(-45);
    }
    
    public void act()
    {
        move(1);
        dist = (dist+1)%MAX_DIST;
        if (dist == 0)
        {
            if (getRotation() < 180) turn(180);
            else turn(2*(getRotation()-270));
        }
    }
}
Not tested, but should work.
Spock47 Spock47

2022/8/30

#
danpost wrote...
            else turn(2*(getRotation()-270));
That else-statement looks very suspicious to me, e.g. if rotation is 270 before, it stays at 270.
danpost danpost

2022/8/30

#
Spock47 wrote...
That else-statement looks very suspicious to me, e.g. if rotation is 270 before, it stays at 270.
A 270 rotation is straight up. That is not part of a "pyramid" shape. With the rotation set to any odd multiple of 45, the code should work and all movement will remain at odd multiples of 45.
You need to login to post a reply.