Okay, I’m having another learning experience here. I don’t know what’s going wrong with this.
I’m experimenting with how classes work together, and how to pass data between them. When I run this code, I get a NullPointerException in the Tile constructor when it tries to initialize cSize.
I tried changing the Tile constructor so that it will take colW and rowH as parameters like this:
Tile(float x, float y, String id, int colW, int rowH) {
// ...
cSize = new PVector(colW, rowH);
// ...
and change the setTiles() function in Board so that it passes them like this:
tiles[n] = new Tile(grid.centers[c][r].x,
grid.centers[c][r].y,
str(n + 1), grid.colW, grid.rowH);
then the program runs okay.
From what I can tell, by the time the Tile constructor is reached, those values have already been initialized in the Grid class, they print the correct values in a println statement in the setTiles() function placed before the loop. So I don’t see why the Tile constructor can’t access them directly without needing to be passed as parameters.
Can someone please tell me what I’m missing?
Board board;
void setup() {
size(500, 500);
board = new Board();
}
void draw() {
background(0, 0, 255);
board.display();
}
class Board {
Grid grid;
Tile[] tiles;
Board() {
grid = new Grid();
tiles = new Tile[grid.nCols * grid.nRows];
setTiles();
}
void setTiles() {
println(grid.colW, grid.rowH);
for (int n = 0; n < tiles.length - 1; n = n) {
for (int r = 0; r < grid.centers.length; r++) {
for (int c = 0; c < grid.centers.length; c++) {
tiles[n] = new Tile(grid.centers[c][r].x,
grid.centers[c][r].y,
str(n + 1));
n++;
}
}
}
}
void display() {
grid.display();
for (int n = 0; n < tiles.length - 1; n++) {
tiles[n].drawTile();
}
}
}
class Grid {
// variables related to basic structure
int nCols, nRows, colW, rowH;
PVector cellSize;
PVector[][] lines;
PVector[][] centers;
// variables related to translation
PVector origin, xyDims, xyCenter;
Grid() {
nCols = 3;
nRows = 3;
colW = 100;
rowH = 100;
cellSize = new PVector(colW, rowH);
lines = new PVector[nCols + 1][nRows + 1];
centers = new PVector[nCols][nRows];
xyDims = new PVector(colW * nCols, rowH * nRows);
xyCenter = PVector.div(xyDims, 2);
origin = new PVector(width/2 - xyCenter.x, height/2 - xyCenter.y);
makeGrid();
applyTranslation(origin);
}
void makeGrid() {
for (int c = 0; c < nCols + 1; c++) {
for (int r = 0; r < nRows + 1; r++) {
lines[c][r] = new PVector(c * cellSize.x, r * cellSize.y);
}
}
for (int c = 0; c < nCols; c++) {
for (int r = 0; r < nRows; r++) {
centers[c][r] = new PVector(c * cellSize.x + cellSize.x / 2,
r * cellSize.y + cellSize.y / 2);
}
}
}
void applyTranslation(PVector newOrigin) {
xyCenter.add(newOrigin);
for (int c = 0; c < lines.length; c++) {
for (int r = 0; r < lines.length; r++) {
lines[c][r].add(newOrigin);
}
}
for (int c = 0; c < centers.length; c++) {
for (int r = 0; r < centers.length; r++) {
centers[c][r].add(newOrigin);
}
}
}
//void setActive(PVector activeCell) {
// for (int c = 0; c < centers.length; c++) {
// for (int r = 0; r < centers.length; r++) {
// if (board.grid.centers[c][r].x == activeCell.x &&
// centers[c][r].y == activeCell.y) {
// centers[c][r].highlightOn = true;
// } else {
// centers[c][r].highlightOn = false;
// }
// }
// }
//}
void display() {
for (int c = 0; c < nCols; c++) {
for (int r = 0; r < nRows; r++) {
noStroke();
fill(0, 0, 0, 127);
rectMode(CENTER);
rect(centers[c][r].x, centers[c][r].y, cellSize.x, cellSize.y);
}
}
for (int c = 0; c < nCols + 1; c++) {
for (int r = 0; r < nRows + 1; r++) {
stroke(0, 0, 255, 127);
line(lines[c][r].x, 0, lines[c][r].x, height);
line(0, lines[c][r].y, width, lines[c][r].y);
}
}
}
}
class Tile {
String id;
PVector loc, activeCell, cSize;
boolean locked, highlightOn;
Tile() {
loc = new PVector();
activeCell = new PVector();
cSize = new PVector(board.grid.colW, board.grid.rowH);
locked = false;
highlightOn = false;
}
Tile(float x, float y, String id) {
loc = new PVector();
loc.x = x;
loc.y = y;
activeCell = new PVector();
cSize = new PVector(board.grid.colW, board.grid.rowH);
locked = false;
highlightOn = false;
this.id = id;
}
void snapToCenter() {
loc = activeCell;
}
void drawTile() {
checkOverTile();
loc.x = constrain(loc.x, board.grid.xyCenter.x - board.grid.xyDims.x/2-1 + cSize.x/2,
board.grid.xyCenter.x + board.grid.xyDims.x/2 - cSize.x/2);
loc.y = constrain(loc.y, board.grid.xyCenter.y - board.grid.xyDims.y/2-1 + cSize.y/2,
board.grid.xyCenter.y + board.grid.xyDims.y/2 - cSize.y/2);
stroke(255);
if (locked) {
fill(255, 92, 92, 127);
} else {
fill(255, 255, 255, 127);
}
rectMode(CENTER);
rect(loc.x, loc.y, cSize.x, cSize.y);
textAlign(CENTER, CENTER);
textSize(36);
text(id, loc.x, loc.y);
}
void checkOverTile() {
checkOverColCenters();
checkOverRowCenters();
//board.grid.setActive(activeCell);
}
void checkOverColCenters() {
for (int i = 0; i < board.grid.centers.length; i++) {
if (loc.x >= board.grid.centers[i][0].x - board.grid.colW/2 &&
loc.x <= board.grid.centers[i][0].x + board.grid.colW/2) {
activeCell.x = board.grid.centers[i][0].x;
}
}
}
void checkOverRowCenters() {
for (int i = 0; i < board.grid.centers.length; i++) {
if (loc.y >= board.grid.centers[0][i].y - board.grid.rowH/2 &&
loc.y <= board.grid.centers[0][i].y + board.grid.rowH/2) {
activeCell.y = board.grid.centers[0][i].y;
}
}
}
}