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

2014/11/3

Accessing a Value from an actor to be used in another method

1
2
danpost danpost

2014/11/4

#
Alright. Well I accidentally wrote the code as if it was in your world class anyway. So use it in your 'getSpeedValue' method. Then to access it from your BallProjectile class, use similar type coding with 'getWorld' to execute the method in the ProjectileWorld class.
KG.1987 KG.1987

2014/11/4

#
Here is the code correctly tagged.
public class ProjectileWorld extends World
{
    
    /**
     * Constructor for objects of class ProjectileWorld.
     * 
     */
   private AngleArc AA;
    private PowerBar PB;
   
    public ProjectileWorld()
    {    
        // Create a new world with 600x400 cells with a cell size of 1x1 pixels.
        super(800, 600, 1); 
        
         
         //Add new powerbar
        PowerBar PB=new PowerBar(200);
         
        addObject(PB, 162, 592);
         
         //Add new Anglearc
        AngleArc AA= new AngleArc(50);
         addObject(AA, 27, 572);
        
        //Add Static Circles
        addObject(new Obstacle((Greenfoot.getRandomNumber(76)+25)),(Greenfoot.getRandomNumber(800)+100),Greenfoot.getRandomNumber(500));
        addObject(new Obstacle((Greenfoot.getRandomNumber(76)+25)),(Greenfoot.getRandomNumber(800)+100),Greenfoot.getRandomNumber(500));
        addObject(new Obstacle((Greenfoot.getRandomNumber(76)+25)),(Greenfoot.getRandomNumber(800)+100),Greenfoot.getRandomNumber(500));
        addObject(new Obstacle((Greenfoot.getRandomNumber(76)+25)),(Greenfoot.getRandomNumber(800)+100),Greenfoot.getRandomNumber(500));
        addObject(new Obstacle((Greenfoot.getRandomNumber(76)+25)),(Greenfoot.getRandomNumber(800)+100),Greenfoot.getRandomNumber(500));
        //Add Projectile
        addObject(new BallProjectile(),50,559); 
        
    }
    
    public double getSpeedValue()
    {
       double power=PB.getFullPercentage();
        power=power*15.0;
        return power;

    }   
    
    public double getAngleValue()
    {

         double angle=AA.getAngleRadians();
        
        return angle;

    }
    

}
Here is the code from the PowerBar (note: this is only part of it)
/**
     * getFullPercentage - calculate how full the PowerBar is
     * 
     * @return the ratio (percentage) of fullness
     */
    public double getFullPercentage()
    {
        
        return power/(double)maxPower;
    }
Here is the code from the AngleArc (Note: this is only part of it)
/**
     * getAngleRadians - returns how full the anglearc is
     * 
     * @return the current fill amount in RADIANS
     */
    public double getAngleRadians()
    {
        return Math.toRadians(power);
    }
Here is the code for BallProjectile
public class BallProjectile extends Actor
{    
    
    private int xSpeed;
    private int ySpeed;
    
    public BallProjectile()
    {
       xSpeed=0;
       ySpeed=0;
       
       setImage(new GreenfootImage(25, 25));  
       
        getImage().setColor(Color.blue);  
  
        getImage().drawOval(0,0,25,25);   
  
        getImage().fillOval(0,0,25,25); 
    }
    
    
    /**
     * Act - do whatever the BallProjectile wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
         ProjectileWorld w= (ProjectileWorld)getWorld();
         double power=w.getSpeedValue(); 
         double angle=w.getAngleValue();
        if(Greenfoot.isKeyDown("space")){
        //ySpeed=4;
        //ySpeed=-1;
      
       xSpeed =(int)(power*Math.cos(angle)); 
       ySpeed = -(int)(power*Math.sin(angle));
       
       setLocation (getX() + xSpeed, getY() - ySpeed);}
       
       if(getY()<=0){
           setImage(new GreenfootImage(25,25));
           getImage().setColor(Color.white);
           getImage().drawOval(0,0,25,25);   
           getImage().fillOval(0,0,25,25);}
       if (getX()>w.getWidth()-2){
           setImage(new GreenfootImage(25,25));
           getImage().setColor(Color.white);
           getImage().drawOval(0,0,25,25);   
           getImage().fillOval(0,0,25,25);
        }           
       
       if (getY() >= w.getHeight()-1) {
          setImage(new GreenfootImage(40, 20));  
  
        getImage().setColor(Color.magenta);  
  
        getImage().drawOval(0,0,40,20);   
  
        getImage().fillOval(0,0,40,20);
     }
        
    }   } 
danpost danpost

2014/11/4

#
Lines 8 and 9 of the ProjectileWorld class declare two fields that are not assigned any objects -- anywhere. Lines 18 and 23 declare local variables (that are NOT the same as your instance fields; even if they have the same name) which are assigned objects. So, the objects in your world are not held in the fields you intended them to be in. Just use the name of the fields in lines 18 and 23 and remove the variable type declarations.
KG.1987 KG.1987

2014/11/4

#
Oh, yeah good catch. I got the projectile to fire now without error but it only goes a very short distance. Is that an error in my xSpeed and ySpeed formulas? (line 35 & 36 of the act() method in the BallProjectile() class)
danpost danpost

2014/11/4

#
It appears it will only move as long as the 'space' key is being pressed. Also, 'power' seems to hold a fractional value (between 0 and 1). That, multiplied by a 'cos' or 'sin' value (again between -1 and 1), will produce a double between -1 and 1. All values except for the value 1 and the value -1 will be reduced to 0 when set as an int value (lines 35 and 36 of your BallProjectile class).
Alwin_Gerrits Alwin_Gerrits

2014/11/4

#
If you want to prevent the problem danpost gave in his last post you can simply multiply the value of 'power' by 100. That should do miracles for the problem, but you have to remember to either devide by 100 later or change your code so it works with the new number. Anyway, that's often a good workaround for numbers that would otherwise get rounded off.
danpost danpost

2014/11/4

#
I just noticed (I do not know how I missed it before) that you are multiplying 'power' by 15.0 in the 'getSpeedValue' method. That should suffice for getting it to move. However, slower movement (when power is low) will cause the actor to move along lesser and lesser possible angles. I would like to see the PowerBar class code, if possible.
KG.1987 KG.1987

2014/11/4

#
Heres the PowerBar() code
public class PowerBar extends Actor
{
    private int power;    // how full now?
    private int maxPower; // max full value?
    
    /**
     * PowerBar - build a PowerBar of specified size
     * 
     * @param width the maximum power allowable.
     */
    public PowerBar(int width)
    {
        // grow an appropriate image
        GreenfootImage img = new GreenfootImage(2+width, 2+10);
        
        // set image
        setImage(img);
        
        power=0;        // user filled power amount is empty to start
        maxPower=width; // maxOiwer is specified by input parameter
        
        redraw(); // initially draw into image
    }
    
    /**
     * redraw - draw the powerbar
     */
    private void redraw()
    {
        // find the image we are drawing into
        GreenfootImage img = getImage();
        
        // draw the border
        img.setColor(Color.black);
        img.drawRect(0,0,1+maxPower, 11);
        
        // draw the background
        img.setColor(Color.gray);
        img.fillRect(1,1,maxPower,10); 
            
        // draw the filled part
        img.setColor(Color.blue);
        img.fillRect(1,1,power,10); 
    }
    
    /**
     * getPower - returns how full the powerBar is
     * 
     * @return the current fill amount
     */
    public int getPower()
    {
        return power;
    }
    
    /**
     * incrememt - grows the filled part of the PowerBar
     */
    public void increment()
    {
        // add 1 to power amount, making sure such does not overfill 
        power++;
        if (power>maxPower) power--;
        
        // redraw, as we should change image to reflect increase.
        redraw();
    }
    
    /**
     * decrement - shrinks the filled part of the PowerBar
     */
    public void decrement()
    {
        // shrink powerbar's usage, making sure not to shrink into negative.
        power--;
        if (power<0) power++;
            
        // redraw - this probably changed the image we should present
        redraw();
    }
    
    /**
     * getFullPercentage - calculate how full the PowerBar is
     * 
     * @return the ratio (percentage) of fullness
     */
    public double getFullPercentage()
    {
        
        return power/(double)maxPower;
    }
    
    /**
     * Act - do whatever the PowerBar wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        // do appropriate change based on user keyboard input
        if (Greenfoot.isKeyDown("left") || 
            Greenfoot.isKeyDown("<") || 
            Greenfoot.isKeyDown(",") )
            decrement();
        else if (Greenfoot.isKeyDown("right") || 
                 Greenfoot.isKeyDown(">") || 
                 Greenfoot.isKeyDown(".") )
            increment();
        
    }    
}
Here the AngleArc() code
public class AngleArc extends Actor
{
    private int power;  // how full now?
    private int radius; // radius of semicircle
    
    /**
     * PowerBar - build a PowerBar of specified size
     * 
     * @param radius the msize of the radius of teh semicircle
     */
    public AngleArc(int radius)
    {    
        // build image to hold semicicle
        GreenfootImage img = new GreenfootImage(1+radius, 1+radius);
        setImage(img);
        
        power=0; // inital abgle is empty
        
        this.radius = radius; // remember radius
        
        redraw(); // generate image
    }
    
    /**
     * redraw - draw the anglearc
     */
    private void redraw()
    {
        GreenfootImage img = getImage(); // iamge to draw in 
        
        
        // draw semicircle background
        img.setColor(Color.gray);
        Shape fillingArc=new Arc2D.Double(-radius,0,2*radius,2*radius,0,90,Arc2D.PIE);
        img.fillShape(fillingArc);

        // draw filled portion
        img.setColor(Color.blue);
        fillingArc=new Arc2D.Double(-radius,0,2*radius,2*radius,0,power,Arc2D.PIE);
        img.fillShape(fillingArc);
        
        // draw the border
        img.setColor(Color.black);       
        Shape emptyArc=new Arc2D.Double(-radius,0,2*radius,2*radius,0,90,Arc2D.PIE);
        img.drawShape(emptyArc);
        img.drawLine(0,0,0,1+radius);
        img.drawLine(0,radius,radius,radius);
    }
    
        
    /**
     * getAngleDegrees - returns how full the anglearc is
     * 
     * @return the current fill amount in DEGREEES
     */
    public int getAngleDegrees()
    {
        return power;
    }
    
    
    /**
     * getAngleRadians - returns how full the anglearc is
     * 
     * @return the current fill amount in RADIANS
     */
    public double getAngleRadians()
    {
        return Math.toRadians(power);
    }
    
    
    /**
     * incrememt - grows the filled part of the AngleArc
     */
    public void increment()
    {
        // incrememt, making sure not to go over max
        power++;
        if (power>90)
            power--;
        else    
            redraw();
    }
    
    /**
     * decrememt - grows the filled part of the AngleArc
     */
    public void decrement()
    {
        // decrememt, making sure not to go under min
        power--;
        if (power<0) 
            power++;
        else    
            redraw();
    }
    
    /**
     * Act - do whatever the AngleArc wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        // modify arc appropriately based on user inout (if any)
        if (Greenfoot.isKeyDown("up") || 
            Greenfoot.isKeyDown("+") || 
            Greenfoot.isKeyDown("=") )
            increment();
        else if (Greenfoot.isKeyDown("down") || 
                 Greenfoot.isKeyDown("-") || 
                 Greenfoot.isKeyDown("_") )
            decrement();
  
    }    
}
KG.1987 KG.1987

2014/11/4

#
Is there a way to press "space" once and have to actor fire without holding "space"?
danpost danpost

2014/11/4

#
Add an instance boolean field to the class code to keep track of the state of the spacebar. Anytime, the field and the current state do not match, adjust the field. Anytime you adjust the field and the new current state is down, fire.
Dr.Blythe Dr.Blythe

2014/11/6

#
***ahem***, reallly?
danpost danpost

2014/11/7

#
Dr.Blythe wrote...
***ahem***, reallly?
Yes -- really.
// with this field
private boolean spaceDown; // default initial value is 'false'
// in act method (or method called from it)
if (spaceDown != Greenfoot.isKeyDown("space") && (spaceDown = !spaceDown)) fire();
KG.1987 KG.1987

2014/11/7

#
Disregard danpost, Dr. Blythe is my professor and was talking to me.
You need to login to post a reply.
1
2