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

2020/4/1

Help with Shield for Asteroids

elsmog elsmog

2020/4/1

#
Hello, I am working through the first edition and I'm stuck on the Asteroids scenario in the last exercise: creating a shield. I have tried using the isKeyDown method for starting the shield visually, but, obviously, when I release the key the image returns to the regular rocket. I've poured over the documentation but I don't understand what I'm missing. Any hints?
danpost danpost

2020/4/1

#
Show rocket codes.
elsmog elsmog

2020/4/2

#
Hey @danpost, thanks for your reply! I actually figured it out in the meantime, just need the fresh eyes of a new day. I am wondering how to implement a shield that deflects asteroids rather than ignoring them, as I do now.
public class Rocket extends SmoothMover
{
    private static final int gunReloadTime = 5;         // The minimum delay between firing the gun.
    private static final int protonWaveReloadTime = 500; // The minimum delay between firing the proton wave.
    private static final int shieldReloadTime = 600;     // The minimum delay between deploying the shield.
    
    public int reloadDelayCount;               // How long ago we fired the gun the last time.
    public int protonWaveDelayCount; // How long ago we fired the proton wave.
    public int shieldDelayCount;     // How long ago we deployed the shield.
    
    public int shieldDuration = 200;  //How long the shield lasts.
   
    
    private GreenfootImage rocket = new GreenfootImage("rocket.png");    
    private GreenfootImage rocketWithThrust = new GreenfootImage("rocketWithThrust.png");
    private GreenfootImage rocketWithShield = new GreenfootImage("rocket-with-shield.png");
    private GreenfootImage rocketWithThrustAndShield = new GreenfootImage("rocket-thrust-shield.png");
    
    private boolean boosterOn = false;
    
    public boolean shieldActive = false;
    
    public GreenfootImage rocketImage = getImage();
    
    private static final int NUMBER_FRAGMENTS = 15;
    
    
    
    /**
     * Initilise this rocket.
     */
    public Rocket()
    {
        reloadDelayCount = 5;
        protonWaveDelayCount = 500;
        shieldDelayCount = 700;
        addForce(new Vector(0, 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()
    {
        Space space = (Space) getWorld();
        move();
        updateRocketImage();
        updateProtonWaveStatus();
        updateShieldStatus();
        checkKeys();
        checkCollision();
        reloadDelayCount++;
        protonWaveDelayCount++;
        shieldDelayCount++;
        space.newLevel();
    }
    
    /**
     * Check whether there are any key pressed and react to them.
     */
    private void checkKeys() 
    {
        ignite(Greenfoot.isKeyDown("up"));
        if (Greenfoot.isKeyDown("space")) 
        {
            fire();
        }

        if (Greenfoot.isKeyDown("left"))
        {
            setRotation(getRotation() - 5);
        }
        
        if (Greenfoot.isKeyDown("right"))
        {
            setRotation(getRotation() + 5);
        }
        
        if (Greenfoot.isKeyDown("z"))
        {
            startProtonWave();
        }
        
    }
    
    /**
     * 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;
        }
    }
    
    /**
     * Change rocket's image to show ignition and move the rocket up or down.
     */
    private void ignite(boolean boosterOn)
    {
        if (Greenfoot.isKeyDown("up"))
        {
            addForce(new Vector (getRotation(), 0.1));
        }
        
        else if (!Greenfoot.isKeyDown("up"))
        {
            boosterOn = false;
        }
    }
    
    /**
     * Check if the Rocket has collided with an asteroid, and if so, remove 
     * rocket from world and display an explosion. Then display final score.
     */
    private void checkCollision()
    {
        Actor intersectingAsteroid = getOneIntersectingObject(Asteroid.class);
        
        if (intersectingAsteroid != null && shieldActive == true)
        {
         // the asteroids do nothing to the rocket
        }
         
        if (intersectingAsteroid != null && shieldActive == false)
        {
            Space space = (Space) getWorld();
            explode();
            space.removeObject(this);
            space.gameOver();
        }
    }
    
    /**
     * Animate the rocket's destruction with sound.
     */
    public void explode()
    {
        placeDebris(this.getX(), this.getY(), NUMBER_FRAGMENTS);
        Greenfoot.playSound("MetalExplosion.wav");
    }
    
    /**
     * Place individual pieces of debris that once comprised the rocket's hull.
     */
    private void placeDebris(int x, int y, int numberFragments)
    {
        for (int i = 0; i < numberFragments; i++) 
        {
            getWorld().addObject ( new Debris(), x, y);
        }
    }
    
    /**
     * Place a proton wave into the world at the location of the rocket.
     */
    private void startProtonWave()
    {
        if (protonWaveDelayCount >= protonWaveReloadTime)
        {
            ProtonWave protonWave = new ProtonWave();
            getWorld().addObject (protonWave, getX(), getY());
            protonWaveDelayCount = 0;
        }
    }
    
    /**
     * Update the Proton Wave's gauge. When available, a blue circle appears in
     * the bottom left corner. When unavailable, there is no blue circle.
     */
    public void updateProtonWaveStatus()
    {
        Space space = (Space) getWorld();
        if (protonWaveDelayCount >= 500)
        {
            space.protonWaveCounter.showImage();
        }
        else if (protonWaveDelayCount < 500)
        {   
            space.protonWaveCounter.hideImage();
        }
        
    }
    
    /**
     * Update the Shield's gauge. When available, a green circle appears in the
     * bottom left corner. When unavailable, there is no green circle.
     */
    public void updateShieldStatus()
    {
        Space space = (Space) getWorld();
        if (shieldDelayCount >= 700)
        {
            space.shieldCounter.showImage();
        }
        else if (shieldDelayCount < 700)
        {   
            space.shieldCounter.hideImage();
        }
        
    }
    
    public void updateRocketImage()
    {
     // rocket with thrust
        if (Greenfoot.isKeyDown("up") && shieldActive == false)
        {
            setImage(rocketWithThrust);
        }
        
     // rocket with thrust and shield
        else if (Greenfoot.isKeyDown("up") && shieldActive == true)
        {
            setImage(rocketWithThrustAndShield);
            if (shieldDelayCount >= shieldDuration)
            {
                setImage(rocketWithThrust);
                shieldActive = false;
            }
        }
     
     // rocket with shield
        else if (Greenfoot.isKeyDown("c"))
        {
            if (shieldDelayCount >= shieldReloadTime)
            {
                setImage(rocketWithShield);
                shieldActive = true;
                shieldDelayCount = 0;
                if (shieldDelayCount >= shieldDuration)
                {
                    setImage(rocket);
                    shieldActive = false;
                }
            }
        }
        else if (shieldActive == true && !Greenfoot.isKeyDown("up"))
        {
            setImage(rocketWithShield);
            if (shieldDelayCount >= shieldDuration)
            {
                setImage(rocket);
                shieldActive = false;
            }
        }
     
     
     // rocket
        else 
        {   
            setImage(rocket);
        }
    }
    
}
danpost danpost

2020/4/2

#
elsmog wrote...
I am wondering how to implement a shield that deflects asteroids rather than ignoring them, as I do now. << Code Omitted >>
This may not be quite so easy to do. Remember that both the asteroids and the rocket are drifting/moving. It may not be enough just to change the direction of a colliding asteroid. In my asteroids scenario, which has shielding implemented, I had both colliding actors change their trajectories with the help of a smooth moving system. You may want to take a look at its codes -- especially the bumpRock method in the Rocket class. As an alternative, you could deflect just the asteroid; but, you will probably need to ensure that its velocity is greater than that of the rocket.
You need to login to post a reply.