This project assumes familiarity with using classes with Processing in Eclipse.
This project demonstrates:
- Abstracting a grid
- Using a 2D array
Program functionality & organization
The program displays a grid and responds to clicks on boxes by displaying, changing, and removing faces within the boxes.
The FaceGrid
class has the same getRow(int y)
, getColumn(int x)
, getTopY(int row)
, getLeftX(int column)
, and drawGrid()
methods as in Abstracting a grid. These methods are used without worrying about how they work. The details of the methods are abstracted away.
The constants at the top of FaceGrid
have been made public
so they can be used by the Face
class.
The FaceGrid
class stores Face
objects in a 2D array. The FaceGrid
method draw
asks each Face
object to draw itself. The FaceGrid
method mousePressed
responds to clicks.
The Face
class is responsible for drawing a face at a given row and column. The Face
class maintains state, including color and whether the face is sad. The Face
class uses constants and methods from the FaceGrid
class to draw a face.
Program code
Face
class
import processing.core.PApplet;
public class Face
{
public static final int DIAMETER = 50;
private FaceGrid parent;
private int color;
private boolean isSad;
public Face(FaceGrid p)
{
parent = p;
color = parent.color(
parent.random(256),
parent.random(256),
parent.random(256));
isSad = false;
}
public void drawSelf(int row, int column)
{
final int centerX = parent.getLeftX(column) + (FaceGrid.BOX_WIDTH / 2);
final int centerY = parent.getTopY(row) + (FaceGrid.BOX_HEIGHT / 2);
parent.fill(color);
parent.ellipse(centerX, centerY, DIAMETER, DIAMETER);
parent.fill(255);
parent.ellipse(centerX - 10, centerY - 5, 5, 5);
parent.ellipse(centerX + 10, centerY - 5, 5, 5);
if(isSad)
{
parent.arc(centerX, centerY + 10, 15, 10,
PApplet.radians(180), PApplet.radians(360));
}
else
{
parent.arc(centerX, centerY + 10, 15, 10,
PApplet.radians(0), PApplet.radians(180));
}
}
public boolean isSad()
{
return isSad;
}
public void makeSad()
{
isSad = true;
}
}
FaceGrid
class
import processing.core.PApplet;
public class FaceGrid extends PApplet
{
public static final int TOP_OFFSET = 20;
public static final int LEFT_OFFSET = 15;
public static final int BOX_WIDTH = 75;
public static final int BOX_HEIGHT = 75;
public static final int ROWS = 5;
public static final int COLUMNS = 8;
private Face[][] faces;
public static void main(String[] args)
{
PApplet.main("FaceGrid");
}
public void settings()
{
final int SCREEN_WIDTH = (LEFT_OFFSET * 2) + (COLUMNS * BOX_WIDTH);
final int SCREEN_HEIGHT = (TOP_OFFSET * 2) + (ROWS * BOX_HEIGHT);
size(SCREEN_WIDTH, SCREEN_HEIGHT);
}
public void setup()
{
faces = new Face[ROWS][COLUMNS];
noLoop();
redraw();
}
public void draw()
{
background(0);
drawGrid();
for(int row = 0; row < faces.length; row++)
{
for(int col = 0; col < faces[0].length; col++)
{
if(faces[row][col] != null)
{
faces[row][col].drawSelf(row, col);
}
}
}
}
public void mousePressed()
{
final int row = getRow(mouseY);
final int col = getColumn(mouseX);
if(row != -1 && col != -1)
{
if(faces[row][col] == null)
{
faces[row][col] = new Face(this);
}
else if( ! faces[row][col].isSad() )
{
faces[row][col].makeSad();
}
else
{
faces[row][col] = null;
}
redraw();
}
}
// returns row corresponding to y or -1 if not an existing row
public int getRow(int y)
{
if(y < getTopY(0) || y >= getTopY(ROWS))
return -1;
return (y - TOP_OFFSET) / BOX_HEIGHT;
}
// returns column corresponding to x or -1 if not an existing column
public int getColumn(int x)
{
if(x < getLeftX(0) || x >= getLeftX(COLUMNS))
return -1;
return (x - LEFT_OFFSET) / BOX_WIDTH;
}
public int getTopY(int row)
{
return TOP_OFFSET + (row * BOX_HEIGHT);
}
public int getLeftX(int column)
{
return LEFT_OFFSET + (column * BOX_WIDTH);
}
public void drawGrid()
{
rectMode(CORNER);
noFill();
strokeWeight(1);
stroke(255);
for(int row = 0; row < ROWS; row++)
{
for(int col = 0; col < COLUMNS; col++)
{
rect(getLeftX(col), getTopY(row), BOX_WIDTH, BOX_HEIGHT);
}
}
}
}
Help & comments
Get help from AP CS Tutor Brandon Horn