Converting a boundaries function with applyForce from .pde to .p5

Hi, guys

I’m converting an old project that I had done in processing, and I’m having a lot of difficulties converting this function.

The function makes a game object float within a pre-limited area, changing the movement force direction when the object reaches the limit. Basically, making the object bounce inside that area in a smooth way.
I’m new with .p5, so I’m still unsure if I’m doing this conversion correctly. The code runs without any errors, but the object simply escapes the boundary without any difficult.

Here is my .pde code:

class King {
    
    PVector position;
    PVector velocity;
    PVector acceleration;
    float r;
    
    float maxspeed;
    float maxforce;
    
    King(float x, float y) {
        acceleration = new PVector(0, 0);
        velocity = new PVector(3, 0.5);
        velocity.mult(5);
        position = new PVector(x, y);
        r = 6;
        maxspeed = 1.5;
        maxforce = 0.15;
    }
    
    void run() {
        update();
        kc();
    }
    
    //Methodto update position
    void update() {
        // Update velocity
        velocity.add(acceleration);
        // Limitspeed
        velocity.limit(maxspeed);
        position.add(velocity);
        // Resetaccelertion to 0 each cycle
        acceleration.mult(0);
    }
    
    void boundaries() {
        
        PVector desired = null;
        
        if (position.x < d) {
            desired = new PVector(maxspeed, velocity.y);
            print(desired);
        } else if (position.x > width - d) {
            desired = new PVector( -maxspeed, velocity.y);
            print(desired);
        } 
        
        if (position.y < 100) {
            desired = new PVector(velocity.x, maxspeed);
            print(desired);
        } else if (position.y > 200) {
            desired = new PVector(velocity.x, -maxspeed);
            print(desired);
        } 
        
        if (desired != null) {
            desired.normalize();
            desired.mult(maxspeed);
            PVector steer = PVector.sub(desired, velocity);
            steer.limit(maxforce);
            applyForce(steer);
        }
    }  
    
    void applyForce(PVector force) {
        // We could add mass here if we want A = F / M
        acceleration.add(force);
    }

And here is my .p5 version:

class King {

    constructor(x, y) {

        this.acceleration = createVector(0, 0);

        this.velocity = createVector(3, 0.5);

        this.position = createVector(x, y);

        this.velocity.mult(5);

        this.maxspeed = 1.5;

        this.maxforce = 0.15;

    }

    runKing() {

        this.update();

        this.kc();

        this.boundaries();

    }

    //Method to update position

    update() {

        // Update velocity

        this.velocity.add(this.acceleration);

        // Limit speed

        this.velocity.limit(this.maxspeed);

        this.position.add(this.velocity);

        // Reset accelertion to 0 each cycle

        this.acceleration.mult(0);

    }

    boundaries() {

        this.desired = createVector(null);

        print(this.maxspeed);

        print(width - d);

        print(this.desired.x);

        print(this.desired.y);

        if (this.position.x < d) {

            this.desired.x = this.maxspeed;

            this.desired.y = this.velocity.y;

            print("menor que d");

        } else if (this.position.x > width - d) {

            this.desired.x = -this.maxspeed;

            this.desired.y = -this.velocity.y;

            print("maior que d");

        }

        if (this.position.y < 100) {

            this.desired.x = this.velocity.x;

            this.desired.y = this.maxspeed;

            ("menor que 100");

        } else if (this.position.y > 200) {

            this.desired.x = -this.velocity.x;

            this.desired.y = -this.maxspeed;

        }

        if (this.desired != null) {

            this.desired.normalize();

            this.desired.mult(this.maxspeed);

            this.steer = createVector();

            this.steer.sub(this.desired, this.velocity);

            this.steer.limit(this.maxforce);

            this.applyForce(this.steer);

        }

    }

    applyForce(force) {

        this.acceleration.add(force);

    }

I’m just posting the code of the function in question because the project is considerably large, I can put a link to my .p5 and .pde projects if need it.

(the print functions on the .p5 code is just for debug.)

In the original Java Mode sketch, desired is a local variable within method King::boundaries():

However, you made it as a property in the p5js version:

Instead you should just use keyword const for it:

    boundaries() {

        const desired = createVector(null);

But that’s some silly detail which doesn’t make any difference to fix the bug.

The actual difference between them is that you’re initializing the latter w/ createVector(), while in the original you just use null.

At the end you check for null in both versions:

Which will always fail in the p5js version b/c desired is initialized w/ a p5.Vector object and never becomes null at any point!

As a workaround you could just initialize desired w/ a “zeroed” p5.Vector:

    boundaries() {

        const desired = createVector(); // x, y & z = 0

And then check if that’s still “zeroed” at the last if () {} block using method p5.Vector::equals():
if (!desired.equals()) { // check if it changed from x, y & z = 0
p5js.org/reference/#/p5.Vector/equals

1 Like

Hi @GoToLoop, thanks for your reply!

I applied your suggestions to the code, but it didn’t change anything, unfortunately. I still have the same results.

From what I can understand, when the vector hits the limits, it only has the velocity adjusted once, and it doesn’t keep updating until the direction rotation is complete, so it keeps going away.

I imagine that the way that p5js is dealing with the desired variable is different from how the processing deals with it. But I am not sure what is different or how to fix it…

Here is the online version of my project if it helps:
p5.js Web Editor | Katamari 2D (p5js.org)

Also, here is my .pde project version, so you can see how it’s supposed to work

https://drive.google.com/drive/folders/11TjKdMANHokFpvJanKM2gcZpv18q5AEF?usp=sharing

Given you’ve linked to both full versions, I’ve decided to refactor your Java Mode’s King class and then re-convert it to p5js afterwards:

King.pde:

class King {
  static final float MAX_SPD = 1.5, MAX_FORCE = .15, MILLS = 1e-3 * TAU;
  static final short SIZE = 200, ALPHA = 70, OFFSET = -105;

  final PVector pos, vel, acc, tmp;
  final PImage king;

  King(final PVector pos) {
    this(pos.x, pos.y);
  }

  King(final float x, final float y) {
    pos = new PVector(x, y);
    vel = new PVector(15, 2.5);
    acc = new PVector();
    tmp = new PVector();
    king = createKing();
  }

  King run() {
    return boundaries().update().drawHalos().drawKing();
  }

  King update() {
    pos.add(vel.add(acc).limit(MAX_SPD));
    acc.mult(0);
    return this;
  }

  King boundaries() {
    tmp.set(vel);

    if (pos.x < SIZE)               tmp.x = MAX_SPD;
    else if (pos.x > width - SIZE)  tmp.x = -MAX_SPD;

    if (pos.y < SIZE >> 1)          tmp.y = MAX_SPD;
    else if (pos.y > SIZE)          tmp.y = -MAX_SPD;

    if (!tmp.equals(vel))  applyForce(
      tmp.setMag(MAX_SPD).sub(vel).limit(MAX_FORCE));

    return this;
  }

  PVector applyForce(final PVector force) {
    return acc.add(force);
  }

  King drawHalos() {
    final float mills = MILLS * millis();

    pushMatrix();
    translate(pos.x, pos.y);
    noStroke();

    /* halo 1 */
    pushMatrix();
    rotate(mills / 20);
    translate(OFFSET, OFFSET);
    fill(#3F284B);

    beginShape();
    vertex(122, 12);
    vertex(124, 9);
    vertex(127, 6);
    vertex(150, 1);
    vertex(163, 21);
    vertex(163, 25);
    vertex(163, 29);
    vertex(169, 45);
    vertex(185, 51);
    vertex(188, 50);
    vertex(192, 50);
    vertex(212, 63);
    vertex(207, 86);
    vertex(204, 89);
    vertex(201, 91);
    vertex(195, 107);
    vertex(201, 122);
    vertex(204, 125);
    vertex(207, 127);
    vertex(212, 150);
    vertex(192, 163);
    vertex(188, 163);
    vertex(185, 163);
    vertex(169, 169);
    vertex(163, 185);
    vertex(163, 188);
    vertex(163, 192);
    vertex(150, 212);
    vertex(127, 207);
    vertex(124, 204);
    vertex(122, 202);
    vertex(107, 195);
    vertex(91, 202);
    vertex(89, 204);
    vertex(86, 207);
    vertex(63, 212);
    vertex(50, 192);
    vertex(50, 188);
    vertex(50, 185);
    vertex(44, 169);
    vertex(29, 163);
    vertex(25, 163);
    vertex(21, 163);
    vertex(1, 150);
    vertex(6, 127);
    vertex(9, 125);
    vertex(12, 122);
    vertex(19, 107);
    vertex(12, 91);
    vertex(9, 89);
    vertex(6, 86);
    vertex(1, 63);
    vertex(21, 50);
    vertex(25, 50);
    vertex(29, 51);
    vertex(44, 45);
    vertex(50, 29);
    vertex(50, 25);
    vertex(50, 21);
    vertex(63, 1);
    vertex(86, 6);
    vertex(89, 9);
    vertex(91, 12);
    vertex(107, 19);
    vertex(122, 12);
    vertex(122, 12);
    endShape(CLOSE);
    popMatrix();

    /* halo 2 */
    pushMatrix();
    rotate(mills / -20);
    translate(OFFSET, OFFSET);
    fill(#7B2751, ALPHA); // #7B2751

    beginShape();
    vertex(120, 26);
    vertex(124, 21);
    bezierVertex(135, 9, 156, 17, 155, 34);
    vertex(155, 40);
    bezierVertex(154, 51, 163, 59, 173, 59);
    vertex(180, 58);
    bezierVertex(196, 58, 205, 78, 192, 89);
    vertex(188, 94);
    bezierVertex(180, 101, 180, 113, 188, 120);
    vertex(192, 124);
    bezierVertex(205, 135, 196, 156, 180, 155);
    vertex(173, 155);
    bezierVertex(163, 154, 154, 163, 155, 174);
    vertex(155, 180);
    bezierVertex(156, 197, 135, 205, 124, 193);
    vertex(120, 188);
    bezierVertex(113, 180, 100, 180, 93, 188);
    vertex(89, 193);
    bezierVertex(78, 205, 57, 196, 58, 180);
    vertex(59, 173);
    bezierVertex(59, 163, 50, 154, 40, 155);
    vertex(34, 155);
    bezierVertex(17, 156, 8, 135, 21, 124);
    vertex(25, 120);
    bezierVertex(33, 113, 33, 101, 25, 94);
    vertex(21, 89);
    bezierVertex(8, 78, 17, 58, 34, 58);
    vertex(40, 59);
    bezierVertex(50, 59, 59, 51, 59, 40);
    vertex(58, 34);
    bezierVertex(57, 17, 78, 9, 89, 21);
    vertex(93, 26);
    bezierVertex(100, 33, 113, 33, 120, 26);
    endShape();
    popMatrix();

    /* halo 3 */
    pushMatrix();
    rotate(mills / 10);
    translate(OFFSET, OFFSET);
    fill(#541642, ALPHA); // #541642

    beginShape();
    vertex(117, 49);
    vertex(122, 40);
    bezierVertex(129, 28, 147, 35, 143, 48);
    vertex(140, 59);
    bezierVertex(138, 67, 146, 75, 154, 73);
    bezierVertex(154, 73, 154, 73, 155, 73);
    vertex(165, 70);
    bezierVertex(178, 67, 186, 85, 174, 91);
    vertex(164, 97);
    bezierVertex(157, 101, 156, 112, 164, 117);
    bezierVertex(164, 117, 164, 117, 164, 117);
    vertex(174, 122);
    bezierVertex(186, 129, 178, 147, 165, 143);
    vertex(155, 140);
    bezierVertex(146, 138, 138, 146, 140, 155);
    bezierVertex(140, 155, 140, 155, 140, 155);
    vertex(143, 165);
    bezierVertex(147, 178, 129, 186, 122, 174);
    vertex(117, 165);
    bezierVertex(112, 157, 101, 157, 97, 164);
    bezierVertex(97, 164, 97, 164, 97, 165);
    vertex(91, 174);
    bezierVertex(84, 186, 66, 178, 70, 165);
    vertex(73, 155);
    bezierVertex(75, 146, 67, 138, 59, 140);
    bezierVertex(59, 140, 59, 141, 59, 141);
    vertex(48, 143);
    bezierVertex(35, 147, 28, 129, 39, 122);
    vertex(49, 117);
    bezierVertex(57, 112, 57, 101, 49, 97);
    bezierVertex(49, 97, 49, 97, 49, 97);
    vertex(39, 91);
    bezierVertex(28, 85, 35, 67, 48, 70);
    vertex(59, 73);
    bezierVertex(67, 75, 75, 68, 73, 59);
    bezierVertex(73, 59, 73, 59, 73, 59);
    vertex(70, 48);
    bezierVertex(66, 35, 84, 28, 91, 40);
    vertex(97, 49);
    bezierVertex(101, 57, 112, 57, 117, 49);
    bezierVertex(117, 49, 117, 49, 117, 49);
    endShape();
    popMatrix();

    /* halo 4 */
    pushMatrix();
    rotate(mills / -10);
    translate(OFFSET, OFFSET);
    fill(#7B087E, ALPHA); // #7B087E

    beginShape();
    vertex(117, 49);
    vertex(122, 40);
    bezierVertex(129, 28, 147, 35, 143, 48);
    vertex(140, 59);
    bezierVertex(138, 67, 146, 75, 154, 73);
    bezierVertex(154, 73, 154, 73, 155, 73);
    vertex(165, 70);
    bezierVertex(178, 67, 186, 85, 174, 91);
    vertex(164, 97);
    bezierVertex(157, 101, 156, 112, 164, 117);
    bezierVertex(164, 117, 164, 117, 164, 117);
    vertex(174, 122);
    bezierVertex(186, 129, 178, 147, 165, 143);
    vertex(155, 140);
    bezierVertex(146, 138, 138, 146, 140, 155);
    bezierVertex(140, 155, 140, 155, 140, 155);
    vertex(143, 165);
    bezierVertex(147, 178, 129, 186, 122, 174);
    vertex(117, 165);
    bezierVertex(112, 157, 101, 157, 97, 164);
    bezierVertex(97, 164, 97, 164, 97, 165);
    vertex(91, 174);
    bezierVertex(84, 186, 66, 178, 70, 165);
    vertex(73, 155);
    bezierVertex(75, 146, 67, 138, 59, 140);
    bezierVertex(59, 140, 59, 141, 59, 141);
    vertex(48, 143);
    bezierVertex(35, 147, 28, 129, 39, 122);
    vertex(49, 117);
    bezierVertex(57, 112, 57, 101, 49, 97);
    bezierVertex(49, 97, 49, 97, 49, 97);
    vertex(39, 91);
    bezierVertex(28, 85, 35, 67, 48, 70);
    vertex(59, 73);
    bezierVertex(67, 75, 75, 68, 73, 59);
    bezierVertex(73, 59, 73, 59, 73, 59);
    vertex(70, 48);
    bezierVertex(66, 35, 84, 28, 91, 40);
    vertex(97, 49);
    bezierVertex(101, 57, 112, 57, 117, 49);
    bezierVertex(117, 49, 117, 49, 117, 49);
    endShape();
    popMatrix();

    /* halo 5 */
    pushMatrix();
    rotate(mills / 5);
    translate(OFFSET, OFFSET);
    fill(#BA007C, ALPHA); // #BA007C

    beginShape();
    vertex(131, 70);
    vertex(137, 66);
    bezierVertex(145, 60, 156, 70, 149, 78);
    vertex(144, 84);
    bezierVertex(140, 89, 143, 97, 149, 98);
    bezierVertex(149, 98, 149, 98, 149, 98);
    vertex(157, 99);
    bezierVertex(167, 101, 167, 115, 157, 116);
    vertex(149, 117);
    bezierVertex(142, 118, 139, 126, 143, 131);
    vertex(148, 138);
    bezierVertex(154, 146, 143, 156, 135, 149);
    vertex(129, 144);
    bezierVertex(124, 140, 116, 143, 115, 149);
    bezierVertex(115, 150, 115, 150, 115, 150);
    vertex(114, 158);
    bezierVertex(113, 168, 98, 167, 97, 157);
    vertex(96, 149);
    bezierVertex(95, 143, 88, 139, 82, 143);
    bezierVertex(82, 143, 82, 143, 82, 143);
    vertex(76, 148);
    bezierVertex(68, 154, 58, 144, 64, 136);
    vertex(69, 129);
    bezierVertex(73, 124, 70, 116, 64, 115);
    bezierVertex(64, 115, 64, 115, 64, 115);
    vertex(56, 114);
    bezierVertex(46, 113, 46, 98, 56, 97);
    vertex(64, 96);
    bezierVertex(71, 96, 74, 88, 70, 83);
    bezierVertex(70, 83, 70, 83, 70, 82);
    vertex(65, 76);
    bezierVertex(59, 68, 70, 58, 78, 64);
    vertex(84, 69);
    bezierVertex(89, 74, 97, 71, 98, 64);
    bezierVertex(98, 64, 98, 64, 98, 64);
    vertex(99, 56);
    bezierVertex(101, 46, 115, 46, 116, 56);
    vertex(117, 64);
    bezierVertex(118, 71, 125, 74, 131, 70);
    bezierVertex(131, 70, 131, 70, 131, 70);
    endShape();
    popMatrix();

    /* halo 6 */
    pushMatrix();
    rotate(mills / -5);
    translate(OFFSET, OFFSET);
    fill(#5F1C73, ALPHA); // #5F1C73

    beginShape();
    vertex(139, 58);
    vertex(148, 52);
    bezierVertex(159, 43, 172, 58, 164, 68);
    vertex(157, 77);
    bezierVertex(151, 83, 155, 94, 164, 95);
    bezierVertex(164, 95, 164, 95, 164, 95);
    vertex(175, 97);
    bezierVertex(188, 99, 188, 118, 174, 120);
    vertex(163, 121);
    bezierVertex(155, 122, 150, 132, 155, 139);
    bezierVertex(155, 139, 155, 139, 155, 139);
    vertex(162, 148);
    bezierVertex(170, 159, 156, 172, 145, 164);
    vertex(137, 157);
    bezierVertex(130, 151, 120, 155, 118, 164);
    bezierVertex(118, 164, 118, 164, 118, 164);
    vertex(116, 175);
    bezierVertex(114, 188, 95, 188, 94, 174);
    vertex(92, 164);
    bezierVertex(92, 155, 81, 150, 74, 155);
    bezierVertex(74, 155, 74, 156, 74, 156);
    vertex(65, 162);
    bezierVertex(54, 170, 41, 156, 49, 145);
    vertex(56, 137);
    bezierVertex(62, 130, 58, 120, 49, 118);
    bezierVertex(49, 118, 49, 118, 49, 118);
    vertex(38, 117);
    bezierVertex(25, 115, 25, 95, 39, 94);
    vertex(50, 93);
    bezierVertex(59, 92, 63, 82, 58, 74);
    bezierVertex(58, 74, 58, 74, 58, 74);
    vertex(51, 66);
    bezierVertex(43, 55, 57, 41, 68, 50);
    vertex(76, 57);
    bezierVertex(83, 62, 94, 58, 95, 49);
    bezierVertex(95, 49, 95, 49, 95, 49);
    vertex(97, 39);
    bezierVertex(99, 25, 118, 26, 120, 39);
    vertex(121, 50);
    bezierVertex(122, 59, 132, 63, 139, 58);
    bezierVertex(139, 58, 139, 58, 139, 58);
    endShape();
    popMatrix();

    popMatrix();
    return this;
  }

  King drawKing() {
    final float alpha = tan(frameCount / 15.) + 150;

    pushMatrix();
    translate(pos.x + OFFSET, pos.y + OFFSET);
    noStroke();

    image(king, 0, 0);

    /* left eye blink */
    fill(#151715, alpha); // #151715
    beginShape();
    vertex(84, 71);
    bezierVertex(86, 70, 88, 70, 90, 70);
    bezierVertex(92, 70, 95, 71, 95, 72);
    bezierVertex(95, 73, 92, 74, 89, 73);
    bezierVertex(87, 73, 85, 72, 84, 71);
    endShape();

    /* right eye blink */
    beginShape();
    vertex(130, 71);
    bezierVertex(128, 70, 126, 70, 124, 70);
    bezierVertex(121, 70, 118, 71, 118, 72);
    bezierVertex(118, 73, 122, 74, 124, 73);
    bezierVertex(126, 73, 128, 72, 130, 71);
    endShape();

    popMatrix();
    return this;
  }

  PImage createKing() {
    final PGraphics pg = createGraphics(160, 170);

    pg.beginDraw();
    pg.noStroke();

    /* beard */
    pg.fill(#1D1920);
    pg.beginShape();
    pg.vertex(151, 100);
    pg.vertex(144, 76);
    pg.vertex(144, 76);
    pg.vertex(145, 69);
    pg.vertex(139, 52);
    pg.vertex(75, 52);
    pg.vertex(68, 69);
    pg.vertex(70, 76);
    pg.vertex(69, 76);
    pg.vertex(62, 100);
    pg.vertex(57, 147);
    pg.vertex(94, 170);
    pg.vertex(119, 170);
    pg.vertex(156, 147);
    pg.vertex(151, 100);
    pg.endShape(CLOSE);

    /* face */
    pg.fill(#96988B);
    pg.beginShape();
    pg.vertex(150, 112);
    pg.bezierVertex(150, 108, 150, 104, 149, 100);
    pg.vertex(149, 100);
    pg.vertex(142, 76);
    pg.vertex(143, 69);
    pg.vertex(137, 52);
    pg.vertex(76, 52);
    pg.vertex(70, 69);
    pg.vertex(72, 76);
    pg.vertex(65, 100);
    pg.bezierVertex(62, 108, 62, 116, 65, 124);
    pg.bezierVertex(65, 128, 67, 131, 70, 133);
    pg.bezierVertex(72, 134, 74, 135, 76, 135);
    pg.bezierVertex(78, 135, 80, 135, 82, 134);
    pg.bezierVertex(80, 137, 78, 142, 78, 146);
    pg.bezierVertex(78, 147, 78, 148, 78, 150);
    pg.bezierVertex(78, 152, 79, 153, 80, 155);
    pg.bezierVertex(80, 157, 81, 158, 82, 159);
    pg.bezierVertex(86, 164, 91, 167, 96, 167);
    pg.bezierVertex(98, 167, 100, 166, 102, 165);
    pg.bezierVertex(107, 161, 107, 152, 101, 145);
    pg.bezierVertex(101, 144, 100, 144, 100, 143);
    pg.vertex(113, 143);
    pg.bezierVertex(113, 144, 112, 144, 112, 145);
    pg.bezierVertex(107, 152, 106, 161, 111, 165);
    pg.bezierVertex(113, 166, 115, 167, 117, 167);
    pg.bezierVertex(122, 167, 127, 164, 131, 159);
    pg.bezierVertex(132, 158, 133, 157, 133, 155);
    pg.bezierVertex(134, 153, 135, 152, 135, 150);
    pg.bezierVertex(135, 148, 135, 147, 135, 146);
    pg.bezierVertex(135, 144, 134, 142, 134, 140);
    pg.bezierVertex(133, 138, 132, 136, 131, 134);
    pg.bezierVertex(133, 135, 135, 135, 137, 135);
    pg.bezierVertex(139, 135, 141, 134, 143, 133);
    pg.bezierVertex(146, 131, 148, 128, 148, 124);
    pg.bezierVertex(150, 120, 150, 116, 150, 112);
    pg.endShape();

    /* nose */
    pg.fill(#DDA17E);
    pg.beginShape();
    pg.vertex(120, 110);
    pg.vertex(93, 110);
    pg.vertex(107, 71);
    pg.vertex(120, 110);
    pg.endShape(CLOSE);

    pg.fill(#CD6947);
    pg.beginShape();
    pg.vertex(106, 97);
    pg.vertex(94, 108);
    pg.vertex(106, 73);
    pg.vertex(106, 97);
    pg.endShape(CLOSE);

    pg.beginShape();
    pg.vertex(107, 97);
    pg.vertex(119, 108);
    pg.vertex(107, 73);
    pg.vertex(107, 97);
    pg.endShape(CLOSE);

    pg.fill(#85305A);
    pg.beginShape();
    pg.vertex(107, 98);
    pg.vertex(93, 110);
    pg.vertex(120, 110);
    pg.vertex(107, 98);
    pg.endShape(CLOSE);

    /* left eye mask */
    pg.fill(#474741);
    pg.beginShape();
    pg.vertex(71, 67);
    pg.bezierVertex(76, 66, 82, 66, 87, 66);
    pg.bezierVertex(95, 66, 108, 67, 109, 71);
    pg.bezierVertex(109, 74, 101, 77, 94, 78);
    pg.bezierVertex(91, 79, 87, 79, 84, 78);
    pg.bezierVertex(78, 77, 73, 73, 71, 67);
    pg.endShape();

    /* right eye mask */
    pg.beginShape();
    pg.vertex(142, 67);
    pg.bezierVertex(137, 66, 131, 66, 126, 66);
    pg.bezierVertex(118, 66, 105, 67, 105, 71);
    pg.bezierVertex(104, 74, 112, 77, 119, 78);
    pg.bezierVertex(122, 79, 126, 79, 129, 78);
    pg.bezierVertex(135, 77, 140, 73, 142, 67);
    pg.endShape();

    /* philtrum */
    pg.fill(#514B48);
    pg.beginShape();
    pg.vertex(113, 120);
    pg.vertex(100, 120);
    pg.vertex(103, 110);
    pg.vertex(110, 110);
    pg.vertex(113, 120);
    pg.endShape(CLOSE);

    /* mustache */
    pg.fill(#1E1B1D);
    pg.beginShape();
    pg.vertex(104, 115);
    pg.vertex(94, 115);
    pg.vertex(85, 123);
    pg.vertex(77, 107);
    pg.vertex(85, 116);
    pg.vertex(92, 111);
    pg.vertex(104, 111);
    pg.vertex(104, 115);
    pg.endShape(CLOSE);

    pg.beginShape();
    pg.vertex(109, 115);
    pg.vertex(119, 115);
    pg.vertex(128, 123);
    pg.vertex(136, 107);
    pg.vertex(128, 116);
    pg.vertex(121, 111);
    pg.vertex(109, 111);
    pg.vertex(109, 115);
    pg.endShape(CLOSE);

    /* lips */
    pg.fill(#32342A);
    pg.beginShape();
    pg.vertex(114, 132);
    pg.vertex(100, 132);
    pg.vertex(92, 130);
    pg.vertex(100, 137);
    pg.vertex(114, 137);
    pg.vertex(122, 130);
    pg.vertex(114, 132);
    pg.endShape(CLOSE);

    pg.ellipse(107, 132, 10, 2);

    pg.beginShape();
    pg.vertex(124, 125);
    pg.vertex(112, 118);
    pg.vertex(107, 120);
    pg.vertex(107, 120);
    pg.vertex(101, 118);
    pg.vertex(89, 125);
    pg.vertex(87, 123);
    pg.vertex(89, 128);
    pg.vertex(101, 125);
    pg.vertex(107, 126);
    pg.vertex(107, 126);
    pg.vertex(107, 126);
    pg.vertex(107, 126);
    pg.vertex(107, 126);
    pg.vertex(112, 125);
    pg.vertex(124, 128);
    pg.vertex(127, 123);
    pg.vertex(124, 125);
    pg.endShape(CLOSE);

    /* cheeks */
    pg.fill(#A3A599);
    pg.circle(79, 95, 17);
    pg.circle(133, 95, 17);
    pg.circle(117, 152, 15);
    pg.circle(97, 152, 15);

    /* crown shadows */
    pg.fill(#49493A);
    pg.beginShape();
    pg.vertex(103, 61);
    pg.vertex(78, 52);
    pg.vertex(107, 52);
    pg.vertex(103, 61);
    pg.endShape(CLOSE);

    pg.beginShape();
    pg.vertex(110, 61);
    pg.vertex(135, 52);
    pg.vertex(107, 52);
    pg.vertex(110, 61);
    pg.endShape(CLOSE);

    /* crown base */
    pg.fill(#E5D277);
    pg.beginShape();
    pg.vertex(138, 50);
    pg.vertex(77, 50);
    pg.vertex(83, 11);
    pg.vertex(92, 30);
    pg.vertex(98, 10);
    pg.vertex(106, 32);
    pg.vertex(116, 9);
    pg.vertex(122, 31);
    pg.vertex(132, 11);
    pg.vertex(138, 50);
    pg.endShape(CLOSE);

    /* crown lower base */
    pg.fill(#CAB125);
    pg.rect(74, 49, 66, 4);
    pg.beginShape();
    pg.vertex(138, 49);
    pg.vertex(77, 49);
    pg.vertex(83, 14);
    pg.vertex(92, 31);
    pg.vertex(98, 12);
    pg.vertex(106, 32);
    pg.vertex(116, 12);
    pg.vertex(121, 32);
    pg.vertex(131, 14);
    pg.vertex(138, 49);
    pg.endShape(CLOSE);

    /* crown shines */
    pg.fill(#E0BA37);
    pg.beginShape();
    pg.vertex(111, 49);
    pg.vertex(103, 49);
    pg.vertex(103, 24);
    pg.vertex(106, 32);
    pg.vertex(111, 22);
    pg.vertex(111, 49);
    pg.endShape(CLOSE);

    pg.fill(#E8D27E);
    pg.beginShape();
    pg.vertex(130, 16);
    pg.vertex(124, 26);
    pg.vertex(124, 49);
    pg.vertex(130, 49);
    pg.vertex(130, 16);
    pg.endShape(CLOSE);

    pg.fill(#C29D38);
    pg.beginShape();
    pg.vertex(83, 15);
    pg.vertex(89, 26);
    pg.vertex(89, 49);
    pg.vertex(83, 49);
    pg.vertex(83, 15);
    pg.endShape(CLOSE);

    pg.fill(#F8E8AD);
    pg.quad(77, 7, 81, 3, 86, 7, 82, 12);
    pg.quad(92, 6, 97, 1, 102, 6, 97, 10);
    pg.quad(109, 6, 115, 1, 120, 6, 115, 10);
    pg.quad(128, 7, 132, 3, 137, 7, 132, 12);

    pg.fill(#EECE61);
    pg.quad(78, 7, 81, 4, 83, 7, 81, 12);
    pg.quad(93, 6, 97, 2, 101, 6, 97, 9);
    pg.quad(110, 6, 115, 2, 119, 6, 115, 9);
    pg.quad(130, 7, 132, 4, 136, 7, 131, 12);

    pg.endDraw();
    return pg.get();
  }
}
1 Like

King.js:

class King {
  static MAX_SPD = 1; // original 1.5
  static MAX_FORCE = 5; // original .15
  static MILLS = 2e-3 * Math.PI;

  static SIZE = 200;
  static ALPHA = 70;
  static OFFSET = -105;

  static get PALETTE() {
    const { ALPHA } = this, palette = [
      '#3F284B',              // halo 1
      [ 123, 39, 81, ALPHA ], // halo 2 (#7B2751)
      [ 84,  22, 66, ALPHA ], // halo 3 (#541642)
      [ 123, 8, 126, ALPHA ], // halo 4 (#7B087E)
      [ 186, 0, 124, ALPHA ], // halo 5 (#BA007C)
      [ 95, 28, 115, ALPHA ], // halo 6 (#5F1C73)
    ].map(c => color(c));

    delete this.PALETTE;
    return this.PALETTE = palette;
  }

  constructor(x, y) {
    this.pos = createVector().set(...arguments);
    this.vel = createVector(15, 5); // original 15, 2.5
    this.acc = createVector();
    this.tmp = createVector();
    this.king = this.createKing();
  }

  runKing() {
    return this.boundaries().update().drawHalos().drawKing();
  }

  update() {
    this.pos.add(this.vel.add(this.acc).limit(King.MAX_SPD));
    this.acc.mult(0);
    return this;
  }

  boundaries() {
    const
      { pos: { x, y }, vel, tmp }  = this,
      { SIZE, MAX_SPD, MAX_FORCE } = King;

    tmp.set(vel);

    if (x < SIZE)               tmp.x = MAX_SPD;
    else if (x > width - SIZE)  tmp.x = -MAX_SPD;

    if (y < SIZE >> 1)          tmp.y = MAX_SPD;
    else if (y > SIZE)          tmp.y = -MAX_SPD;

    tmp.equals(vel) || this.update().applyForce( // extra update() call
      tmp.setMag(MAX_SPD).sub(vel).limit(MAX_FORCE));

    return this;
  }

  applyForce(force) {
    return this.acc.add(force);
  }

  drawHalos() {
    const
      { pos: { x, y } } = this,
      { MILLS, OFFSET, PALETTE } = King,
      mills = MILLS * millis();

    push();
    translate(x, y).noStroke();;

    /* halo 1 */
    push();
    rotate(mills / 20).translate(OFFSET, OFFSET);

    fill(PALETTE[0]).beginShape(); // #3F284B
    vertex(122, 12).vertex(124, 9).vertex(127, 6);
    vertex(150, 1).vertex(163, 21).vertex(163, 25);
    vertex(163, 29).vertex(169, 45).vertex(185, 51);
    vertex(188, 50).vertex(192, 50).vertex(212, 63);
    vertex(207, 86).vertex(204, 89).vertex(201, 91);
    vertex(195, 107).vertex(201, 122).vertex(204, 125);
    vertex(207, 127).vertex(212, 150).vertex(192, 163);
    vertex(188, 163).vertex(185, 163).vertex(169, 169);
    vertex(163, 185).vertex(163, 188).vertex(163, 192);
    vertex(150, 212).vertex(127, 207).vertex(124, 204);
    vertex(122, 202).vertex(107, 195).vertex(91, 202);
    vertex(89, 204).vertex(86, 207).vertex(63, 212);
    vertex(50, 192).vertex(50, 188).vertex(50, 185);
    vertex(44, 169).vertex(29, 163).vertex(25, 163);
    vertex(21, 163).vertex(1, 150).vertex(6, 127);
    vertex(9, 125).vertex(12, 122).vertex(19, 107);
    vertex(12, 91).vertex(9, 89).vertex(6, 86);
    vertex(1, 63).vertex(21, 50).vertex(25, 50);
    vertex(29, 51).vertex(44, 45).vertex(50, 29);
    vertex(50, 25).vertex(50, 21).vertex(63, 1);
    vertex(86, 6).vertex(89, 9).vertex(91, 12);
    vertex(107, 19).vertex(122, 12).vertex(122, 12);
    endShape(CLOSE).pop();

    /* halo 2 */
    push();
    rotate(mills / -20).translate(OFFSET, OFFSET);

    fill(PALETTE[1]).beginShape(); // #7B2751
    vertex(120, 26).vertex(124, 21).bezierVertex(135, 9, 156, 17, 155, 34);
    vertex(155, 40).bezierVertex(154, 51, 163, 59, 173, 59);
    vertex(180, 58).bezierVertex(196, 58, 205, 78, 192, 89);
    vertex(188, 94).bezierVertex(180, 101, 180, 113, 188, 120);
    vertex(192, 124).bezierVertex(205, 135, 196, 156, 180, 155);
    vertex(173, 155).bezierVertex(163, 154, 154, 163, 155, 174);
    vertex(155, 180).bezierVertex(156, 197, 135, 205, 124, 193);
    vertex(120, 188).bezierVertex(113, 180, 100, 180, 93, 188);
    vertex(89, 193).bezierVertex(78, 205, 57, 196, 58, 180);
    vertex(59, 173).bezierVertex(59, 163, 50, 154, 40, 155);
    vertex(34, 155).bezierVertex(17, 156, 8, 135, 21, 124);
    vertex(25, 120).bezierVertex(33, 113, 33, 101, 25, 94);
    vertex(21, 89).bezierVertex(8, 78, 17, 58, 34, 58);
    vertex(40, 59).bezierVertex(50, 59, 59, 51, 59, 40);
    vertex(58, 34).bezierVertex(57, 17, 78, 9, 89, 21);
    vertex(93, 26).bezierVertex(100, 33, 113, 33, 120, 26);
    endShape().pop();

    /* halo 3 */
    push();
    rotate(mills / 10).translate(OFFSET, OFFSET);

    fill(PALETTE[2]).beginShape(); // #541642
    vertex(117, 49).vertex(122, 40);
    bezierVertex(129, 28, 147, 35, 143, 48);
    vertex(140, 59);
    bezierVertex(138, 67, 146, 75, 154, 73);
    bezierVertex(154, 73, 154, 73, 155, 73);
    vertex(165, 70).bezierVertex(178, 67, 186, 85, 174, 91);
    vertex(164, 97);
    bezierVertex(157, 101, 156, 112, 164, 117);
    bezierVertex(164, 117, 164, 117, 164, 117);
    vertex(174, 122).bezierVertex(186, 129, 178, 147, 165, 143);
    vertex(155, 140);
    bezierVertex(146, 138, 138, 146, 140, 155);
    bezierVertex(140, 155, 140, 155, 140, 155);
    vertex(143, 165).bezierVertex(147, 178, 129, 186, 122, 174);
    vertex(117, 165);
    bezierVertex(112, 157, 101, 157, 97, 164);
    bezierVertex(97, 164, 97, 164, 97, 165);
    vertex(91, 174).bezierVertex(84, 186, 66, 178, 70, 165);
    vertex(73, 155);
    bezierVertex(75, 146, 67, 138, 59, 140);
    bezierVertex(59, 140, 59, 141, 59, 141);
    vertex(48, 143).bezierVertex(35, 147, 28, 129, 39, 122);
    vertex(49, 117);
    bezierVertex(57, 112, 57, 101, 49, 97);
    bezierVertex(49, 97, 49, 97, 49, 97);
    vertex(39, 91).bezierVertex(28, 85, 35, 67, 48, 70);
    vertex(59, 73);
    bezierVertex(67, 75, 75, 68, 73, 59);
    bezierVertex(73, 59, 73, 59, 73, 59);
    vertex(70, 48).bezierVertex(66, 35, 84, 28, 91, 40);
    vertex(97, 49);
    bezierVertex(101, 57, 112, 57, 117, 49);
    bezierVertex(117, 49, 117, 49, 117, 49);
    endShape().pop();

    /* halo 4 */
    push();
    rotate(mills / -10).translate(OFFSET, OFFSET);

    fill(PALETTE[3]).beginShape(); // #7B087E
    vertex(117, 49).vertex(122, 40);
    bezierVertex(129, 28, 147, 35, 143, 48);
    vertex(140, 59);
    bezierVertex(138, 67, 146, 75, 154, 73);
    bezierVertex(154, 73, 154, 73, 155, 73);
    vertex(165, 70).bezierVertex(178, 67, 186, 85, 174, 91);
    vertex(164, 97);
    bezierVertex(157, 101, 156, 112, 164, 117);
    bezierVertex(164, 117, 164, 117, 164, 117);
    vertex(174, 122).bezierVertex(186, 129, 178, 147, 165, 143);
    vertex(155, 140);
    bezierVertex(146, 138, 138, 146, 140, 155);
    bezierVertex(140, 155, 140, 155, 140, 155);
    vertex(143, 165).bezierVertex(147, 178, 129, 186, 122, 174);
    vertex(117, 165);
    bezierVertex(112, 157, 101, 157, 97, 164);
    bezierVertex(97, 164, 97, 164, 97, 165);
    vertex(91, 174).bezierVertex(84, 186, 66, 178, 70, 165);
    vertex(73, 155);
    bezierVertex(75, 146, 67, 138, 59, 140);
    bezierVertex(59, 140, 59, 141, 59, 141);
    vertex(48, 143).bezierVertex(35, 147, 28, 129, 39, 122);
    vertex(49, 117);
    bezierVertex(57, 112, 57, 101, 49, 97);
    bezierVertex(49, 97, 49, 97, 49, 97);
    vertex(39, 91).bezierVertex(28, 85, 35, 67, 48, 70);
    vertex(59, 73);
    bezierVertex(67, 75, 75, 68, 73, 59);
    bezierVertex(73, 59, 73, 59, 73, 59);
    vertex(70, 48).bezierVertex(66, 35, 84, 28, 91, 40);
    vertex(97, 49);
    bezierVertex(101, 57, 112, 57, 117, 49);
    bezierVertex(117, 49, 117, 49, 117, 49);
    endShape().pop();

    /* halo 5 */
    push();
    rotate(mills / 5).translate(OFFSET, OFFSET);

    fill(PALETTE[4]).beginShape(); // #BA007C
    vertex(131, 70).vertex(137, 66);
    bezierVertex(145, 60, 156, 70, 149, 78);
    vertex(144, 84);
    bezierVertex(140, 89, 143, 97, 149, 98);
    bezierVertex(149, 98, 149, 98, 149, 98);
    vertex(157, 99).bezierVertex(167, 101, 167, 115, 157, 116);
    vertex(149, 117).bezierVertex(142, 118, 139, 126, 143, 131);
    vertex(148, 138).bezierVertex(154, 146, 143, 156, 135, 149);
    vertex(129, 144);
    bezierVertex(124, 140, 116, 143, 115, 149);
    bezierVertex(115, 150, 115, 150, 115, 150);
    vertex(114, 158).bezierVertex(113, 168, 98, 167, 97, 157);
    vertex(96, 149);
    bezierVertex(95, 143, 88, 139, 82, 143);
    bezierVertex(82, 143, 82, 143, 82, 143);
    vertex(76, 148).bezierVertex(68, 154, 58, 144, 64, 136);
    vertex(69, 129);
    bezierVertex(73, 124, 70, 116, 64, 115);
    bezierVertex(64, 115, 64, 115, 64, 115);
    vertex(56, 114).bezierVertex(46, 113, 46, 98, 56, 97);
    vertex(64, 96);
    bezierVertex(71, 96, 74, 88, 70, 83);
    bezierVertex(70, 83, 70, 83, 70, 82);
    vertex(65, 76).bezierVertex(59, 68, 70, 58, 78, 64);
    vertex(84, 69);
    bezierVertex(89, 74, 97, 71, 98, 64);
    bezierVertex(98, 64, 98, 64, 98, 64);
    vertex(99, 56).bezierVertex(101, 46, 115, 46, 116, 56);
    vertex(117, 64);
    bezierVertex(118, 71, 125, 74, 131, 70);
    bezierVertex(131, 70, 131, 70, 131, 70);
    endShape().pop();

    /* halo 6 */
    push();
    rotate(mills / -5).translate(OFFSET, OFFSET);

    fill(PALETTE[5]).beginShape(); // #5F1C73
    vertex(139, 58).vertex(148, 52);
    bezierVertex(159, 43, 172, 58, 164, 68);
    vertex(157, 77);
    bezierVertex(151, 83, 155, 94, 164, 95);
    bezierVertex(164, 95, 164, 95, 164, 95);
    vertex(175, 97).bezierVertex(188, 99, 188, 118, 174, 120);
    vertex(163, 121);
    bezierVertex(155, 122, 150, 132, 155, 139);
    bezierVertex(155, 139, 155, 139, 155, 139);
    vertex(162, 148).bezierVertex(170, 159, 156, 172, 145, 164);
    vertex(137, 157);
    bezierVertex(130, 151, 120, 155, 118, 164);
    bezierVertex(118, 164, 118, 164, 118, 164);
    vertex(116, 175).bezierVertex(114, 188, 95, 188, 94, 174);
    vertex(92, 164);
    bezierVertex(92, 155, 81, 150, 74, 155);
    bezierVertex(74, 155, 74, 156, 74, 156);
    vertex(65, 162).bezierVertex(54, 170, 41, 156, 49, 145);
    vertex(56, 137);
    bezierVertex(62, 130, 58, 120, 49, 118);
    bezierVertex(49, 118, 49, 118, 49, 118);
    vertex(38, 117).bezierVertex(25, 115, 25, 95, 39, 94);
    vertex(50, 93);
    bezierVertex(59, 92, 63, 82, 58, 74);
    bezierVertex(58, 74, 58, 74, 58, 74);
    vertex(51, 66).bezierVertex(43, 55, 57, 41, 68, 50);
    vertex(76, 57);
    bezierVertex(83, 62, 94, 58, 95, 49);
    bezierVertex(95, 49, 95, 49, 95, 49);
    vertex(97, 39).bezierVertex(99, 25, 118, 26, 120, 39);
    vertex(121, 50);
    bezierVertex(122, 59, 132, 63, 139, 58);
    bezierVertex(139, 58, 139, 58, 139, 58);
    endShape().pop();

    pop();
    return this;
  }

  drawKing() {
    const alpha = tan(frameCount / 15) + 150;

    push();
    translate(this.pos.x + King.OFFSET, this.pos.y + King.OFFSET);
    noStroke();

    image(this.king, 0, 0);

    /* left eye blink */
    fill(21, 23, 21, alpha); // #151715
    beginShape().vertex(84, 71);
    bezierVertex(86, 70, 88, 70, 90, 70);
    bezierVertex(92, 70, 95, 71, 95, 72);
    bezierVertex(95, 73, 92, 74, 89, 73);
    bezierVertex(87, 73, 85, 72, 84, 71);
    endShape();

    /* right eye blink */
    beginShape().vertex(130, 71);
    bezierVertex(128, 70, 126, 70, 124, 70);
    bezierVertex(121, 70, 118, 71, 118, 72);
    bezierVertex(118, 73, 122, 74, 124, 73);
    bezierVertex(126, 73, 128, 72, 130, 71);
    endShape();

    pop();
    return this;
  }

  createKing() {
    const pg = createGraphics(160, 170);

    /* beard */
    pg.noStroke().fill('#1D1920').beginShape().
    vertex(151, 100).vertex(144, 76).vertex(144, 76).
    vertex(145, 69).vertex(139, 52).vertex(75, 52).
    vertex(68, 69).vertex(70, 76).vertex(69, 76).
    vertex(62, 100).vertex(57, 147).vertex(94, 170).
    vertex(119, 170).vertex(156, 147).vertex(151, 100).
    endShape(CLOSE);

    /* face */
    pg.fill('#96988B').beginShape().
    vertex(150, 112).bezierVertex(150, 108, 150, 104, 149, 100).
    vertex(149, 100).vertex(142, 76).vertex(143, 69).vertex(137, 52).
    vertex(76, 52).vertex(70, 69).vertex(72, 76).vertex(65, 100).
    bezierVertex(62, 108, 62, 116, 65, 124).
    bezierVertex(65, 128, 67, 131, 70, 133).
    bezierVertex(72, 134, 74, 135, 76, 135).
    bezierVertex(78, 135, 80, 135, 82, 134).
    bezierVertex(80, 137, 78, 142, 78, 146).
    bezierVertex(78, 147, 78, 148, 78, 150).
    bezierVertex(78, 152, 79, 153, 80, 155).
    bezierVertex(80, 157, 81, 158, 82, 159).
    bezierVertex(86, 164, 91, 167, 96, 167).
    bezierVertex(98, 167, 100, 166, 102, 165).
    bezierVertex(107, 161, 107, 152, 101, 145).
    bezierVertex(101, 144, 100, 144, 100, 143).
    vertex(113, 143).
    bezierVertex(113, 144, 112, 144, 112, 145).
    bezierVertex(107, 152, 106, 161, 111, 165).
    bezierVertex(113, 166, 115, 167, 117, 167).
    bezierVertex(122, 167, 127, 164, 131, 159).
    bezierVertex(132, 158, 133, 157, 133, 155).
    bezierVertex(134, 153, 135, 152, 135, 150).
    bezierVertex(135, 148, 135, 147, 135, 146).
    bezierVertex(135, 144, 134, 142, 134, 140).
    bezierVertex(133, 138, 132, 136, 131, 134).
    bezierVertex(133, 135, 135, 135, 137, 135).
    bezierVertex(139, 135, 141, 134, 143, 133).
    bezierVertex(146, 131, 148, 128, 148, 124).
    bezierVertex(150, 120, 150, 116, 150, 112).
    endShape();

    /* nose */
    pg.fill('#DDA17E').beginShape().
    vertex(120, 110).vertex(93, 110).vertex(107, 71).vertex(120, 110).
    endShape(CLOSE).

    fill('#CD6947').beginShape().
    vertex(106, 97).vertex(94, 108).vertex(106, 73).vertex(106, 97).
    endShape(CLOSE).

    beginShape().
    vertex(107, 97).vertex(119, 108).vertex(107, 73).vertex(107, 97).
    endShape(CLOSE).

    fill('#85305A').beginShape().
    vertex(107, 98).vertex(93, 110).vertex(120, 110).vertex(107, 98).
    endShape(CLOSE);

    /* left eye mask */
    pg.fill('#474741').beginShape().vertex(71, 67).
    bezierVertex(76, 66, 82, 66, 87, 66).
    bezierVertex(95, 66, 108, 67, 109, 71).
    bezierVertex(109, 74, 101, 77, 94, 78).
    bezierVertex(91, 79, 87, 79, 84, 78).
    bezierVertex(78, 77, 73, 73, 71, 67).
    endShape();

    /* right eye mask */
    pg.beginShape().vertex(142, 67).
    bezierVertex(137, 66, 131, 66, 126, 66).
    bezierVertex(118, 66, 105, 67, 105, 71).
    bezierVertex(104, 74, 112, 77, 119, 78).
    bezierVertex(122, 79, 126, 79, 129, 78).
    bezierVertex(135, 77, 140, 73, 142, 67).
    endShape();

    /* philtrum */
    pg.fill('#514B48').beginShape().vertex(113, 120).
    vertex(100, 120).vertex(103, 110).vertex(110, 110).vertex(113, 120).
    endShape(CLOSE);

    /* mustache */
    pg.fill('#1E1B1D').beginShape().
    vertex(104, 115).vertex(94, 115).vertex(85, 123).vertex(77, 107).
    vertex(85, 116).vertex(92, 111).vertex(104, 111).vertex(104, 115).
    endShape(CLOSE).

    beginShape().
    vertex(109, 115).vertex(119, 115).vertex(128, 123).vertex(136, 107).
    vertex(128, 116).vertex(121, 111).vertex(109, 111).vertex(109, 115).
    endShape(CLOSE);

    /* lips */
    pg.fill('#32342A').beginShape().vertex(114, 132).
    vertex(100, 132).vertex(92, 130).vertex(100, 137).
    vertex(114, 137).vertex(122, 130).vertex(114, 132).
    endShape(CLOSE).

    ellipse(107, 132, 10, 2).beginShape().
    vertex(124, 125).vertex(112, 118).vertex(107, 120).
    vertex(107, 120).vertex(101, 118).vertex(89, 125).
    vertex(87, 123).vertex(89, 128).vertex(101, 125).
    vertex(107, 126).vertex(107, 126).vertex(107, 126).
    vertex(107, 126).vertex(107, 126).vertex(112, 125).
    vertex(124, 128).vertex(127, 123).vertex(124, 125).
    endShape(CLOSE);

    /* cheeks */
    pg.fill('#A3A599').
    circle(79, 95, 17).circle(133, 95, 17).
    circle(117, 152, 15).circle(97, 152, 15);

    /* crown shadows */
    pg.fill('#49493A').beginShape().
    vertex(103, 61).vertex(78, 52).vertex(107, 52).vertex(103, 61).
    endShape(CLOSE).

    beginShape().
    vertex(110, 61).vertex(135, 52).vertex(107, 52).vertex(110, 61).
    endShape(CLOSE);

    /* crown base */
    pg.fill('#E5D277').beginShape().vertex(138, 50).
    vertex(77, 50).vertex(83, 11).vertex(92, 30).
    vertex(98, 10).vertex(106, 32).vertex(116, 9).
    vertex(122, 31).vertex(132, 11).vertex(138, 50).
    endShape(CLOSE);

    /* crown lower base */
    pg.fill('#CAB125').rect(74, 49, 66, 4).
    beginShape().vertex(138, 49).
    vertex(77, 49).vertex(83, 14).vertex(92, 31).
    vertex(98, 12).vertex(106, 32).vertex(116, 12).
    vertex(121, 32).vertex(131, 14).vertex(138, 49).
    endShape(CLOSE);

    /* crown shines */
    pg.fill('#E0BA37').beginShape().
    vertex(111, 49).vertex(103, 49).vertex(103, 24).
    vertex(106, 32).vertex(111, 22).vertex(111, 49).
    endShape(CLOSE).

    fill('#E8D27E').beginShape().vertex(130, 16).
    vertex(124, 26).vertex(124, 49).vertex(130, 49).vertex(130, 16).
    endShape(CLOSE).

    fill('#C29D38').beginShape().vertex(83, 15).
    vertex(89, 26).vertex(89, 49).vertex(83, 49).vertex(83, 15).
    endShape(CLOSE).

    fill('#F8E8AD').
    quad(77, 7, 81, 3, 86, 7, 82, 12).
    quad(92, 6, 97, 1, 102, 6, 97, 10).
    quad(109, 6, 115, 1, 120, 6, 115, 10).
    quad(128, 7, 132, 3, 137, 7, 132, 12).

    fill('#EECE61').
    quad(78, 7, 81, 4, 83, 7, 81, 12).
    quad(93, 6, 97, 2, 101, 6, 97, 9).
    quad(110, 6, 115, 2, 119, 6, 115, 9).
    quad(130, 7, 132, 4, 136, 7, 131, 12);

    return pg.get();
  }
}

After replacing your “King.js” w/ mine your code behaved like the original Java Mode version.

P.S.:

  • Spoke too soon! Just noticed it isn’t bouncing like it should!
  • Changed the values used in the Java Mode to your current 1s.
  • Also I had to make an extra call to King::update() for it to work.
  • No idea why the p5js version can’t behave the same as Java Mode using the same constants.

In short, I’ve got rid of both desired & steer and replaced them w/ PVector tmp.

The strategy I’ve chosen was to initialize tmp w/ vel: tmp.set(vel);

At the end of King::boundaries() check if tmp isn’t equals() to vel; which happens when it’s been changed by the previous if () blocks.

There are other changes I’ve done to the King class in some hopeless attempt to make it run faster.

Any further questions about them just ask.

1 Like

WOW!

Ok, I was really not expecting that!

Thank you so much for putting so much effort to help me!

Your revamp version is fantastic, I must say! And the boundaries() function is much easier to understand now! Thank you very much!

This is an old project, and I was only trying to port it to my web browser, but now I’m really tempted on rewriting all the other scripts with what I learned from yours.

1 Like