float ballX, ballY;
you never had PVector in your code,
you can use, OK, but why you use if you not like??
somewhere you are supposed to use
hatX = mouseX -45 ; // middle HAT
to limit move must check:
hatX = constrain(mouseX,45,width-45) - 45;
for the draw of all that rectangles use
hatX and not mouseX to make that limit happen,
sorry need to move all rect again.
void drawPuppy() {
hatX = constrain(mouseX, 45, width-45) - 45;
hatY = 400;
fill(0);
rect(hatX, hatY, 90, 10); //HAT
fill(255, 224, 189); //head
rect(hatX+15, hatY+10, 60, 40);
fill(210, 105, 30);
rect(hatX+25, hatY+20, 15, 5); //left eye
rect(hatX+25+20, hatY+20, 15, 5); //right eye
fill(0);
ellipse(hatX+42, hatY+36, 10, 2); //mouth
fill(255, 0, 0);
rect(hatX+25, hatY+50, 40, 20); //body
fill(0);
rect(hatX+35, hatY+70, 5, 10); //legs
rect(hatX+35+15, hatY+70, 5, 10);
}
also the “ball hit hat” logic i would change
( still your pvector )
boolean ballHitsHat() {
// Rectangle and circle collision detection
// if (ballPos.y + ballRadius > hatY && ballPos.x + ballRadius > hatX && ballPos.x + ballRadius < hatX + hatW) {
if (ballPos.y < hatY && ballPos.y + ballRadius > hatY && ballPos.x > hatX && ballPos.x < hatX + hatW) {
ballPos.y = hatY-ballRadius; // anti rebounce
return true;
}
return false;
}
so we are not able to deal with a hit on the hat corner,
( if ball center outside hatX ( + hatW ) )
but that would require real circle // rect collision logic!!!