Class p5 is the original constructor already.
It’s not been hacked like the reference stored in p5.prototype.Sprite.
Here’s a very simple “index.html” code proving so:
index.html:
<script src=https://cdn.JsDelivr.net/npm/p5></script>
<script src=https://MolleIndustria.GitHub.io/p5.play/lib/p5.play.js></script>
<script>
console.log('p5 constructor', p5 === p5.prototype.constructor);
const Sprite = p5.prototype.Sprite;
console.log('Sprite constructor', Sprite === Sprite.prototype.constructor);
</script>
Here’s my attempt on subclassing p5, based on my previous “Class p5 Extended” sketch:
index.html:
<script defer src=https://cdn.JsDelivr.net/npm/p5></script>
<script defer src=sketch.js></script>
sketch.js:
/**
* Class p5 Extended II (v1.1.1)
* GoToLoop (2019-Jul-31)
*
* https://Discourse.Processing.org/t/
* wrapping-preload-setup-and-draw-in-an-es6-class/13071/5
*
* https://Discourse.Processing.org/t/how-i-extends-class-in-p5-js/894/5
*
* https://CodePen.io/GoSubRoutine/pen/voJozR/left?editors=0011
*/
'use strict';
class Level extends p5 {
static get FILENAME() {
return 'https://upload.Wikimedia.org/wikipedia/commons/thumb/2/2e/' +
'Processing_3_logo.png/480px-Processing_3_logo.png';
}
static redirectP5Callbacks(p) {
p.preload = p.loadLevel.bind(p); // preload() callback has to be bind()
p.setup = p.initLevel; // but callback setup() doesn't need bind()
p.draw = p.runLevel.bind(p); // draw() has to be bind() like preload()
p.mousePressed = p.mouseDragged = p.restartLevel; // optional for mouse
p.touchStarted = p.touchMoved = p.restartLevel; // optional for touch
p.keyPressed = p.keyReleased = p.restartLevel.bind(p); // required for key
}
constructor(levelNum) {
super(Level.redirectP5Callbacks);
this.levelNum = levelNum;
}
loadLevel() {
this.img = this.loadImage(Level.FILENAME);
}
initLevel() {
this.createCanvas(this.img.width, this.img.height);
this.noLoop();
this.rectMode(this.CORNER).ellipseMode(this.CENTER);
this.colorMode(this.RGB).blendMode(this.BLEND);
this.fill('yellow').stroke(0).strokeWeight(1.5).strokeCap(this.ROUND);
}
runLevel() {
this.background('#' + this.hex(~~this.random(0x1000), 3));
this.set(0, 0, this.img);
}
restartLevel() {
this.redraw();
return false;
}
// When bind() isn't needed, we can directly override the callback method:
windowResized() {
this.print('LevelNum: ' + this.levelNum);
return false;
}
}
// const levels = [ new Level(0), new Level(1) ];
const levels = Array.from({ length: 2 }, (v, i) => new Level(i));
BtW, I’ve hacked the callbacks w/ Function::bind():