First person camera help

i’ve edited some code i found for a first person camera but cant figure out how to rotate y axis well inside the matrix and also how to stop the block from jittering around when i move the camera. any help would be appreciated

FPCamera mainCamera;

// Enables all camera transformations.
boolean cameraEnabled = false;

void setup() {
  size(1280, 600, P3D);
  // Creates a new camera.
  mainCamera = new FPCamera();
  // Camera transformations are enabled.
  cameraEnabled = true;
}

void draw() {
  background(0);

  // Tells the program that boolean cameraEnabled controls camera transformations.
  if (cameraEnabled == true) {
    mainCamera.camTransformations();
    // Updates and stores the cameras position every frame.
    //debugCamPos();
  }
  // Just some blocks so i can see things move.
  renderEnvironment();
}

// Creats a ground plain.
void renderEnvironment() {
  // number of boxes that are placed along each axis (X and Z only) to form the ground plain.
  int boxNumberPerAxis = 25;

  fill(198, 101, 35);
  // Forming the celling plain.
  for (int z = 0; z < boxNumberPerAxis; z++ ) {
    for (int x = 0; x < boxNumberPerAxis; x++) {
      block(x*50, 0, z*50, 50);
    }
  }

  // Forming the ground plain.
  fill(105, 88, 114);
  for (int z = 0; z < boxNumberPerAxis; z++ ) {
    for (int x = 0; x < boxNumberPerAxis; x++) {
      block(x*50, height-height/3, z*50, 50);
    }
  }
}


class FPCamera {

  // The Main camera's position.
  PVector cameraPosition;

  FPCamera() {
    cameraPosition = new PVector(width/2, height/2+50, (height/2) / tan(PI*30 / 180));
  }



  // All transformations applyed to the camera are here.
  void camTransformations() {

    // Camera rotations.
    pushMatrix();
    translate(cameraPosition.x, cameraPosition.y, cameraPosition.z);

    // Side to side movment
    rotateY(-mouseX*0.01);

    translate(0, 0, -200);
    box(50);

    float x = modelX(0, 0, 0);
    float y = modelY(0, 0, 0);
    float z = modelZ(0, 0, 0);
    popMatrix();
    y = map(mouseY, 0, height, -200, 1200);


    // Up and down movment.
    //y = map(mouseY, 0, height, -200, 1200);
    println(y);

    camera(cameraPosition.x, cameraPosition.y, cameraPosition.z, x, y, z, 0, 1, 0);
    println(x);
    println(y);
    println(z);

    // Camera positional movment.
  }
}


void block(float x, float y, float z, float s){
  pushMatrix();
  translate(x, y, z);
  box(s);
  popMatrix();
}

I was looking for resources on how to make a first-person camera myself a while ago and made a sketch with a working one. The way I did it was tracking the direction using pitch and yaw values, then executing translate(camX, camY, camZ), rotateY(yaw) and rotateX(pitch) in that order to position and orient the camera. I also make sure to always keep the pitch value clamped between -pi/2 and pi/2 so there is not confusing upside-down camera. In addition, I use some funky imports to hide the mouse and set its position to the center of the screen, then use the change in mouseX and mouseY every frame to change the yaw and pitch of the camera.
The Camera Class is actually a 3rd person camera, but with a small distance, it essentially becomes first-person.

public class Camera {
  private PVector focus, prevFocus; // world position of where the camera should look
  private float glide; //internal value for gliding from one focus to another, used for cutscenes and stuff
  float yaw, pitch, distance, glideRate;
  float fov, aspect, zNear, zFar; // camera settings
  public Camera() {
    prevFocus = new PVector(0, 0, 0);
    focus = new PVector(0, 0, 0);
    glide = 1;
    glideRate = 0.005;
    yaw = 0;
    pitch = HALF_PI;
    distance = 1;
    fov = radians(80);
    zNear = 1;
    zFar = 65536;
  }
  public PVector getPosition() {
    PVector tempFocus = PVector.lerp(prevFocus, focus, glideValue()); //glideValue applies a logistic curve to the normally linearly changing glide value to make it smoother.
    return new PVector(distance * sin(yaw) * cos(pitch) + tempFocus.x, distance * -sin(pitch) + tempFocus.y, distance * cos(yaw) * cos(pitch) + tempFocus.z);
  }
  public PVector getOrientation() {
    return PVector.sub(focus, getPosition()).normalize();
  }
  // for instantaneous movement or for movement that occurs every frame
  public void setFocus(PVector newFocus) {
    prevFocus = focus.copy();
    focus = newFocus.copy();
    glide = 1;
  }
  // for smooth movement. It is best not to interrupt this by checking when the glide value != 1 with isGliding().
  public void glideToFocus(PVector newFocus) {
    prevFocus = focus.copy();
    focus = newFocus.copy();
    glide = 0;
  }
  private float glideValue() {
    float e = exp(20 * (glide - 0.5));
    return (e / (1 + e));
  }
  public boolean isGliding() {
    return glide != 1;
  }
  public void render() {
    if (glide < 0) glide = 0;
    if (glide < 1) {
      glide += glideRate;
    }
    if (glide > 1) glide = 1;
    clampValues();
    PVector pos = getPosition();
    PVector tempfocus = PVector.lerp(prevFocus, focus, glideValue());
    perspective(fov, float(width)/float(height), zNear, zFar);
    camera(pos.x, pos.y, pos.z, tempfocus.x, tempfocus.y, tempfocus.z, 0, 1, 0);
  }
  public void clampValues() {
    if (distance <= 0) {
      distance = 1;
    }
    if (pitch <= -HALF_PI)
      pitch = -HALF_PI + 0.0001;
    if (pitch >= HALF_PI)
      pitch = HALF_PI - 0.0001;
    while (yaw < 0 || yaw >= TAU) {
      if (yaw < 0)
        yaw += TAU;
      if (yaw >= TAU)
        yaw -= TAU;
    }
  }
  public String toString() {
    return "Pitch: " + pitch + "\nYaw: " + yaw + "\nZoom: " + distance + "\nfov: " + degrees(fov) + "\nnearClip: " + zNear + "\nfarClip: " + zFar;
  }
}

The driver class has all the code necessary to drive the camera, and includes features like deltaTime which allows you to have framerate-independent code, and full-axis movement so you can explore the scene.

import com.jogamp.newt.opengl.GLWindow; //used for funky mouse position and hiding stuff

PVector camfocus; //3D coordinates of the target
Camera maincam;
//deltaTime is in seconds
float deltaTime;
long ptime;
//mouse control
boolean Lock;
GLWindow r;
float Sensitivity;
int offsetX=0;
int offsetY=0; 
PVector oldMouse;
//player control
boolean w, a, s, d, space, shift;
// more efficient environment
PShape env;
void setup() {
  size(1600, 900, P3D); // 1600 x 900 pog
  frameRate(75);
  r=(GLWindow)surface.getNative(); //for the funky
  Lock = false;
  Sensitivity = 0.5;
  oldMouse = new PVector(mouseX, mouseY);
  camfocus = new PVector(0, 50, 0);
  maincam = new Camera();
  maincam.yaw = 5 * PI/4.0;
  maincam.distance = 2; //Camera is actually a 3rd person camera, but at distances as short as 2, it's basically first person. Distance cannot be negative.
  ptime = 0;
  env = createEnvironment();
}

void draw() {
  //time update
  long curTime = System.nanoTime();
  deltaTime = (curTime - ptime) * 0.000000001; //converts nanoseconds to seconds as a float
  ptime = curTime;
  // If you multiply time sensitive actions by deltaTime, the time it takes for that action to complete becomes independent of framerate!
  // mouse shenanigans are not by me originally, but I don't remember which forum user showed me this
  if (Lock) {
    r.setPointerVisible(false); //When locked and trying to move, the pointer jerks all over the place, so best to hide it.
    r.warpPointer(width/2, height/2); //Move it to the exact center of the sketch window.
    r.confinePointer(true); //Locks pointer inside of the sketch's window so it doesn't escape.
    //The pointer will still hit the window's edges, limiting moves fast enough.
    //But as soon as the pointer is outside of the window it's visible until it's
    //teleported back inside the window, which is less preferable.
  } else {
    r.confinePointer(false); 
    r.setPointerVisible(true);
  } //Else undo that stuff.
  if (Lock) {
    maincam.yaw -= (mouseX-offsetX-width/2)*Sensitivity*deltaTime;
    maincam.pitch += (mouseY-offsetY-height/2)*Sensitivity*deltaTime;
  } //If lock, then adjust position...
  offsetX=offsetY=0; // used to store mouse position when mouse is not locked. This prevents the camera from looking to a new location when the mouse becomes locked again
  float moveSpeed = 420.69; // heh
  if(w){
    camfocus = camfocus.add(PVector.mult(maincam.getOrientation(), moveSpeed * deltaTime));
  }
  if(a){
    camfocus = camfocus.add(moveSpeed * deltaTime * -cos(maincam.yaw), 0, moveSpeed * deltaTime * sin(maincam.yaw));
  }
  if(s){
    camfocus = camfocus.add(PVector.mult(maincam.getOrientation(), -moveSpeed * deltaTime));
  }
  if(d){
    camfocus = camfocus.add(moveSpeed * deltaTime * cos(maincam.yaw), 0, moveSpeed * deltaTime * -sin(maincam.yaw));
  }
  if(space){
    camfocus = camfocus.add(0, -moveSpeed * deltaTime, 0);
  }
  if(shift){
    camfocus = camfocus.add(0, moveSpeed * deltaTime, 0);
  }
  maincam.setFocus(camfocus); //sets new camera position
  maincam.render();
  background(0);
  //renderEnvironment();
  shape(env); //using a pre-computed PShape significantly improves real-time performance
}

// Creats a ground plane out of boxes.
void renderEnvironment() {
  // number of boxes that are placed along each axis (X and Z only) to form the ground plain.
  int boxNumberPerAxis = 25;

  fill(198, 101, 35);
  // Forming the celling plain.
  for (int z = 0; z < boxNumberPerAxis; z++ ) {
    for (int x = 0; x < boxNumberPerAxis; x++) {
      block(x*50, 0, z*50, 50);
    }
  }

  // Forming the ground plain.
  fill(105, 88, 114);
  for (int z = 0; z < boxNumberPerAxis; z++ ) {
    for (int x = 0; x < boxNumberPerAxis; x++) {
      block(x*50, height * (2.0/3.0), z*50, 50);
    }
  }
}


void block(float x, float y, float z, float s){
  pushMatrix();
  translate(x, y, z);
  box(s);
  popMatrix();
}

PShape createEnvironment() {
  PShape out = createShape(GROUP);
  // number of boxes that are placed along each axis (X and Z only) to form the ground plane.
  int boxNumberPerAxis = 25;

  fill(198, 101, 35);
  // Forming the ceiling plane.
  for (int z = 0; z < boxNumberPerAxis; z++ ) {
    for (int x = 0; x < boxNumberPerAxis; x++) {
      PShape child = createShape(BOX, 50);
      child.translate(x*50,0,z*50);
      child.setFill(color(198, 101, 35));
      out.addChild(child);
    }
  }

  // Forming the ground plain.
  fill(105, 88, 114);
  for (int z = 0; z < boxNumberPerAxis; z++ ) {
    for (int x = 0; x < boxNumberPerAxis; x++) {
      PShape child = createShape(BOX, 50);
      child.translate(x*50,height * (2.0/3.0),z*50);
      child.setFill(color(105, 88, 114));
      out.addChild(child);
    }
  }
  return out;
}

void keyPressed() {
  if(key == 'w' || key == 'W'){
    w = true;
  }
  if(key == 'a' || key == 'A'){
    a = true;
  }
  if(key == 's' || key == 'S'){
    s = true;
  }
  if(key== 'd' || key == 'D'){
    d = true;
  }
  if(keyCode == SHIFT){
    shift = true;
  }
  if(key == ' '){
    space = true;
  }
  if (key == 'e') {
    if (!Lock) {
      oldMouse = new PVector(mouseX, mouseY);
      offsetX = mouseX - width/2;
      offsetY = mouseY - height/2;
    }
    if (Lock) {
      r.warpPointer((int) oldMouse.x, (int) oldMouse.y);
    }
    Lock = !Lock;
  }
  if (key == 'v') {
    maincam.fov = radians(20);
    Sensitivity *= 0.125;
  }
}
void keyReleased() {
  if(key == 'w' || key == 'W'){
    w = false;
  }
  if(key == 'a' || key == 'A'){
    a = false;
  }
  if(key == 's' || key == 'S'){
    s = false;
  }
  if(key== 'd' || key == 'D'){
    d = false;
  }
  if(keyCode == SHIFT){
    shift = false;
  }
  if(key == ' '){
    space = false;
  }
  if (key == 'v') {
    maincam.fov = radians(80);
    Sensitivity *= 8;
  }
}
void mousePressed() {
  if (!Lock) {
    oldMouse = new PVector(mouseX, mouseY);
    offsetX = mouseX - width/2;
    offsetY = mouseY - height/2;
    Lock = true;
  }
}
void mouseWheel(MouseEvent event) {
  float e = event.getCount();
  maincam.fov += (PI/180) * e;
}