I'm looking to make fireworks appear wherever the mouse is clicked.. I've called the firework base image Rock...
City (or world) code:
Rock code:
Explosion code:
SmoothMover code:
debris code:
And finally, my Vector code:
I've been working at this, using the explosions tutorials to make the base. So how would I get this to work?
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);
}
}
}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);
}
}
}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));
}
}
}
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;
}
}
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();
}
}
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;
}
}
