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