Additional code for the supernova movie -- Greenfoot programming lesson continued
Find other posts in the same category: | | |

Long description

The supernova scenario needs several more files. The video tutorial shows you where to copy and paste the code from.
http://www.greenfoot.org/doc/videos.html

I've pasted in the code here
(a) to show you the final versions of the code after it's been changed from a rock explosion to a supernova explosion
(b) so you can copy and paste it easily from here
(b) and so that the code can be found by search engines. It's hard to find Greenfoot code in search engines.

This is the code for the World sub-class MyWorld

import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
public class MyWorld extends World
{
public MyWorld()
{
super(1000, 800, 1);
Rock rock = new Rock();
addObject(rock, 500,400);
}
}

Under the Actor class create a sub-class called SmoothMover and put this code in it

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

/**
* A superclass for specific actor classes that add smooth movement functionality.
*
* Movement is based on doubles (rather than ints), and thus generates smoother
* movement for fast moving actors in high resolution worlds.
*
* The SmoothMover also implements world wrap-around: when moving out of the world at any edge,
* the actor will enter again at the opposite side.
*
* Requires class Vector.
*
* @author Poul Henriksen
*/
public abstract class SmoothMover extends Actor
{
private Vector speed = new Vector();

private double x = 0;
private double y = 0;

public SmoothMover()
{
}

/**
* Create new thing initialised with given speed.
*/
public SmoothMover(Vector speed)
{
this.speed = speed;
}

/**
* Move forward one step.
*/
public void move()
{
x = x + speed.getX();
y = y + speed.getY();

if (outOfWorld()) {
getWorld().removeObject(this);
}
else {
setLocation(x, y);
}
}

private boolean outOfWorld()
{
return (x >= getWorld().getWidth())
|| (x < 0)
|| (y >= getWorld().getHeight())
|| (y < 0) ;
}

/**
* Providing 'setLocation' based on doubles. This will eventually call
* the built-in 'setLocation' method in Actor.
*/
public void setLocation(double x, double y)
{
this.x = x;
this.y = y;
super.setLocation((int) x, (int) y);
}

/**
* Override the default 'setLocation' method to keep our own coordinates
* up-to-date.
*/
public void setLocation(int x, int y)
{
setLocation((double) x, (double) y);
}

/**
* Increase the speed with the given vector.
*/
public void increaseSpeed(Vector s)
{
speed.add(s);
}

/**
* Return the current speed.
*/
public Vector getSpeed()
{
return speed;
}
}

Under SmoothMover create a sub-class called Debris and put this code in it

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(0, 0);

public Debris()
{
int direction = Greenfoot.getRandomNumber(360);
int speed = Greenfoot.getRandomNumber(30);
increaseSpeed( new Vector(direction, speed));
}
/**
* 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()
{
increaseSpeed(GRAVITY);
move();
}
}

You will need one more file. You will create a new class called Vector. Look at the top on the menu bar. Click Edit (to the left of Help). Click New class. Name the new class Vector. Look in the box under the Actor class. Right click on the Vector box. Open the editor. Paste this code into it.

/**
* Vector - This class was written as a utility class for Greenfoot scenarios.
*
* This class represents a 2-dimensional vector.
*
* The vector can be used to deal with movement information (speed and
* direction) of actors. An actor can store a vector, and then other vectors
* can be added to modify the current velocity and direction.
*
* @author Poul Henriksen
* @author Michael Kolling
*
* @version 1.1 (July 2007)
*/
public class Vector
{
double dx = 0;
double dy = 0;
int direction = 0;
double length;

public Vector()
{
}

public Vector(int direction, double length)
{
this.length = length;
this.direction = direction;
updateCartesian();
}

// public Vector(Location start, Location end)
// {
// dx = end.getX() - start.getX();
// dy = end.getY() - start.getY();
// updatePolar();
// }

/**
* Set the direction of this vector.
*/
public void setDirection(int direction) {
this.direction = direction;
updateCartesian();
}

/**
* Add other vector to this vector.
*/
public void add(Vector other) {
dx += other.dx;
dy += other.dy;
updatePolar();
}

public void reduceLength(double d) {
length = length - d;
updateCartesian();
}

public void scale(double factor) {
length = length * factor;
updateCartesian();
}

public void setNeutral() {
dx = 0.0;
dy = 0.0;
length = 0.0;
direction = 0;
}

/**
* 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));
}

public double getX() {
return dx;
}

public double getY() {
return dy;
}

public int getDirection() {
return direction;
}

public double getLength() {
return length;
}

/**
* Create 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;
}

public String toString() {
return "[" + direction + " " + length + " / " + dx + "," + dy + "]";
}
}


Previous page

To see articles on the same topic, click the links below the name of the author at the top of this page.