Greenfoot: How do I make it so I press a button once and it keeps acting?

1.3k Views Asked by At

Title, I want to make my program shoot a ball when you press the button once, and then it keeps going and you can't do anything until it finishes. Current code for firing below.

public void act() 
{
        // Steps for calculating the launch speed and angle
        ProjectileWorld myWorld = (ProjectileWorld) getWorld();
        double shotStrength = myWorld.getSpeedValue();
        double shotAngle = myWorld.getAngleValue();
        // Checks to see if the space key is pressed, if it is, the projectile is fired
        String key = Greenfoot.getKey();  
        if ("space".equals(key))
        { 
            //xSpeed and ySpeed changed as requirements say
            xSpeed = (int)(shotStrength*Math.cos(shotAngle));
            ySpeed = -(int)(shotStrength*Math.sin(shotAngle));
            actualX += xSpeed;
            actualY += ySpeed;
            setLocation ((int) actualX, (int) actualY);
        }

right now this makes it so the ball only moves when I hold spacebar, and since that's the case, I can let go of the space bar and change the shotStrength and shotAngle while the ball is still in the air

1

There are 1 best solutions below

2
On BEST ANSWER

The key here is to change the state of your 'act' method's context to 'moving ball'.

There are a number of ways to accomplish this, but basically it depends on how act() is called.

my first thought is to do something like this:

public enum ActionMode{  MovingBall, Shooting, Waiting, Etc }

public void act() 
{
        // Steps for calculating the launch speed and angle
        ProjectileWorld myWorld = (ProjectileWorld) getWorld();
        double shotStrength = myWorld.getSpeedValue();
        double shotAngle = myWorld.getAngleValue();
        // Checks to see if the space key is pressed, if it is, the projectile is fired
        String key = Greenfoot.getKey();  
        if ("space".equals(key)){
            mode = ActionMode.MovingBall;
        }
        while(mode==ActionMode.MovingBall){

            //xSpeed and ySpeed changed as requirements say
            xSpeed = (int)(shotStrength*Math.cos(shotAngle));
            ySpeed = -(int)(shotStrength*Math.sin(shotAngle));
            actualX += xSpeed;
            actualY += ySpeed;
            setLocation ((int) actualX, (int) actualY);
            if( ballHasFinishedMoving(actualX, actualY) ){
                 mode==ActionMode.Waiting;
            }
        }
        ...
}
private boolean ballHasFinishedMoving( int actualX, int actualY ){
       logic to determine if ball has finished.
}