Rotate arc in pacman animation

Waka is the movement of the mouth/bite of pac man when its moving.

2 Likes

I made some work and progress…but i cant make the rotation…any help would be apreciated…
Pacman moves left, right, up and down…and makes the waka waka… but always pointing to the right… no matter the direction…
I dont know were the bug/error is… here is the code
Any ideas to improve the code are welcome…

const CLOCKWISE_ROTATION = 0;
const ANTICLOCKWISE_ROTATION = 1;

class PacMan {
  constructor(x, y) {
    this.speed = 10;
    this.stepFrame = 0.1;
    this.x = x;
    this.y = y;
    this.direction = 1; //ClockWise 1 Left, 2 up, 3 right, 4 down arbitrary numbers
    fill(255, 255, 0);
    this.biteSize = PI / 16;
    this.startAngle;
    this.endAngle;

  }
  stay() {
    this.startAngle = this.biteSize * sin(frameCount * this.stepFrame) + this.biteSize;
    this.endAngle = TWO_PI - this.startAngle;    
    arc(
      this.x,
      this.y,
      80,
      80,
      this.startAngle,
      this.endAngle,
      PIE
    );
  }
  moveRight() {
    switch (this.direction) {
      case 1:
        //Previous direction was 1 ( left) and new direction would be 3 (right). So i have to rotate from 0 to 180 degrees.
        this.rotatePacman(0, 180, CLOCKWISE_ROTATION);
        break;
      case 2:
        //Previous direction was 2 ( up) and new direction would be 3 (right). So i have to rotate from 90 to 180 degrees.
        this.rotatePacman(90, 180, CLOCKWISE_ROTATION);
        break;
      case 3:
        //Previous direction was 3 ( right) and new direction would be 3 (right). So no rotation needed.
        break;
      case 4:
        //Previous direction was 4 ( down) and new direction would be 3 (right). So i have to rotate from 270 to 180  degrees.
        this.rotatePacman(270, 180, ANTICLOCKWISE_ROTATION);
        break;
      default:
      //
    }
    //new direction ( moving right)
    this.direction = 3;
    this.x = this.x + this.speed;

    arc(this.x, this.y, 80, 80, this.startAngle, this.endAngle, PIE);
  }
  moveLeft() {
    switch (this.direction) {
      case 1:
        //Previous direction was 1 ( left) and new direction would be 1 (left). So no rotation needed.
        break;
      case 2:
        //Previous direction was 2 ( up) and new direction would be 1 (left). So i have to rotate from 90 to 0 degrees.
        this.rotatePacman(90, 0, ANTICLOCKWISE_ROTATION);
        break;
      case 3:
        //Previous direction was 3 ( right) and new direction would be 1 (left). So i have to rotate from 180 to 0 degrees.
        this.rotatePacman(180, 0, ANTICLOCKWISE_ROTATION);
        break;
      case 4:
        //Previous direction was 4 ( down) and new direction would be 1 (left). So i have to rotate from 270 to 0  degrees.
        //Better from -90 to 0. if possible
        this.rotatePacman(-90, 0, ANTICLOCKWISE_ROTATION);
        break;
      default:
      //
    }
    //new direction ( moving left)
    this.direction = 1;
    this.x = this.x - this.speed;

    arc(this.x, this.y, 80, 80, this.startAngle, this.endAngle, PIE);
  }

  moveDown() {
    switch (this.direction) {
      case 1:
        //Previous direction was 1 ( left) and new direction would be 4 (down).So i have to rotate from 0 to 270 o from 0 to -90
        //this.rotatePacman(0, 270, CLOCKWISE_ROTATION);
        this.rotatePacman(0, -90, ANTICLOCKWISE_ROTATION);
        break;
      case 2:
        //Previous direction was 2 ( up) and new direction would be 4 (down). So i have to rotate from 90 to 270 degrees.
        this.rotatePacman(90, 270, CLOCKWISE_ROTATION);
        break;
      case 3:
        //Previous direction was 3 ( right) and new direction would be 4 (down). So i have to rotate from 180 to 270 degrees.
        this.rotatePacman(180, 270, CLOCKWISE_ROTATION);
        break;
      case 4:
        //Previous direction was 4 ( down) and new direction would be 4 (down). So no rotation needed.
        break;
      default:
      //
    }
    //new direction ( moving down)
    this.direction = 4;
    this.y = this.y + this.speed;

    arc(this.x, this.y, 80, 80, this.startAngle, this.endAngle, PIE);
  }
  moveUp() {
    switch (this.direction) {
      case 1:
        //Previous direction was 1 ( left) and new direction would be 2 (up).So i have to rotate from 0 to 90
        //this.rotatePacman(0, 270, CLOCKWISE_ROTATION);
        this.rotatePacman(0, 90, CLOCKWISE_ROTATION);
        break;
      case 2:
        //Previous direction was 2 ( up) and new direction would be 2 (up). So no rotation needed.
        break;
      case 3:
        //Previous direction was 3 ( right) and new direction would be 2 (UP). So i have to rotate from 180 to 90 degrees.
        this.rotatePacman(180, 90, ANTICLOCKWISE_ROTATION);
        break;
      case 4:
        //Previous direction was 4 ( down) and new direction would be 2 (up). So rotation needed from 270 to 90 or -90 to 90.
        this.rotatePacman(270, 90, ANTICLOCKWISE_ROTATION);
        //this.rotatePacman(90, -90, ANTICLOCKWISE_ROTATION);
        break;
      default:
      //
    }
    //new direction ( moving up)
    this.direction = 2;
    this.y = this.y - this.speed;

    arc(this.x, this.y, 80, 80, this.startAngle, this.endAngle, PIE);
  }

  /**
   * Rotate pacman from one start angle to a end angle, rotation direction could be clockwise or anticlockwise.
   * @constructor
   * @param {int} startAngle - start angle of the rotation.
   * @param {int} endAngle - the end angle of the rotation.
   * @param {int} direction - CLOCKWISE_ROTATION or ANTICLOCK_ROTATION
   */
  rotatePacman(startAngle, endAngle, direction) {
    
    const STEP_ANGLE = 0.5;
    fill(255, 255, 0);
    noStroke();

    // Update start and stop angles
    this.biteSize = PI / 16; // smaller the denominator, bigger the bite
    startAngle = this.biteSize * sin(frameCount * 0.1) + this.biteSize;
    endAngle = TWO_PI - startAngle;
    let pacAngle = startAngle
    // this is the only Pacman that you are drawing
    while ( pacAngle < endAngle) 
    {
      push();
      translate(this.x, this.y);
      /*if( direction == CLOCKWISE_ROTATION){
        pacAngle= pacAngle + 0.5;
       }
      else if ( direction == ANTICLOCKWISE_ROTATION) {
        pacAngle = pacAngle + 0.5;
      }
      else {
        console.log("Aqui pasa algo raro")
      }*/
       pacAngle = pacAngle + STEP_ANGLE;
       if( direction == CLOCKWISE_ROTATION){
        rotate(radians(pacAngle)); // this angle changes
       }
      else if ( direction == ANTICLOCKWISE_ROTATION) {
       rotate(radians(-pacAngle)); // this angle changes
      }
      else {
        console.log("Aqui pasa algo raro")
      }
//rotate(radians(pacAngle)); // this angle changes
      arc(this.x, this.y, 80, 80, startAngle, startAngle + pacAngle, PIE);
      pop();
    }
    //pacAngle = pacAngle + 0.5; // grow angle, makes Pacman turn
  } //Close method rotatePacman
} // Close Paman class

function setup() {
  createCanvas(1200, 800);
  pacMan = new PacMan(50, 50);
  pacMan.direction = 3;
}

function draw() {
  background(0);
  pacMan.stay();
}

// **** Click on canvas to start **** //
function keyPressed(event) {
  if (keyCode === LEFT_ARROW) {
    pacMan.moveLeft();
  } else if (keyCode === RIGHT_ARROW) {
    pacMan.moveRight();
  } else if (keyCode === UP_ARROW) {
    pacMan.moveUp();
  } else if (keyCode === DOWN_ARROW) {
    pacMan.moveDown();
  }
}

Hello @edufissure,

This topic inspired this:
Pac-Man Waka Waka Arcs

I wrote from scratch… there may be elements in there that may help.

:)

Made some progress…i do the waka waka animation and pacman can move in the four directions…the only thing im missing and i really need help it to rotate from looking left to looking up, for example in some kind of nice transition, lets say degree by degree

The code:


/*frameCount

A Number variable that tracks the number of frames drawn since the sketch started.

frameCount's value is 0 inside setup(). It increments by 1 each time the code in draw() finishes executing.
*/
const CLOCKWISE_ROTATION = 0;
const ANTICLOCKWISE_ROTATION = 1;

class PacMan {
  constructor(x, y) {
    this.speed = 10;
    this.stepFrame = 0.1;
    this.x = x;
    this.y = y;
    this.direction = 1; //ClockWise 1 Left, 2 up, 3 right, 4 down arbitrary numbers
    fill(255, 255, 0);
    this.biteSize = PI / 16;
    this.startBiteAngle;
    this.endBiteAngle;
  }
  stay() {
    //angleMode(DEGREES);

    switch (this.direction) {
      case 1:
        this.startBiteAngle = radians(-168.75) + this.biteSize * sin(frameCount * this.stepFrame);
        this.endBiteAngle = radians(168.75) - this.biteSize * sin(frameCount * this.stepFrame);
        break;
      case 2:
        this.startBiteAngle = radians(-78.75) + this.biteSize * sin(frameCount * this.stepFrame);
        this.endBiteAngle = radians(258.75) - this.biteSize * sin(frameCount * this.stepFrame);
        break;
      case 3:
        this.startBiteAngle = this.biteSize * sin(frameCount * this.stepFrame) + this.biteSize;
        this.endBiteAngle = TWO_PI - this.startBiteAngle;
        break;
      case 4:
        this.startBiteAngle = radians(-258.75) + this.biteSize * sin(frameCount * this.stepFrame);
        this.endBiteAngle = radians(78.75) - this.biteSize * sin(frameCount * this.stepFrame);
        break;
      default:
      //
    }

    arc(this.x, this.y, 80, 80, this.startBiteAngle, this.endBiteAngle, PIE);
  }
  moveRight() {
    switch (this.direction) {
      case 1:
        //Previous direction was 1 ( left) and new direction would be 3 (right). So i have to rotate from 0 to 180 degrees.
        this.rotatePacman(0, 180, CLOCKWISE_ROTATION);
        break;
      case 2:
        //Previous direction was 2 ( up) and new direction would be 3 (right). So i have to rotate from 90 to 180 degrees.
        this.rotatePacman(90, 180, CLOCKWISE_ROTATION);
        break;
      case 3:
        //Previous direction was 3 ( right) and new direction would be 3 (right). So no rotation needed.
        break;
      case 4:
        //Previous direction was 4 ( down) and new direction would be 3 (right). So i have to rotate from 270 to 180  degrees.
        this.rotatePacman(270, 180, ANTICLOCKWISE_ROTATION);
        break;
      default:
      //
    }
    //new direction ( moving right)
    this.direction = 3;
    this.x = this.x + this.speed;
    
    this.startBiteAngle = this.biteSize * sin(frameCount * this.stepFrame) + this.biteSize;
    this.endBiteAngle = TWO_PI - this.startBiteAngle;
    arc(this.x, this.y, 80, 80, this.startBiteAngle, this.endBiteAngle, PIE);
  }
  moveLeft() {
    switch (this.direction) {
      case 1:
        //Previous direction was 1 ( left) and new direction would be 1 (left). So no rotation needed.
        break;
      case 2:
        //Previous direction was 2 ( up) and new direction would be 1 (left). So i have to rotate from 90 to 0 degrees.
        this.rotatePacman(90, 0, ANTICLOCKWISE_ROTATION);
        break;
      case 3:
        //Previous direction was 3 ( right) and new direction would be 1 (left). So i have to rotate from 180 to 0 degrees.
        this.rotatePacman(180, 0, ANTICLOCKWISE_ROTATION);
        break;
      case 4:
        //Previous direction was 4 ( down) and new direction would be 1 (left). So i have to rotate from 270 to 0  degrees.
        //Better from -90 to 0. if possible
        this.rotatePacman(-90, 0, ANTICLOCKWISE_ROTATION);
        break;
      default:
      //
    }
    //new direction ( moving left)
    this.direction = 1;
    this.x = this.x - this.speed;
    this.stay();
    /*
    this.startBiteAngle = radians(-168.75) + this.biteSize * sin(frameCount * this.stepFrame);
    this.endBiteAngle = radians(168.75) - this.biteSize * sin(frameCount * this.stepFrame);

    arc(this.x, this.y, 80, 80, this.startBiteAngle, this.endBiteAngle, PIE);*/
  }

  moveDown() {
    switch (this.direction) {
      case 1:
        //Previous direction was 1 ( left) and new direction would be 4 (down).So i have to rotate from 0 to 270 o from 0 to -90
        //this.rotatePacman(0, 270, CLOCKWISE_ROTATION);
        this.rotatePacman(0, -90, ANTICLOCKWISE_ROTATION);
        break;
      case 2:
        //Previous direction was 2 ( up) and new direction would be 4 (down). So i have to rotate from 90 to 270 degrees.
        this.rotatePacman(90, 270, CLOCKWISE_ROTATION);
        break;
      case 3:
        //Previous direction was 3 ( right) and new direction would be 4 (down). So i have to rotate from 180 to 270 degrees.
        this.rotatePacman(180, 270, CLOCKWISE_ROTATION);
        break;
      case 4:
        //Previous direction was 4 ( down) and new direction would be 4 (down). So no rotation needed.
        break;
      default:
      //
    }
    //new direction ( moving down)
    this.direction = 4;
    this.y = this.y + this.speed;
    this.stay();
    /*
    this.startBiteAngle = radians(-258.75) + this.biteSize * sin(frameCount * this.stepFrame);
    this.endBiteAngle = radians(78.75) - this.biteSize * sin(frameCount * this.stepFrame);

    arc(this.x, this.y, 80, 80, this.startBiteAngle, this.endBiteAngle, PIE);*/
  }
  moveUp() {
    switch (this.direction) {
      case 1:
        //Previous direction was 1 ( left) and new direction would be 2 (up).So i have to rotate from 0 to 90
        //this.rotatePacman(0, 270, CLOCKWISE_ROTATION);
        this.rotatePacman(0, 90, CLOCKWISE_ROTATION);
        break;
      case 2:
        //Previous direction was 2 ( up) and new direction would be 2 (up). So no rotation needed.
        break;
      case 3:
        //Previous direction was 3 ( right) and new direction would be 2 (UP). So i have to rotate from 180 to 90 degrees.
        this.rotatePacman(180, 90, ANTICLOCKWISE_ROTATION);
        break;
      case 4:
        //Previous direction was 4 ( down) and new direction would be 2 (up). So rotation needed from 270 to 90 or -90 to 90.
        this.rotatePacman(270, 90, ANTICLOCKWISE_ROTATION);
        //this.rotatePacman(90, -90, ANTICLOCKWISE_ROTATION);
        break;
      default:
      //
    }
    //new direction ( moving up)
    this.direction = 2;
    this.y = this.y - this.speed;
    this.stay();
    /*
  this.startBiteAngle = radians(-78.75) + this.biteSize * sin(frameCount * this.stepFrame);
   this.endBiteAngle = radians(258.75) - this.biteSize * sin(frameCount * this.stepFrame);
    arc(this.x, this.y, 80, 80, this.startBiteAngle, this.endBiteAngle, PIE);*/
  }

  /**
   * Rotate pacman from one start angle to a end angle, rotation direction could be clockwise or anticlockwise.
   * @constructor
   * @param {int} startBiteAngle - start angle of the rotation.
   * @param {int} endBiteAngle - the end angle of the rotation.
   * @param {int} direction - CLOCKWISE_ROTATION or ANTICLOCK_ROTATION
   */
  rotatePacman(startAngle, endAngle, direction) {
    noLoop();
    const STEP_ANGLE = 0.5;
    fill(255, 255, 0);
    noStroke();

    
    let pacAngle = startAngle;
    // this is the only Pacman that you are drawing
    while (pacAngle < endAngle) {
      push();
      translate(this.x, this.y);
      pacAngle = pacAngle + STEP_ANGLE;
      if (direction == CLOCKWISE_ROTATION) {
        rotate(radians(pacAngle)); // this angle changes
      } else if (direction == ANTICLOCKWISE_ROTATION) {
        rotate(radians(-pacAngle)); // this angle changes
      } else {
        console.log("Aqui pasa algo raro");
      }
      console.log("Estoy en "+ pacAngle + " y quiero llegar a endAngle" + endAngle);
    //  rotate(radians(pacAngle)); // this angle changes
      //arc( this.x, this.y, 80,  80, startBiteAngle, startBiteAngle + pacAngle, PIE);
      pop();
    }
    loop();
    //pacAngle = pacAngle + 0.5; // grow angle, makes Pacman turn
  } //Close method rotatePacman
} // Close Paman class

function setup() {
  createCanvas(700, 700);
  pacMan = new PacMan(50, 50);
  pacMan.direction = 1;
}

function draw() {
  background(0);
  pacMan.stay();
}

// **** Click on canvas to start **** //
function keyPressed(event) {
  if (keyCode === LEFT_ARROW) {
    pacMan.moveLeft();
  } else if (keyCode === RIGHT_ARROW) {
    pacMan.moveRight();
  } else if (keyCode === UP_ARROW) {
    pacMan.moveUp();
  } else if (keyCode === DOWN_ARROW) {
    pacMan.moveDown();
  }
}

Also any help imporving the code would be apreciated, i think it can be easier to paint the arc (pacman) with start and end bite angle…But i havent found a better or more easy solution.

Thanks
pd: think if you wanna help that my students would be happy :slight_smile:

@GoToLoop can you adapt or give some hints this code: Reddit - Dive into anything

To my code, if you test my code it gives some weird behaviour when pressing more than one key at once ( left, right, up, down arrow). I think the code is right but if you press simultaneally or almost same time lets say right and left, then the result movement is weird…some kind of give some priority or waiting some time miliseconds to avoid this… i saw that in you code the movement is clean and smooth…

Thanks

Another rotation example (rotate PacMan by hitting spaceBar):

float rotDegStart = 12; // start facing right
float rotDegEnd = 348;
float biteSize;

void setup() {
  size(400, 200);
  surface.setTitle("PacMan Rotate");
  fill(255, 255, 0);
  biteSize = PI/16; //smaller denominator => bigger bite
}

void draw() {
  background(0);
  arc(width/2, height/2, 80, 80, radians(rotDegStart)-biteSize*sin(frameCount*0.1), radians(rotDegEnd)+biteSize*sin(frameCount*0.1), PIE);
}

void keyPressed() {
  // spaceBar = 32
  if (keyCode == 32) {
    rotDegStart += 2;
    rotDegEnd += 2;
  }
}

There’s also a p5.js version of it:
https://www.Reddit.com/r/processing/comments/bshqa8/how_would_i_make_a_keypressed_function_support/eoolcrm/
Maybe it’s easier to understand the code.

I think i did it…what do you think of the code ? It lacks some comments but seems quite clean and using functions and the class Pacman…
Im not sure if rotating is working as should, as if i change the step_angle i cant see much difference…

/*frameCount

A Number variable that tracks the number of frames drawn since the sketch started.

frameCount's value is 0 inside setup(). It increments by 1 each time the code in draw() finishes ecoordXPacmanecuting.
*/
const CLOCKWISE_ROTATION = 0;
const ANTICLOCKWISE_ROTATION = 1;


class PacMan {
  
  
  /**
   * Rotate pacman from one start angle to a end angle, rotation pacmanDirection could be clockwise or anticlockwise.
   * @constructor
   * @param {int} speedPacman - speedPacman of paman.
   * @param {int} speedPacmanBitePacman - steps between frames.
   * @param {int} pacmanDirection - CLOCKWISE_ROTATION or ANTICLOCK_ROTATION
   */
  constructor(coordXPacman, coordYPacman) {
    //Fill pacman with color yellow
    fill(255, 255, 0);
    
    //Values for elements
    this.speedPacman = 20;
    this.speedPacmanBitePacman = 0.2;
    this.coordXPacman = coordXPacman;
    this.coordYPacman = coordYPacman;
    this.pacmanDirection = 1; //ClockWise 1 Left, 2 up, 3 right, 4 down arbitrary numbers
    this.pacmanSize = 80;// Width and height of pacman
   // 
    this.biteSize = PI / 16;
    this.startBiteAngle;
    this.endBiteAngle;
  }
  
  stay() {
    switch (this.pacmanDirection) {
      case 1:
        this.startBiteAngle = radians(-168.75) + this.biteSize * sin(frameCount * this.speedPacmanBitePacman);
        this.endBiteAngle = radians(168.75) - this.biteSize * sin(frameCount * this.speedPacmanBitePacman);
        break;
      case 2:
        this.startBiteAngle = radians(-78.75) + this.biteSize * sin(frameCount * this.speedPacmanBitePacman);
        this.endBiteAngle = radians(258.75) - this.biteSize * sin(frameCount * this.speedPacmanBitePacman);
        break;
      case 3:
        this.startBiteAngle = this.biteSize * sin(frameCount * this.speedPacmanBitePacman) + this.biteSize;
        this.endBiteAngle = TWO_PI - this.startBiteAngle;
        break;
      case 4:
        this.startBiteAngle = radians(-258.75) + this.biteSize * sin(frameCount * this.speedPacmanBitePacman);
        this.endBiteAngle = radians(78.75) - this.biteSize * sin(frameCount * this.speedPacmanBitePacman);
        break;
      default:
      //
    }

    arc(this.coordXPacman, this.coordYPacman, this.pacmanSize, this.pacmanSize, this.startBiteAngle, this.endBiteAngle, PIE);
  }
  moveRight() {

    switch (this.pacmanDirection) {
      case 1:
        //Previous pacmanDirection was 1 ( left) and new pacmanDirection would be 3 (right). So i have to rotate from 0 to 180 degrees.
        this.rotatePacman(0, 180, CLOCKWISE_ROTATION);
        break;
      case 2:
        //Previous pacmanDirection was 2 ( up) and new pacmanDirection would be 3 (right). So i have to rotate from 90 to 180 degrees.
        this.rotatePacman(90, 180, CLOCKWISE_ROTATION);
        break;
      case 3:
        //Previous pacmanDirection was 3 ( right) and new pacmanDirection would be 3 (right). So no rotation needed.
        break;
      case 4:
        //Previous pacmanDirection was 4 ( down) and new pacmanDirection would be 3 (right). So i have to rotate from 270 to 180  degrees.
        this.rotatePacman(270, 180, ANTICLOCKWISE_ROTATION);
        break;
      default:
      //
    }
    //new pacmanDirection ( moving right)
    this.pacmanDirection = 3;
    this.coordXPacman = this.coordXPacman + this.speedPacman;
    this.stay();

  }
  moveLeft() {
    switch (this.pacmanDirection) {
      case 1:
        //Previous pacmanDirection was 1 ( left) and new pacmanDirection would be 1 (left). So no rotation needed.
        break;
      case 2:
        //Previous pacmanDirection was 2 ( up) and new pacmanDirection would be 1 (left). So i have to rotate from 90 to 0 degrees.
        this.rotatePacman(90, 0, ANTICLOCKWISE_ROTATION);
        break;
      case 3:
        //Previous pacmanDirection was 3 ( right) and new pacmanDirection would be 1 (left). So i have to rotate from 180 to 0 degrees.
        this.rotatePacman(180, 0, ANTICLOCKWISE_ROTATION);
        break;
      case 4:
        //Previous pacmanDirection was 4 ( down) and new pacmanDirection would be 1 (left). So i have to rotate from 270 to 0  degrees.
        //Better from -90 to 0. if possible
        this.rotatePacman(-90, 0, ANTICLOCKWISE_ROTATION);
        break;
      default:
      //
    }
    //new pacmanDirection ( moving left)
    this.pacmanDirection = 1;
    this.coordXPacman = this.coordXPacman - this.speedPacman;
    this.stay();

  }

  moveDown() {
    switch (this.pacmanDirection) {
      case 1:
        //Previous pacmanDirection was 1 ( left) and new pacmanDirection would be 4 (down).So i have to rotate from 0 to 270 o from 0 to -90
        //this.rotatePacman(0, 270, CLOCKWISE_ROTATION);
        this.rotatePacman(0, -90, ANTICLOCKWISE_ROTATION);
        break;
      case 2:
        //Previous pacmanDirection was 2 ( up) and new pacmanDirection would be 4 (down). So i have to rotate from 90 to 270 degrees.
        this.rotatePacman(90, 270, CLOCKWISE_ROTATION);
        break;
      case 3:
        //Previous pacmanDirection was 3 ( right) and new pacmanDirection would be 4 (down). So i have to rotate from 180 to 270 degrees.
        this.rotatePacman(180, 270, CLOCKWISE_ROTATION);
        break;
      case 4:
        //Previous pacmanDirection was 4 ( down) and new pacmanDirection would be 4 (down). So no rotation needed.
        break;
      default:
      //
    }
    //new pacmanDirection ( moving down)
    this.pacmanDirection = 4;
    this.coordYPacman = this.coordYPacman + this.speedPacman;
    this.stay();

  }
  moveUp() {

    switch (this.pacmanDirection) {
      case 1:
        //Previous pacmanDirection was 1 ( left) and new pacmanDirection would be 2 (up).So i have to rotate from 0 to 90
        this.rotatePacman(0, 90, CLOCKWISE_ROTATION);
        break;
      case 2:
        //Previous pacmanDirection was 2 ( up) and new pacmanDirection would be 2 (up). So no rotation needed.
        break;
      case 3:
        //Previous pacmanDirection was 3 ( right) and new pacmanDirection would be 2 (UP). So i have to rotate from 180 to 90 degrees.
        this.rotatePacman(180, 90, ANTICLOCKWISE_ROTATION);
        break;
      case 4:
        //Previous pacmanDirection was 4 ( down) and new pacmanDirection would be 2 (up). So rotation needed from 270 to 90 or -90 to 90.
        this.rotatePacman(270, 90, ANTICLOCKWISE_ROTATION);
        break;
      default:
      //
    }
    //new pacmanDirection ( moving up)
    this.pacmanDirection = 2;
    this.coordYPacman = this.coordYPacman - this.speedPacman;
    this.stay();
  }

  /**
   * Rotate pacman from one start angle to a end angle, rotation pacmanDirection could be clockwise or anticlockwise.
   * @
   * @param {int} startAngleRotation - start angle of the rotation.
   * @param {int} endAngleRotation - the end angle of the rotation.
   * @param {int} pacmanDirection - CLOCKWISE_ROTATION or ANTICLOCK_ROTATION
   */
  rotatePacman(startAngleRotation, endAngleRotation, pacmanDirection) {
    
    const STEP_ANGLE = 1;
    let angleNow = startAngleRotation;
    
    push();

    // this is the only Pacman that you are drawing
    while (angleNow < endAngleRotation) {
       background(0);
      //Not necessary but it doesnt hurt
       //translate(this.coordXPacman, this.y);
      if (pacmanDirection == CLOCKWISE_ROTATION) {
        rotate(radians(angleNow)); // this angle changes
      } else if (pacmanDirection == ANTICLOCKWISE_ROTATION) {
        rotate(radians(-angleNow)); // this angle changes
      } else {
        console.log("Aqui pasa algo raro");
      }
      arc(this.coordXPacman, this.coordYPacman, this.pacmanSize, this.pacmanSize, angleNow, angleNow + this.biteSize, PIE);

       angleNow = angleNow + STEP_ANGLE;
      console.log("Estoy en "+ angleNow + " y quiero llegar a endAngle" + endAngleRotation);

    }
    
   pop();
   
  } //Close method rotatePacman

} // Close Paman class

function setup() {
  createCanvas(700, 700);
  pacMan = new PacMan(50, 50);
  pacMan.pacmanDirection = 1;
}

function draw() {
  
  //frameRate(30);
  //console.log("Frame Rate es" + frameRate());
  background(0);
  pacMan.stay();
  // Draw a box.
}

// **** Click on canvas to start **** //
function keyPressed(event) {
  if (keyCode === LEFT_ARROW) {
    pacMan.moveLeft();
  } else if (keyCode === RIGHT_ARROW) {
    pacMan.moveRight();
  } else if (keyCode === UP_ARROW) {
    pacMan.moveUp();
  } else if (keyCode === DOWN_ARROW) {
    pacMan.moveDown();
  }
  else{
    padMan.stay();
  }
}

Perhaps one thing to improve is to avoid many key pressed at the same time in ā€œmad modeā€ hitting the keyboard…

Thanks again…any comment or suggestion or solution for keypress would be apreciated…

1 Like

Typographical error.

Just curious; what age range student are you going to teach this to?

done ?? Its strange the code works fine in Web Editor

18 at least 19-21 most of them…
But is a sample, this i would guide them step by step…and then id let them make another game similar to this…like ā€œBusca un tesoroā€, ā€œencuentra la salida de la piramideā€ …

Past year i did it with 4 differente images instead of a arc…this was curious about rotating and using arc…perhaps they can understand more how JS and p5.js works

That could mean it’s not being used.

You seem to place a lot of emphasis on ā€˜rotation’. Pacman can be ā€˜rotated’ by changing the start and end angles of the arc and does not necessarily require the use of push…rotate()…pop. The other interesting aspect of Pacman is his ā€˜bite’ which is animated by using the frameCount and ā€˜sin’ values which fluctuate between positive and negative values, giving the biting motion. Thanks for posting; it’s been a fun thread.

If i had time id make a function rotatePacmanWithoutRotate :wink: as you said…its been interesting to make the rotation in different ways…specially when this project-game has educational purpose. ( i can get adavantage of rotate instruction to explain rotate, and push and pop…

By the way in your code you defien float variables void setup which doesnt work in Editor Web…is a mistake or you only write an idea ? or size instead of createcanvas…or surface.settitle… @svan

Thanks

The following should work in p5.js although not as well as the original code in Java mode. You have to repeatedly hit the SHIFT key to get it to rotate, but that is similar to how your code works for PacMan movement. In Java mode on my system (macOS) PacMan will just keep rotating as long as you hold the spacebar down. Other keys don’t seem to work that way though.

var rotDegStart = 12;
var rotDegEnd = 348;
var bitSize;

function setup() {
  createCanvas(400, 200);
  fill(255, 255, 0);
  biteSize = PI/16; //smaller denominator => bigger bite
}

function draw() {
  background(0);
  arc(width/2, height/2, 80, 80, radians(rotDegStart)-biteSize*sin(frameCount*0.1), radians(rotDegEnd)+biteSize*sin(frameCount*0.1), PIE);
}

function keyPressed() {
  if (keyCode == SHIFT) {
    rotDegStart += 5;
    rotDegEnd += 5;
  }
}

Thanks…two ideas

1 - I was able to translate to p5.js in JS, i didnt recognize your code, i didnt know you can code p5 in Java also…so i was curious why you published some code i didnt know it exist…

2 - I dont see quite clear why or where comes the idea from this line of code…

biteSize*sin(frameCount*0.1)

3 - Also if you put

angleMode(DEGREES);

from that instruction and below rotate and all instructions that need radians they use degrees… perhaps more comfortable for most humans :wink:

PacMan bites with biteSize x sin(frameCount x 0.1). Use println(sin(frameCount x 0.1)) to see what values are being generated. The sin value goes from negative to positive values in a repeating cycle (sine wave) and that’s what opens and closes the mouth (by changing the start and end angles).

Yes but you can make something go 0.1 from 0 to 30 and then when you arrive to 30 change to -0.1 till you arrive to -30, then change again to 0.1 till arrive to 30. and so on…sorry my bad english but i guess you got the idea…

Im curious were or how you got the idea of using sin and multiply for frameCount…

Now i dont have time but in same editor i got error in variable definitions like float…in the void setup function…and self.title… if i can later or tomorrow i put a screenshot

Post-weekend, swooping back in with some loose thoughts…

  • This whole thread has showed me once again how important it is to know the boundary conditions of a question or task. (Not just in creative coding, but basically anywhere). It was long unclear who this sketch was aimed at or what the end goal for it was. A lot of the back and forth was us talking about the same thing, but with vastly different intentions behind it. It eventually all worked out, though took far more energy and time than necessary.
  • Regarding your course: With what coding background are your students coming into the course and what level do you intend to lift them up to? Based on this I’d opt to leave out certain complex or repetitive topics, e.g. trying to wrangle arc(), and beginning/ending angles into submission is only interesting for so long…
  • PacMan is a great hook as a base theme. I see great opportunity here to let your students creativity soar. ā€œRecreating Pacman as we know itā€ can be a goal. But ā€œInterpreting Pacman in new waysā€ might also be very intriguing. Especially when ā€œanything goesā€.
  • Maybe you can provide a functional but limited base class for your students to use as a jumping off point. They then can implement their own interpretation of how Pacman moves and functions. Some students might opt to make ā€œClassic Pacmanā€ others might do ā€œBizarro World Pacmanā€.
  • Collect all those different Pacmen and let them loose all at once on one stage. (Which is also a great opportunity to teach extended OOP concepts.)
  • Here’s my own interpretation of the waka waka mini-meme: WakaWakaParty. (Mind you, I’m not very well versed with p5.js, so forgive me frankensteining the whole thing together).
  • Lastly, this was a fun one. Thanks all! More of this, please. :slight_smile:
2 Likes

Yes in case you missed…here i have one project of one of my best students… : Rotate arc in pacman animation - #13 by edufissure

The main idea is to implement a nice rotation of pacman, because i used 4 different images looking right up down and up… so if i could get some nice rotation and smooth movement from one direction to another would be great ( also a learning by doing kind of thing)

I still think i could improve the rotation call, the switch in every function moverigth, moveleft, moveup and movedown… and to control more than one key at the same time ( hitting the keyboard)

I think we all made a good job, giving different opinions and ways of code…We can code this animation using arc or using rotate. Using radians or using degrees.

i disagree that was unclear who this sketch was aimed at or end goal, the end goal was as said before make as smooth transition as we can from pacman changing direction look…One the animation was achieved, it was easy to tranlate to different moves/lookings… One i had understand the movement from right to left, it was easy to get the left to right one, left to up, left to down…etc…

I still waiting for sin*framecount answer jejjej

1 Like

Go back and look at your original post. The code in question came from you initially. Apparently it is not original with you, but it works like a charm, in spite of not being intuitively obvious. Using frameCount to control animation is fairly common in Processing. Less obvious is using sin() to get positive and negative values for opening and closing of PacMan’s mouth.

2 Likes