A Spinning Box¶
In these notes we’ll create a class for a rectangle that can move and spin. It’s a good example of how to go about creating your own animated sprites.
We will need the Sprite class:
class Sprite {
  float x;
  float y;
  float dx;
  float dy;
  void update() {
    x += dx;
    y += dy;
  }
}
Here is the SpinningBox class, and its variables:
class SpinningBox extends Sprite {
    float width;
    float height;
    float angleInDegrees;
    float dAngle; // rate of change of angle
    color fillColor;
    color strokeColor;
    // ...
} // class SpinningBox
Recall that extends Sprite means that a copy of all the variables and
functions in the Sprite class will be put in SpinningBox. So, we don’t
need to add x, y, dx, or dy because they are inherited from
Sprite.
The render() function draws the box, while the update() function makes
it move:
void render() {
  rectMode(CENTER);
  pushMatrix();
  // move the origin to the center of the box
  translate(x, y);
  rotate(radians(angleInDegrees));
  fill(fillColor);
  stroke(strokeColor);
  rect(0, 0, w, h);
  popMatrix();
}
void update() {
  super.update();
  angleInDegrees += dAngle;
}
This draws the box centered at, and rotated around, the point (x, y).
The statement super.update() calls that update() function in the
Sprite class. The term “super” refers to the fact that Sprite is the
“super class” of SpinningBox.
Here’s a program that animates it:
SpinningBox b = new SpinningBox();
void setup() {
  size(500, 500);
  b.x = 250;
  b.y = 250;
  b.w = 200;
  b.h = 150;
  b.angleInDegrees = 0;
  b.dAngle = 2;
  b.fillColor = color(0, 255, 0);
  b.strokeColor = color(255, 0, 0);
}
void draw() {
  background(255);
  b.render();
  b.update();
}
Changing update¶
To change how the box moves, modify update(). For example:
class SpinningBox extends Sprite {
  // ...
  void update() {
    // super.update();
    angleInDegrees += dAngle;
    w = map(mouseY, 0, 500, 50, 300);
    h = map(mouseX, 0, 500, 50, 300);
    x = mouseX;
    y = mouseY;
  }
} // class SpinningBox
The call to super.update() has been commented-out but left in as a
reminder that we can call if it we want the default Sprite update
behaviour.
Multiple Spinning Boxes¶
It’s easy to make as many spinning boxes as you like. For example:
Box b = new Box();
Box c = new Box();
void setup() {
  size(500, 500);
  b.x = 250;
  b.y = 250;
  b.w = 200;
  b.h = 150;
  b.angleInDegrees = 0;
  b.dAngle = 2;
  b.fillColor = color(0, 255, 0);
  b.strokeColor = color(255, 0, 0);
  c.x = 25;
  c.y = 350;
  c.w = 400;
  c.h = 15;
  c.angleInDegrees = 0;
  c.dAngle = -0.5;
  c.fillColor = color(23, 255, 44);
  c.strokeColor = color(255, 200, 100);
}
void draw() {
  background(255);
  b.render();
  b.update();
  c.render();
  c.update();
}
The procedure for creating and using sprites is always the same:
- Create a class for your animated object that extends - Sprite.
- Add a - render()function that draws the object based on the current values of its variables.- Do not put any code that changes variables in - render()! Put all such code into- update().
- Add a customized - update()function, calling- super.update()(the- update()function from- Sprite) if necessary. If you are happy with the default- update()in- Sprite, then you don’t need a custom- update().- Do not put any drawing code in update! All drawing code should be in - render().
To use a sprite, follow these steps:
- Create an object using - newand assign it to a variable, e.g.:- SpinningBox b = new SpinningBox(); 
- Inside - setup(), assign initial values to all the variables in the object.
- Inside - draw(), call the objects- render()function to display it on the screen, and its- update()function to change its variables.
An Image Sprite¶
An image sprite is an animated object that draws an image.
Images behave similarly to rectangles, and so we will use SpinningBox as a
guide for writing the ImageSprite class:
class Sprite {
  float x;
  float y;
  float dx;
  float dy;
  void update() {
    x += dx;
    y += dy;
  }
}
class ImageSprite extends Sprite {
  PImage img;
  float angleInDegrees;
  float dAngle;
  void render() {
    imageMode(CENTER);
    pushMatrix();
    // move the origin to the center of the image
    translate(x, y);
    rotate(radians(angleInDegrees));
    image(img, 0, 0);
    popMatrix();
  }
  void update() {
    // super.update();
    x = mouseX;
    y = mouseY;
    angleInDegrees += dAngle;
  }
}
ImageSprite a = new ImageSprite();
void setup() {
  size(500, 500);
  a.img = loadImage("cat.jpg");
  a.x = 250;
  a.y = 250;
  a.angleInDegrees = 0;
  a.dAngle = 2;
}
void draw() {
  background(255);
  a.render();
  a.update();
}
For this code to work, you must have an image file named cat.jpg in your
program’s data folder.
Questions¶
- Why are - xand- ynot defined in the- SpinningBoxclass?
- What does the statement - super.update()mean in the- update()function of- SpinningBox? What would happen if that statement were deleted?
- What is the value of - bimmediately after this statement is executed:- SpinningBox b; 
Programming Questions¶
- Make a class called SpinningTrianglethat extendsSpriteand makes a triangle move around the screen, and also rotate around one of its corner points.
- Make a class called BouncingBoxthat extendsSpriteand makes a box bounce around the screen. Don’t let any part of the box go off the screen.
Source Code¶
class Sprite {
  float x;
  float y;
  float dx;
  float dy;
  void update() {
    x += dx;
    y += dy;
  }
}
class Box extends Sprite {
  float w;
  float h;
  float angleInDegrees;
  float dAngle; // rate of change of the angle
  color fillColor;
  color strokeColor;
  void render() {
    rectMode(CENTER);
    pushMatrix();
    // move the origin to the center of the box
    translate(x, y);
    rotate(radians(angleInDegrees));
    fill(fillColor);
    stroke(strokeColor);
    rect(0, 0, w, h);
    popMatrix();
  }
  void update() {
    // super.update();
    angleInDegrees += dAngle;
    w = map(mouseY, 0, 500, 50, 300);
    h = map(mouseX, 0, 500, 50, 300);
    x = mouseX;
    y = mouseY;
  }
} // class Box
Box b = new Box();
Box c = new Box();
void setup() {
  size(500, 500);
  b.x = 250;
  b.y = 250;
  b.w = 200;
  b.h = 150;
  b.angleInDegrees = 0;
  b.dAngle = 2;
  b.fillColor = color(0, 255, 0);
  b.strokeColor = color(255, 0, 0);
  c.x = 25;
  c.y = 350;
  c.w = 400;
  c.h = 15;
  c.angleInDegrees = 0;
  c.dAngle = -0.5;
  c.fillColor = color(23, 255, 44);
  c.strokeColor = color(255, 200, 100);
}
void draw() {
  background(255);
  b.render();
  b.update();
  c.render();
  c.update();
}