Error when embedding one class inside another

Hi all,

I’m trying to translate code from Processing to p5. The code embeds one class (Wheel) inside another (Car). I think that I’m close, but I’m getting an error message on line 70: backWheel is not defined.

Is my issue line 51 and 52?:

let backWheel;
let frontWheel;

Should I be initializing these variables somewhere else, and if so, where?

I’m using OpenProcessing.org as an editor if that’s helpful.

Here’s the full code:

let dealership = new Array(15);

function setup() {
	createCanvas(windowWidth, windowHeight);
	colorMode(HSB);
	angleMode(DEGREES);

	dealership[0] = new Car(50, 80 + 0 * 60, 0 * 10, random(1, 2));
}

function draw() {
	background(50);
	dealership[0].displayCar();
	dealership[0].moveCar();
}

class Wheel {
	// --------- Wheel: Attributes ---------//
	constructor(tempX1, tempY1, tempAngle1, tempColor1) {
		this.x1 = tempX1;
		this.y1 = tempY1;
		this.angle1 = tempAngle1;
		this.color1 = tempColor1;
	}

	//--------- Wheel: Display ---------//
	displayWheel() {
		fill(this.color1, 255, 255);
		push();
		translate(this.x1 - 25, this.y1);
		rotate(this.angle1);
		ellipse(0, 0, 15, 20);
		pop();
	}

	//-------- Wheel: Turn ---------//
	turnWheel() {
		this.angle1 = this.angle1 + 1; // The 1 rotates the ellipse by 1 degree
	}
}


class Car {
	// --------- CAR: Attributes ---------//
	constructor(tempX, tempY, tempPaint, tempSpeed) {
		this.x = tempX;
		this.y = tempY;
		this.paint = tempPaint;
		this.speed = tempSpeed;

		let backWheel;  //-------------------------------------------------------------------- WHEEL
		let frontWheel;  //--------------------------------------------------------------------	WHEEL

		backWheel = new Wheel(this.x - 25, this.y, 0, 52); //--------------------------------------------------------------------	WHEEL
		frontWheel = new Wheel(this.x + 25, this.y, 0, 91); //--------------------------------------------------------------------	WHEEL
	}

	//--------- CAR: Display ---------//
	displayCar() {
		rectMode(CENTER);
		fill(this.paint, 255, 255);
		rect(this.x - 10, this.y - 30, 50, 20);
		rect(this.x, this.y - 10, 75, 20);
		fill(212, 242, 252);
		rect(this.x + 5, this.y - 30, 15, 15);
		// fill(0);
		// ellipse(this.x - 25, this.y, 20, 20);
		// ellipse(this.x + 25, this.y, 20, 20);

		backWheel.displayWheel(); //-------------------------------------------------------------------- WHEEL
		frontWheel.displayWheel(); //--------------------------------------------------------------------	WHEEL
	}

	//-------- CAR: Move ---------//
	moveCar() {
		this.x += this.speed;
		backWheel.turnWheel(); //-------------------------------------------------------------------- WHEEL
		frontWheel.turnWheel(); //-------------------------------------------------------------------- WHEEL
	}
}
1 Like
this.backWheel = new Wheel(this.x - 25, this.y, 0, 52);
this.frontWheel = new Wheel(this.x + 25, this.y, 0, 91);
1 Like

Thanks! I’m still getting the same error though. Here’s the updated code:

let dealership = new Array(15);

function setup() {
	createCanvas(windowWidth, windowHeight);
	colorMode(HSB);
	angleMode(DEGREES);

	dealership[0] = new Car(50, 80 + 0 * 60, 0 * 10, random(1, 2));
}

function draw() {
	background(50);
	dealership[0].displayCar();
	dealership[0].moveCar();
}

class Wheel {
	// --------- Wheel: Attributes ---------//
	constructor(tempX1, tempY1, tempAngle1, tempColor1) {
		this.x1 = tempX1;
		this.y1 = tempY1;
		this.angle1 = tempAngle1;
		this.color1 = tempColor1;
	}

	//--------- Wheel: Display ---------//
	displayWheel() {
		fill(this.color1, 255, 255);
		push();
		translate(this.x1 - 25, this.y1);
		rotate(this.angle1);
		ellipse(0, 0, 15, 20);
		pop();
	}

	//-------- Wheel: Turn ---------//
	turnWheel() {
		this.angle1 = this.angle1 + 1; // The 1 rotates the ellipse by 1 degree
	}
}


class Car {
	// --------- CAR: Attributes ---------//
	constructor(tempX, tempY, tempPaint, tempSpeed) {
		this.x = tempX;
		this.y = tempY;
		this.paint = tempPaint;
		this.speed = tempSpeed;

		let backWheel;  //-------------------------------------------------------------------- WHEEL
		let frontWheel;  //--------------------------------------------------------------------	WHEEL

		this.backWheel = new Wheel(this.x - 25, this.y, 0, 52); //--------------------------------------------------------------------	WHEEL
		this.frontWheel = new Wheel(this.x + 25, this.y, 0, 91); //--------------------------------------------------------------------	WHEEL
	}

	//--------- CAR: Display ---------//
	displayCar() {
		rectMode(CENTER);
		fill(this.paint, 255, 255);
		rect(this.x - 10, this.y - 30, 50, 20);
		rect(this.x, this.y - 10, 75, 20);
		fill(212, 242, 252);
		rect(this.x + 5, this.y - 30, 15, 15);
		// fill(0);
		// ellipse(this.x - 25, this.y, 20, 20);
		// ellipse(this.x + 25, this.y, 20, 20);

		backWheel.displayWheel(); //-------------------------------------------------------------------- WHEEL
		frontWheel.displayWheel(); //--------------------------------------------------------------------	WHEEL
	}

	//-------- CAR: Move ---------//
	moveCar() {
		this.x += this.speed;
		backWheel.turnWheel(); //-------------------------------------------------------------------- WHEEL
		frontWheel.turnWheel(); //-------------------------------------------------------------------- WHEEL
	}
}
1 Like

why not play online editor, so easy for all to take a look and contribute…

https://editor.p5js.org/kll/sketches/DD0uhc6IH


sorry, need

this.dada

everywhere

1 Like

Excellent, thanks for your help; that worked! Here’s the working code for later viewers:

let dealership = new Array(15);

function setup() {
	createCanvas(windowWidth, windowHeight);
	colorMode(HSB);
	angleMode(DEGREES);

	dealership[0] = new Car(100, 80, 15, random(1, 2));
}

function draw() {
	background(50);
	dealership[0].displayCar();
	dealership[0].moveCar();
}

class Wheel {
	// --------- Wheel: Attributes ---------//
	constructor(tempX1, tempY1, tempAngle1, tempColor1) {
		this.x1 = tempX1;
		this.y1 = tempY1;
		this.angle1 = tempAngle1;
		this.color1 = tempColor1;
	}

	//--------- Wheel: Display ---------//
	displayWheel(tempCarX, tempCarY) {
		this.carX = tempCarX;
		this.carY = tempCarY;
		
		fill(this.color1);
		push();
		translate(this.carX, this.carY); // We need to translate to where the Car's (x,y) coordinates are
		rotate(this.angle1);
		ellipse(0, 0, 17, 20);
		pop();
	}

	//-------- Wheel: Turn ---------//
	turnWheel(tempWheelSpeed) { // When call this method (line 77) we need to write a speed in the brackets*
		this.wheelSpeed = tempWheelSpeed;	
		this.angle1 = this.angle1 + this.wheelSpeed; // The wheelSpeed adds x degrees to the angle
	}
}

class Car {
	// --------- CAR: Attributes ---------//
	constructor(tempX, tempY, tempPaint, tempSpeed) {
		this.x = tempX;
		this.y = tempY;
		this.paint = tempPaint;
		this.speed = tempSpeed;
		
		let backWheel; // Wheel class ----------------------------------- Wheel class // declare new wheel objects in the car constructor
		let frontWheel; // Wheel class ---------------------------------- Wheel class //
		this.backWheel = new Wheel(this.x - 25, this.y, 0, 25); // ------ Wheel class // assign the wheel objects in the car constructor
		this.frontWheel = new Wheel(this.x + 25, this.y, 0, 25); // ----- Wheel class //
	}

	//--------- CAR: Display ---------//
	displayCar() {
		rectMode(CENTER);
		fill(this.paint, 255, 255);
		rect(this.x - 10, this.y - 30, 50, 20);
		rect(this.x, this.y - 10, 75, 20);
		fill(212, 242, 252);
		rect(this.x + 5, this.y - 30, 15, 15);
		this.backWheel.displayWheel(this.x - 25, this.y); // ------------ Wheel class // draw the backWheel
		this.frontWheel.displayWheel(this.x + 25, this.y); // ----------- Wheel class //
	}

	//-------- CAR: Move ---------//
	moveCar() {
		this.x += this.speed; // update the position of the car
		this.backWheel.turnWheel(this.speed * 2); // -------------------- Wheel class // update the position of the backWheel
		this.frontWheel.turnWheel(this.speed * 2); // ------------------- Wheel class //
	}
}

// * The speed we enter, in this case, is the speed of the car times 2.
3 Likes

For best help possible, it’s always nice to post both the original running code together w/ the attempted converted 1. :bulb:

Here comes some notes about your converted code. :nerd_face:

The Array constructor creates a slightly weaker performant sparse array!

As a workaround we can invoke its method fill() in order to possibly make it “solid”:
const dealership = Array(15).fill();

B/c your Array got initial length = 15, I suppose you’re gonna add 14 more Car instances to it, right?

Once it’s done, you’re gonna need a loop to iterate over each Car object:

function draw() {
  background(50);
  for (const car of dealership)  car.displayCar(), car.moveCar();
}

Shortened version for method Wheel::turnWheel():

turnWheel(wheelSpeed) {
  this.angle1 += this.wheelSpeed = wheelSpeed;
}

P.S.: It doesn’t seem like property wheelSpeed is used anywhere else, neither its current value needs to be remembered. :thinking:

So we can safely ignore that property in class Wheel and get a much shorter method: :stuck_out_tongue:

turnWheel(wheelSpeed) {
  this.angle1 += wheelSpeed;
}

P.S.: We’ve got again the same situation of unnecessary properties like the previous wheelSpeed. :roll_eyes:

This time it is carX & carY. Neither values need to be remembered anywhere else! :zipper_mouth_face:

All the method needs are already provided via its parameters tempCarX & tempCarY. :face_with_monocle:

So we can shorten method Wheel::displayWheel() a lot more: :grinning:

displayWheel(carX, carY) {
  push();
  translate(carX, carY).rotate(this.angle1);
  fill(this.color1).ellipse(0, 0, 17, 20);
  pop();
}
  • Both backWheel & frontWheel are properties of class Car.
  • Therefore they’re not local variables.
  • So there’s no need to declare them as such.
  • You can safely delete those 2 declaring statements.
3 Likes