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

2013/11/1

Fireworks physics?

OhSoFoxy OhSoFoxy

2013/11/1

#
I'm looking to make fireworks appear wherever the mouse is clicked.. I've called the firework base image Rock... City (or world) code:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class city here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class city extends World
{

    /**
     * Constructor for objects of class city.
     * 
     */
    public city()
    {    
        // Create a new world with 600x400 cells with a cell size of 1x1 pixels.
        super(800, 500, 1); 
        placeRocks();

       Explosion.initialiseImages();
    }
    
    public void placeRocks()
    {
        for (int i = 0; i < 10; i++) {
            int x = Greenfoot.getRandomNumber( getWidth() );
            int y = Greenfoot.getRandomNumber( getHeight());
            addObject ( new Rock(), x, y);
}
}
}
Rock code:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Rock here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Rock extends Actor
{
    private static final int NUM_FRAGMENTS = 100;
    
    /**
     * Act - do whatever the Rock wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        String key = Greenfoot.getKey();
        if (key != null)
        {
            explode();
    }    
}
   

    public void explode()
    {
        placeDebris (getX(), getY(), NUM_FRAGMENTS);
        getWorld().removeObject(this);
        
        
    }
    
    private void placeDebris(int x, int y, int numFragments)
    {
        for (int i=0; i < numFragments; i++) {
            getWorld().addObject ( new debris(), x, y);
}
}
}
Explosion code:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.*;

/**
 * An explosion. It starts by expanding and then collapsing. 
 * The explosion will explode other obejcts that the explosion intersects.
 * 
 * @author Poul Henriksen
 * @version 1.0.1
 */
public class Explosion extends Actor
{
    /** How many images should be used in the animation of the explostion */
    private final static int IMAGE_COUNT= 8;
    
    /** 
     * The images in the explosion. This is static so the images are not
     * recreated for every object (improves performance significantly).
     */
    private static GreenfootImage[] images;
    
    /** Current size of the explosion */
    private int imageNo = 0;
    
    /** How much do we increment the index in the explosion animation. */
    private int increment=1;    
    
    public Explosion() {
        initialiseImages();
        setImage(images[0]);        
        Greenfoot.playSound("Explosion.wav");
    }    
    
    /** 
     * Create the images for explosion.
     */
    public synchronized static void initialiseImages() {
        if(images == null) {
            GreenfootImage baseImage = new GreenfootImage("explosion.png");
            int maxSize = baseImage.getWidth()/2;
            int delta = maxSize / (IMAGE_COUNT+1);
            int size = 0;
            images = new GreenfootImage[IMAGE_COUNT];
            for(int i=0; i < IMAGE_COUNT; i++) {
                size = size + delta;
                images[i] = new GreenfootImage(baseImage);
                images[i].scale(size, size);
            }
        }
    }
    
    /**
     * EXPLODE!
     */
    public void act()
    { 
        if(imageNo > 0) {
            setImage(images[imageNo]);
        }

        imageNo += increment;
        if(imageNo >= IMAGE_COUNT) {
            increment = -increment;
            imageNo += increment;
        }
        
        if(imageNo <= 0) {
            setImage(new GreenfootImage(1,1));
        }
        }
    }
       
SmoothMover code:
import greenfoot.*;  // (World, Actor, GreenfootImage, and Greenfoot)
import java.util.*;
/**
 * A variation of an actor that maintains precise location (using doubles for the co-ordinates
 * instead of ints). It also maintains a current movement in form of a movement vector.
 * 
 * This is a variation of the SmoothMover class presented ealier in the book (version 2.0).
 * This version implements wrap-around movement: when the actor moves out of the world at one
 * side, it enters it again at the opposite edge.
 * 
 * @author Poul Henriksen
 * @author Michael Kolling
 * 
 * @version 2.1
 */
public abstract class SmoothMover extends Actor
{
    private Vector movement;
    private double exactX;
    private double exactY;
    
    public SmoothMover()
    {
        this(new Vector());
    }
    
    /**
     * Create new thing initialised with given speed.
     */
    public SmoothMover(Vector movement)
    {
        this.movement = movement;
    }
    
    /**
     * Move in the current movement direction. Wrap around to the opposite edge of the
     * screen if moving out of the world.
     */
    public void move() 
    {
        exactX = exactX + movement.getX();
        exactY = exactY + movement.getY();
        
        if (outOfWorld()) {
            getWorld().removeObject(this);
        }
        else{
            setLocation(exactX, exactY);
        }
    }
    
    private boolean outOfWorld()
    { return     (exactX >= getWorld().getWidth())
            || (exactX < 0)
            || (exactY >= getWorld().getHeight())
            || (exactY < 0);
        }
    
    /**
     * Set the location from exact coordinates.
     */
    public void setLocation(double x, double y) 
    {
        exactX = x;
        exactY = y;
        super.setLocation((int) x, (int) y);
    }
    
    /**
     * Set the location from int coordinates.
     */
    public void setLocation(int x, int y) 
    {
        exactX = x;
        exactY = y;
        super.setLocation(x, y);
    }

    /**
     * Return the exact x-coordinate (as a double).
     */
    public double getExactX() 
    {
        return exactX;
    }

    /**
     * Return the exact y-coordinate (as a double).
     */
    public double getExactY() 
    {
        return exactY;
    }

    /**
     * Increase the speed with the given vector.
     */
    public void addForce(Vector force) 
    {
        movement.add(force);
    }
    
    /**
     * Accelerate the speed of this mover by the given factor. (Factors < 1 will
     * decelerate.)
     */
    public void accelerate(double factor)
    {
        movement.scale(factor);
        if (movement.getLength() < 0.15) {
            movement.setNeutral();
        }
    }
    
    /**
     * Return the speed of this actor.
     */
    public double getSpeed()
    {
        return movement.getLength();
    }
    
    /**
     * Stop movement of this actor.
     */
    public void stop()
    {
        movement.setNeutral();
    }
    
    /**
     * Return the current speed.
     */
    public Vector getMovement() 
    {
        return movement;
    }
}
debris code:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class debris here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class debris extends SmoothMover
{

private static final Vector GRAVITY = new Vector(90, 1.5);
private static final int FORCE = 15;

public debris()
{
int direction = Greenfoot.getRandomNumber(360);
int movement = Greenfoot.getRandomNumber(FORCE);
addForce( new Vector(direction, movement));

// random image size
GreenfootImage img = getImage();
int width = Greenfoot.getRandomNumber(30) + 1;
int height = Greenfoot.getRandomNumber(30) + 1;
img.scale (width, height);

setRotation (Greenfoot.getRandomNumber(360));
}
    /**
     * Act - do whatever the debris wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        addForce(GRAVITY);
        move();
    }    
}
And finally, my Vector code:
import greenfoot.Greenfoot;

/**
 * A 2D vector.
 * 
 * @author Poul Henriksen
 * @author Michael Kolling
 * 
 * @version 2.0
 */
public final class Vector
{
    double dx;
    double dy;
    int direction;
    double length;
    
    /**
     * Create a new, neutral vector.
     */
    public Vector()
    {
    }

    /**
     * Create a vector with given direction and length. The direction should be in
     * the range [0..359], where 0 is EAST, and degrees increase clockwise.
     */
    public Vector(int direction, double length)
    {
        this.length = length;
        this.direction = direction;
        updateCartesian();
    }

    /**
     * Create a vector by specifying the x and y offsets from start to end points.
     */
    public Vector(double dx, double dy)
    {
        this.dx = dx;
        this.dy = dy;
        updatePolar();
    }

    /**
     * Set the direction of this vector, leaving the length intact.
     */
    public void setDirection(int direction) 
    {
        this.direction = direction;
        updateCartesian();
    }
   
    /**
     * Add another vector to this vector.
     */
    public void add(Vector other) 
    {
        dx += other.dx;
        dy += other.dy;
        updatePolar();
    }
    
    /**
     * Set the length of this vector, leaving the direction intact.
     */
    public void setLength(double length) 
    {
        this.length = length;
        updateCartesian();
    }
    
    /**
     * Scale this vector up (factor > 1) or down (factor < 1). The direction
     * remains unchanged.
     */
    public void scale(double factor) 
    {
        length = length * factor;
        updateCartesian();
    }
    
    /**
     * Set this vector to the neutral vector (length 0).
     */
    public void setNeutral() {
        dx = 0.0;
        dy = 0.0;
        length = 0.0;
        direction = 0;
    }
    
    /**
     * Revert to horizontal component of this movement vector.
     */
    public void revertHorizontal() {
        dx = -dx;
        updatePolar();
    }
    
    /**
     * Revert to vertical component of this movement vector.
     */
    public void revertVertical() {
        dy = -dy;
        updatePolar();
    }
    
    /**
     * Return the x offset of this vector (start to end point).
     */
    public double getX() {
        return dx;
    }
     
    /**
     * Return the y offset of this vector (start to end point).
     */
    public double getY() {
        return  dy;
    }
    
    /**
     * Return the direction of this vector (in degrees). 0 is EAST.
     */
    public int getDirection() {
        return direction;
    }
    
    /**
     * Return the length of this vector.
     */
    public double getLength() {
        return length;
    }

    /**
     * Update the direction and length fom the current dx, dy.
     */
    private void updatePolar() 
    {
        this.direction = (int) Math.toDegrees(Math.atan2(dy, dx));
        this.length = Math.sqrt(dx*dx+dy*dy);
    }   
    
    /**
     * Update dx and dy from the current direction and length.
     */
    private void updateCartesian() 
    {
        dx = length * Math.cos(Math.toRadians(direction));
        dy = length * Math.sin(Math.toRadians(direction));   
    }
    
    /**
     * Return a copy of this vector.
     */
    public Vector copy() 
    {
        Vector copy = new Vector();
        copy.dx = dx;
        copy.dy = dy;
        copy.direction = direction;
        copy.length = length;
        return copy;
    }    
}
I've been working at this, using the explosions tutorials to make the base. So how would I get this to work?
You need to login to post a reply.