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

2018/10/26

Making world generation spawn user-controlled actors, or making an actor that creates more of the same actor under user control.

112ccs25 112ccs25

2018/10/26

#
I don't expect this to work, and frankly I'm only doing it because I've got spare time in class. I've been messing with the Asteroids game from the book, and I'm trying to either
  • Create several Rockets upon world creation
  • Make the Rocket able to shoot more Rockets that can then shoot more Rockets
Here is my space code:
import greenfoot.*;  // (World, Actor, GreenfootImage, and Greenfoot)
import java.awt.Color;

/**
 * Space. Something for rockets to fly in...
 * 
 * @author Michael Kolling
 */
public class Space extends World
{
    public Space() 
    {
        super(600, 400, 1);
        GreenfootImage background = getBackground();
        background.setColor(greenfoot.Color.BLACK);
        background.fill();
        createStars(300);
        Explosion.initialiseImages();
        
    }
    
    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 color = 150 - Greenfoot.getRandomNumber(120);
             background.setColorAt(x,y,new greenfoot.Color(color,color,color));
        }
    }

    public void populate()
    {
        addObject(new Asteroid(), Greenfoot.getRandomNumber(500),Greenfoot.getRandomNumber(400));
 
        addObject(new Rocket(), Greenfoot.getRandomNumber(500),Greenfoot.getRandomNumber(400));
        
    }
    public void RandomThingMethod()
    {
        int z = Greenfoot.getRandomNumber(10);
        int x = Greenfoot.getRandomNumber(getWidth());
        int y = Greenfoot.getRandomNumber(getHeight());
            addObject(new Asteroid(),x,y); //keep in mind that it's decided by random if it adds it or not.
    }
}
Here is my rocket code:
import greenfoot.*;  // (World, Rocket, GreenfootImage, and Greenfoot)

/**
 * A rocket that can be controlled by the arrowkeys: up, left, right.
 * The gun is fired by hitting the 'space' key.
 * 
 * @author Poul Henriksen
 * @author Michael Kolling
 */
public class Rocket extends Mover
{
    private int gunReloadTime;                  // The minimum delay between firing the gun.
    private int reloadDelayCount;               // How long ago we fired the gun the last time.
    private Vector acceleration;                // How fast the rocket is.
    private int shotsFired;                     // Number of shots fired.
    
    private GreenfootImage rocket = new GreenfootImage("rocket.png");    


    /**
     * Initilise this rocket.
     */
    public Rocket()
    {
        gunReloadTime = 20;
        reloadDelayCount = 0;
        acceleration = new Vector(0, 0.3);
        increaseSpeed(new Vector(13, 0.3)); // initially slowly drifting
        shotsFired = 0;
    }

    /**
     * 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()
    {
        move();
        checkCollision();
        checkKeys();
        reloadDelayCount++;
    }
    
    /**
     * Return the number of shots fired from this rocket.
     */
    public int getShotsFired()
    {
        return shotsFired;
    }
    
    /**
     * Return the approximate current travelling speed of this rocket.
     */
    public int getSpeed()
    {
        return (int) (getMovement().getLength() * 10);
    }
    
    /**
     * Set the time needed for re-loading the rocket's gun. The shorter this time is,
     * the faster the rocket can fire. The (initial) standard time is 20.
     */
    public void setGunReloadTime(int reloadTime)
    {
        gunReloadTime = reloadTime;
    }
    
    /**
     * Check whether we are colliding with an asteroid.
     */
    private void checkCollision() 
    {
        Asteroid a = (Asteroid) getOneIntersectingObject(Asteroid.class);
        if(a != null) {
            getWorld().addObject(new Explosion(), getX(), getY());
            getWorld().removeObject(this);
        }
    }
    
    /**
     * Check whether there are any key pressed and react to them.
     */
    private void checkKeys() 
    {
        ignite(Greenfoot.isKeyDown("up"));
        
        if(Greenfoot.isKeyDown("left")) {
            setRotation(getRotation() - 5);
        }        
        if(Greenfoot.isKeyDown("right")) {
            setRotation(getRotation() + 5);
        }
        if(Greenfoot.isKeyDown("space")) {
            fire();
        }        
    }
    
    /**
     * Should the rocket be ignited?
     */
    private void ignite(boolean boosterOn) 
    {
        if(boosterOn) {
            acceleration.setDirection(getRotation());
            increaseSpeed(acceleration);
        }
        else {
            setImage(rocket);        
        }
    }
    
    /**
     * Fire a bullet if the gun is ready.
     */
    private void fire() 
    {
        if(reloadDelayCount >= gunReloadTime) {
            Bullet b = new Bullet(getMovement().copy(), getRotation());
            getWorld().addObject(b, getX(), getY());
            b.move();
            shotsFired++;
            reloadDelayCount = 0;
        }
    }
 
public class Any extends Rocket implements Cloneable // must be implemented
{
    // the rocket method
    public Object rocket()
    {
        try
        {
            Rocket rocket = (Rocket)super.clone();
            // in the case that the actor rocketd was in the world, the 'world' field of the
            // rocket needs to be reset to 'null' before adding rocket into the world;
            // one not only cannot add an object into a world it is already in, but
            // cannot even add one into a world that it only appears to be in
            if (rocket.getWorld() != null)
            {
                rocket.getWorld().removeObject(rocket);
                getWorld().addObject(rocket, getX(), getY());
            }
            return rocket;
        }
        catch (CloneNotSupportedException cnse) // must be caught
        {
            System.out.println("Clone not supported");
        }
        return null;
    }
     
    // sample use
    public void act()
    {
        if (Greenfoot.mouseClicked(this))
        {
            Any rocket = (Any)rocket();
            if (rocket != null) rocket.move(50);
        }
    }
}

}
If anyone knows if this is even possible, and has the spare time to help a couple teenagers have a good laugh, feel free to reply
danpost danpost

2018/10/26

#
I really do not think you want to clone a rocket. There are no states that a rocket-created rocket would need from the rocket that created it (gunReloadTime is a constant all new rockets will get; reloadDelayCount is specific to each rocket; acceleration is variable and specific to each rocket; and as for shotsFired, I doubt you want what current value the rocket creating it has for the new rocket). Just create a new Rocket object using 'new Rocket()' instead of trying to clone one. The only thing you may have to do is match the rotation:
// having a Rocket create a new Rocket
Actor rocket = new Rocket();
getWorld().addObject(rocket, getX(), getY());
rocket.setRotation(getRotation());
You can then move the rocket off of its creator. You may also want to set the speed of the new rocket. This would involve changing the magnitude of the Vector object for speed (held in the SmoothMover class).
You need to login to post a reply.