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

2021/12/31

Can't figure it out, healthbar Asteroids

SportingLife7 SportingLife7

2021/12/31

#
How can I reference my rocket class so that the explosion and the removal of my rocket instance will occur when the health bar is finished?
HealthBar
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
//import java.awt.Color;
/**
 * Write a description of class HealthBar here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class HealthBar extends Actor
{
    int health = 20;
    int healthBarWidth = 80;
    int healthBarHeight = 10;
    int pixelsPerHealthPoint = healthBarWidth/health;
    /**
     * Act - do whatever the HealthBar wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public HealthBar()
    {
        update();
        //death();
    }
    public void act() 
    {
        update();
        death();
    }    
    public void update()
    {
        setImage(new GreenfootImage(healthBarWidth + 2, healthBarHeight + 2));
        getImage().setColor(Color.WHITE);
        getImage().drawRect(0, 0,healthBarWidth + 1, healthBarHeight + 1);
        getImage().setColor(Color.RED);
        getImage().fillRect(1, 1, health * pixelsPerHealthPoint, healthBarHeight);
    }
    public void death()
    {
        if(health == 0)
        {
           Space space = (Space)getWorld(); //go to our world and run this method      
           space.addObject(new Explosion(),getX(),getY()); // rocket actor coordinates needed here!
           space.removeObject(this);// refers to the rocket (but how can I refer the rocket!) running the code  
           space.gameOver();//exam question!!
        }
    }
}
Space (my world)
import greenfoot.*;  // (World, Actor, GreenfootImage, and Greenfoot)


/**
 * Space. Something for rockets to fly in.
 * 
 * @author Michael Kolling
 * @version 1.0
 */
public class Space extends World
{
    private Counter scoreCounter;
    private int startAsteroids = 3;
    private int startStars = 2500;
    HealthBar healthbar = new HealthBar();
    public Space() 
    {
        super(600, 400, 1);
        GreenfootImage background = getBackground();
        background.setColor(Color.BLACK);
        background.fill();
        
        Rocket rocket = new Rocket();
        addObject(rocket, getWidth()/2 + 100, getHeight()/2);
        
        addAsteroids(startAsteroids);
        createStars(startStars);
        
        scoreCounter = new Counter("Score: ");
        addObject(scoreCounter, 60, 380);

        Explosion.initializeImages();
        ProtonWave.initializeImages();
        
        addObject(healthbar, 424, 34);
    }
    /**
     * Add a given number of stars to our world..
     */
    private void createStars(int number) 
    {
        GreenfootImage background = getBackground();
        for(int i = 0; i < number; i++) 
        {
            int x = Greenfoot.getRandomNumber(getWidth());
            int y = Greenfoot.getRandomNumber(getHeight());
            int r = Greenfoot.getRandomNumber(256);
            background.setColor(new Color(r,r,r));
            //int g = Greenfoot.getRandomNumber(256);
            //int b = Greenfoot.getRandomNumber(256);
            //background.setColor(new Color(r,g,b));
            background.fillOval(x, y, 4 , 4); //the two two controls the size of my stars!
            //we add the same r value to make it gray if we would have many then we would get rainbow!
        }
    }
    /**
     * Add a given number of asteroids to our world. Asteroids are only added into
     * the left half of the world.
     */
    private void addAsteroids(int count) 
    {
        for(int i = 0; i < count; i++) 
        {
            int x = Greenfoot.getRandomNumber(getWidth()/2);
            int y = Greenfoot.getRandomNumber(getHeight()/2);
            addObject(new Asteroid(), x, y);
        }
    }
    /**
     * 
     */
    public void countScore()
    {
        scoreCounter.add(100);
    }
    /**
     * 
     */
    public HealthBar getHealthBar()
    {
        return healthbar;
    }
    /**
     * This method is called when the game is over to display the final score.
     */
    public void gameOver() 
    {
        addObject(new ScoreBoard(scoreCounter.getValue()), getWidth()/2, getHeight()/2); // the coordinates div
        // TODO: show the score board here. Currently missing.
    }

}
Rocket
import greenfoot.*;  // (World, Actor, GreenfootImage, and Greenfoot)

/**
 * A rocket that can be c   ontrolled by the arrowkeys: up, left, right.
 * The gun is fired by hitting the 'space' key. 'z' releases a proton wave.
 * 
 * @author Poul Henriksen
 * @author Michael Kolling
 * 
 * @version 1.0
 */
public class Rocket extends SmoothMover
{
    private static final int gunReloadTime = 5;         // The minimum delay between firing the gun.
    private static final int protonWaveCalm = 250;      //minimum delay between activating prton wave
    private int reloadDelayCount;                       // How long ago we fired the gun the last time.
    private int reloadPowerCount;                       // How long ago we activated the prton wave
    private GreenfootImage rocket = new GreenfootImage("rocket.png");    
    private GreenfootImage rocketWithThrust = new GreenfootImage("rocketWithThrust.png");
    private boolean yes = false;
    /**
     * Initilise this rocket.
     */
    public Rocket()
    {
        reloadDelayCount = 5;
        reloadPowerCount = 50;
        addForce(new Vector(getRotation(), 0.3));
    }

    /**
     * Do what a rocket's gotta do. (Which is: mostly flying about, and turning,
     * accelerating and shooting when the right keys are pressed.)
     */
    public void act()
    {
        checkKeys();
        reloadDelayCount++; //increases our counter for bullets
        reloadPowerCount++; //increases our counter for proton waves
        ignite (Greenfoot.isKeyDown("up"));
        move();
        checkCollision();//leave last in our act mehthod (order matters (if rocket is gone, rocket can't check keys)
    }

    /**
     * Check whether there are any key pressed and react to them.
     */
    private void checkKeys() 
    {
        if (Greenfoot.isKeyDown("space")) 
        {
            fire();
        }
        if (Greenfoot.isKeyDown("left")) 
        {
            //get my rotatio, and then based off of that, set my rotation
            //to change by 5 degrees
            setRotation(getRotation()-5);
        }
        if (Greenfoot.isKeyDown("right")) 
        {
            //get my rotatio, and then based off of that, set my rotation
            //to change by 5 degrees
            setRotation(getRotation()+5);
        }
        ignite(Greenfoot.isKeyDown("up")); //isKeyDown provides the
        if (Greenfoot.isKeyDown("z"))
        {
            //to add a prton wave into our world when this key is pressed
            StartProton();

        }
    }

    /**
     * changes between two rocket images, depending on if the up key is pressed 
     * adds force in the direction we are facing if up is pressed
     */
    private void ignite (boolean boosterOn)
    {
        if (boosterOn)
        {
            setImage ("rocketWithThrust.png");
            addForce(new Vector(getRotation(), 0.3));//we are asking for direction get the rotation we are already pointing in
        }
        else
        {
            setImage ("rocket.png");
        }
    }

    /**
     * Fire a bullet if the gun is ready.
     */
    private void fire() 
    {
        if (reloadDelayCount >= gunReloadTime) 
        {
            Bullet bullet = new Bullet (getMovement().copy(), getRotation());
            getWorld().addObject (bullet, getX(), getY());
            bullet.move ();
            reloadDelayCount = 0;
        }
    }

    /**
     * method checks to see if we have collided with an asteroid, if we have remove rocket and add explosion BOOM!
     */
    private void checkCollision()
    {
        //Actor a = getOneIntersectingObject(Asteroid.class);
        //if (a != null)                       // a way to simplify (a is storing the intersecting object line)
        //{ World world = getWorld(); and then what follows which are the two line in my if statement below
        if (getOneIntersectingObject(Asteroid.class) != null && yes == false)// as long as it doesn't equal nothing
        //instead of going to world now it goes to space but space is a world so inherited methods still not affected for other objects
        { //this is casting , the use of this in the below using space instead of world
            Space space = (Space)getWorld(); //go to our world and run this method      
            HealthBar healthbar = space.getHealthBar();
            healthbar.health--;
            yes = true;
            //space.gameOver(); //exam question!!! Why do we get an error here? //another question! us doing casting
        }
        else if (getOneIntersectingObject(Asteroid.class) != null)
        {
            yes = false;
        }
        //check if colliding with asteroid
        //if we are
        //remove rocket
        //add explosion
        //game over
        //another place to see casting is in Newton's project in the smoothmover method With the double values into 
    }
    // public void done()
    // {
           // Space space = (Space)getWorld(); //go to our world and run this method      
           // space.addObject(new Explosion(),getX(),getY()); // short answer question of statements make difference remember why did it not work when this line of 
           // space.removeObject(this); // refers to the rocket running the code  
           // space.gameOver();//exam question!!
    // }
    /**
     * Fire up a proton if the count is ready and it has already calmed down.
     */
    private void StartProton() 
    {
        if (reloadPowerCount >= protonWaveCalm) 
        {
            ProtonWave protonWave = new ProtonWave ();
            getWorld().addObject (protonWave, getX(), getY());
            reloadPowerCount = 0;
        }
    }

}
Thanks for the help! :)
danpost danpost

2021/12/31

#
A health bar is like an instrument. It registers and visually displays some value which can be read. It is an inanimate object, meaning it does nothing on its own. It certainly should have no knowledge of any rocket; and, it certainly cannot explode. This means that there should not be any act method in the HealthBar class -- and it should not have a death method either. An image for the health bar only needs to be created during initialization and when its value is changed. Instead of changing its value from outside the class, call a method to adjust its value:
public void adjustValue(int changeAmount)
{
    health += changeAmount; // make change
    if (health > 20) health = 20; // maintain range
    if (health < 0) health = 0;
    update(); // update image
}
Not sure what is going on with the boolean yes. I do not see a colliding asteroid being removed. So, the code I see will diminish the value of health every other act step with the (toggling of the boolean field). If the only time an explosion occurs is when the rocket hits an asteroid and the health value bottoms out, then the world can just wait for an explosion to finish before showing game over. Yes, the world can have an act method, too. It will need a boolean field to indicate an explosion was found, so when the explosion ends, it can do the game over thing:
boolean explosionFound;

public void act()
{
    if (!explosionFound && !getObjects(Explosion.class).isEmpty()) explosionFound = true;
    if (explosionFound && getObjects(Explosion.class).isEmpty()) gameOver();
}
In Rocket class, immediately after decreasing health value, check the new value to see if it is zero. If so, add explosion and remove rocket:
healthbar.adjustValue(-1);
if (healthbar.value == 0)
{
    ...
SportingLife7 SportingLife7

2022/1/4

#
So this is my rocket class after I entered the code you wrote (thank you by the way), i'm getting an error where I commented "ERROR HERE!!!!!" it says "cannot find symbol - variable value". Do i have to create a variable called value in my healthbar class with a stated integer or....? Thanks again for your help :) This is the rocket class code (I apologize for the mess)
import greenfoot.*;  // (World, Actor, GreenfootImage, and Greenfoot)

/**
 * A rocket that can be c   ontrolled by the arrowkeys: up, left, right.
 * The gun is fired by hitting the 'space' key. 'z' releases a proton wave.
 * 
 * @author Poul Henriksen
 * @author Michael Kolling
 * 
 * @version 1.0
 */
public class Rocket extends SmoothMover
{
    private static final int gunReloadTime = 5;         // The minimum delay between firing the gun.
    private static final int protonWaveCalm = 250;      //minimum delay between activating prton wave
    private int reloadDelayCount;                       // How long ago we fired the gun the last time.
    private int reloadPowerCount;                       // How long ago we activated the prton wave
    private GreenfootImage rocket = new GreenfootImage("rocket.png");    
    private GreenfootImage rocketWithThrust = new GreenfootImage("rocketWithThrust.png");
    private boolean yes = false;
    /**
     * Initilise this rocket.
     */
    public Rocket()
    {
        reloadDelayCount = 5;
        reloadPowerCount = 50;
        addForce(new Vector(getRotation(), 0.3));
    }

    /**
     * Do what a rocket's gotta do. (Which is: mostly flying about, and turning,
     * accelerating and shooting when the right keys are pressed.)
     */
    public void act()
    {
        checkKeys();
        reloadDelayCount++; //increases our counter for bullets
        reloadPowerCount++; //increases our counter for proton waves
        ignite (Greenfoot.isKeyDown("up"));
        move();
        checkCollision();//leave last in our act mehthod (order matters (if rocket is gone, rocket can't check keys)
    }

    /**
     * Check whether there are any key pressed and react to them.
     */
    private void checkKeys() 
    {
        if (Greenfoot.isKeyDown("space")) 
        {
            fire();
        }
        if (Greenfoot.isKeyDown("left")) 
        {
            //get my rotatio, and then based off of that, set my rotation
            //to change by 5 degrees
            setRotation(getRotation()-5);
        }
        if (Greenfoot.isKeyDown("right")) 
        {
            //get my rotatio, and then based off of that, set my rotation
            //to change by 5 degrees
            setRotation(getRotation()+5);
        }
        ignite(Greenfoot.isKeyDown("up")); //isKeyDown provides the
        if (Greenfoot.isKeyDown("z"))
        {
            //to add a prton wave into our world when this key is pressed
            StartProton();

        }
    }

    /**
     * changes between two rocket images, depending on if the up key is pressed 
     * adds force in the direction we are facing if up is pressed
     */
    private void ignite (boolean boosterOn)
    {
        if (boosterOn)
        {
            setImage ("rocketWithThrust.png");
            addForce(new Vector(getRotation(), 0.3));//we are asking for direction get the rotation we are already pointing in
        }
        else
        {
            setImage ("rocket.png");
        }
    }

    /**
     * Fire a bullet if the gun is ready.
     */
    private void fire() 
    {
        if (reloadDelayCount >= gunReloadTime) 
        {
            Bullet bullet = new Bullet (getMovement().copy(), getRotation());
            getWorld().addObject (bullet, getX(), getY());
            bullet.move ();
            reloadDelayCount = 0;
        }
    }

    /**
     * method checks to see if we have collided with an asteroid, if we have remove rocket and add explosion BOOM!
     */
    private void checkCollision()
    {
        //Actor a = getOneIntersectingObject(Asteroid.class);
        //if (a != null)                       // a way to simplify (a is storing the intersecting object line)
        //{ World world = getWorld(); and then what follows which are the two line in my if statement below
        if (getOneIntersectingObject(Asteroid.class) != null && yes == false)// as long as it doesn't equal nothing
        //instead of going to world now it goes to space but space is a world so inherited methods still not affected for other objects
        { //this is casting , the use of this in the below using space instead of world
            Space space = (Space)getWorld(); //go to our world and run this method      
            HealthBar healthbar = space.getHealthBar();
            healthbar.health--;
            healthbar.adjustValue(-1);
            if (healthbar.value == 0)
            {
                space.addObject(new Explosion(),getX(),getY()); // short answer question of statements make difference remember why did it not work when this line of 
                space.removeObject(this); // refers to the rocket running the code  
                yes = true;
                //space.gameOver(); //exam question!!! Why do we get an error here? //another question! us doing casting
            }
        }
            else if (getOneIntersectingObject(Asteroid.class) != null)
            {
                yes = false;
            }
            //check if colliding with asteroid
            //if we are
            //remove rocket
            //add explosion
            //game over
            //another place to see casting is in Newton's project in the smoothmover method With the double values into 
        }

        // Space space = (Space)getWorld(); //go to our world and run this method      
        // space.addObject(new Explosion(),getX(),getY()); // short answer question of statements make difference remember why did it not work when this line of 
        // space.removeObject(this); // refers to the rocket running the code  
      
        /**
         * Fire up a proton if the count is ready and it has already calmed down.
         */
        private void StartProton() 
        {
            if (reloadPowerCount >= protonWaveCalm) 
            {
                ProtonWave protonWave = new ProtonWave ();
                getWorld().addObject (protonWave, getX(), getY());
                reloadPowerCount = 0;
            }
        }

    }
danpost danpost

2022/1/4

#
SportingLife7 wrote...
<< Code Omitted >>
The HealthBar class codes is what you need to show.
SportingLife7 SportingLife7

2022/1/4

#
Sorry, you lost me there.
SportingLife7 SportingLife7

2022/1/4

#
Exactly what do you mean by HealthBar class codes? (I don't know what i'm doing)
danpost danpost

2022/1/4

#
SportingLife7 wrote...
Exactly what do you mean by HealthBar class codes? (I don't know what i'm doing)
Seriously? You even said above
This is the rocket class code (I apologize for the mess)
and gave its codes. I want you to say:
This is the health bar class code
and give its codes.
SportingLife7 SportingLife7

2022/1/5

#
Got it, thanks. This is the healthbar class code
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
/**
 * Write a description of class HealthBar here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class HealthBar extends Actor
{
    int health = 20;
    int healthBarWidth = 80;
    int healthBarHeight = 10;
    int pixelsPerHealthPoint = healthBarWidth/health;

    /**
     * Act - do whatever the HealthBar wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public HealthBar()
    {
        update();
    }

    public void act() 
    {
        update();
        adjustValue(20);
    }    

    public void update()
    {
        setImage(new GreenfootImage(healthBarWidth + 2, healthBarHeight + 2));
        getImage().setColor(Color.WHITE);
        getImage().drawRect(0, 0,healthBarWidth + 1, healthBarHeight + 1);
        getImage().setColor(Color.PINK);
        getImage().fillRect(1, 1, health * pixelsPerHealthPoint, healthBarHeight);
    }

    // public void death()
    // {
        // if(health == 0)
        // {
            // Space space = (Space)getWorld(); //go to our world and run this method      
            // space.addObject(new Explosion(),getX(),getY()); // rocket actor coordinates needed here!
            // space.removeObject(Rocket.class);// refers to the rocket (but how can I refer the rocket!) running the code  
            // space.gameOver();//exam question!!
        // }
    // }

    public void adjustValue(int changeAmount)
    {
        health += changeAmount; // make change
        if (health > 20) health = 20; //maintain range
        if (health < 0) health = 0;
        update(); // update image
    }
}
danpost danpost

2022/1/5

#
Okay. So, instead of "healthbar.value" use "healthbar.health". Remove the act method from your HealthBar class (lines 24 thru 29).
SportingLife7 SportingLife7

2022/1/5

#
That worked, but now the healthbar completely goes out as soon as it touches one asteroid. The explosion and everything appears when the healthbar runs out, which is great, thanks for your help on that.
SportingLife7 SportingLife7

2022/1/5

#
Actually, we are all good. Thanks for your help @danpost.
You need to login to post a reply.