I am creating(or recreating) a classic style game for a final project for my art school class. Coding is new. I am about 8 months into learning it so, everything is still in "training-wheel" mode for me. I think the game was called paddle ball. It is like pong but with one "ball" and one "paddle" the ball bounced off the top and side. The player tried to return the ball with the paddle and if it goes past, the player loses and the game restarts.
THe problem I am having is the when the ball come in contact with the paddle, in has suddenly been getting stuck and not bounding back. If the paddle stays in contact, it rapidly raises the "score". Also, now the paddle is moving on the y axis then it is supposed to be fixed and only move on the x axis.
I have been fiddling with it so much, I am sure I accidently save over something I didn't intend to.
Could someone please take a peek and show me how to fix it back to working again?
Here is a link to the code (runswithout errors here): https://editor.p5js.org/Rico2022/sketches/YIOKSbFWu
Below I will put the code as well:
// Requirement 1: Load Sound
let sound;
function preload() {
//sound = loadSound('metalPing4.mp3');
}
// Requirement 7: Define a custom class
class Ball {
constructor(x, y, r) {
this.x = x;
this.y = y;
this.r = r;
this.xSpeed = random(2, 7) * (random() > 0.5 ? 1 : -1);
this.ySpeed = random(-7, -2);
}
move() {
this.x += this.xSpeed;
this.y += this.ySpeed;
}
display() {
fill('#D9FFF5');
ellipse(this.x, this.y, this.r * 2, this.r * 2);
}
bounce() {
if (this.x < this.r || this.x > width - this.r) {
this.xSpeed *= -1;
}
if (this.y < this.r || this.y > height - this.r) {
this.ySpeed *= -1;
}
}
}
let ball;
let score = 0;
let gameState = "start";
function setup() {
createCanvas(400, 400);
ball = new Ball(random(50, 350), 50, 10);
}
function draw() {
background(0);
if (gameState === "start") {
titleScreen();
} else if (gameState === "playing") {
playGame();
} else if (gameState === "playAgain") {
playAgainScreen();
}
}
function titleScreen() {
fill('#d9c3f7');
textSize(32);
textAlign(CENTER);
text("Paddle Ball Game", width / 2, height / 2 - 40);
textSize(24);
text("Click to Start", width / 2, height / 2);
}
function playGame() {
// Requirement 5: Use sin or cos
let paddleY = height - 25 - 15 * sin(radians(frameCount % 360));
// Paddle
fill('#ffffff');
rect(mouseX, paddleY, 90, 15);
ball.move();
ball.display();
ball.bounce();
paddleCollision(paddleY);
//Score
fill('#d9c3f7');
textSize(24);
text("Score: " + score, 10, 25);
}
function playAgainScreen() {
fill('#d9c3f7');
textSize(32);
textAlign(CENTER);
text("Game Over", width / 2, height / 2 - 40);
textSize(24);
text("Click to Play Again", width / 2, height / 2);
}
function mousePressed() {
if (gameState === "start") {
gameState = "playing";
} else if (gameState === "playAgain") {
gameState = "playing";
score = 0;
ball = new Ball(random(50, 350), 50, 10);
}
}
// Requirement 6: Create and use your own function
function paddleCollision(paddleY) {
if (ball.x > mouseX && ball.x < mouseX + 90 && ball.y + ball.r >= paddleY) {
// Requirement 2: Play Sound
//sound.play();
// Requirement 4: Use of map()
let angle = map(ball.x, mouseX, mouseX + 90, -PI / 4, PI / 4);
ball.xSpeed = ball.xSpeed * cos(angle) * 1.05;
ball.ySpeed = -abs(ball.ySpeed) * sin(angle) * 1.05;
// Requirement 10: Event on Collision
score++;
}
}
// Requirement 3: Use random
function randomBgColor() {
let r = random(0, 255);
let g = random(0, 255);
let b = random(0, 255);
return color(r, g, b);
}
function titleScreen() {
//background(randomBgColor());
background(107, 143, 113);
fill('#d9c3f7');
textSize(32);
textAlign(CENTER);
text("Paddle Ball Game", width / 2, height / 2 - 40);
textSize(24);
text("Click to Start", width / 2, height / 2);
}
function playGame() {
// Requirement 5: Use sin or cos
let paddleY = height - 25 - 15 * sin(radians(frameCount % 360));
// Paddle
fill('#AAD2BA');
rect(mouseX, paddleY, 90, 15);
ball.move();
ball.display();
ball.bounce();
paddleCollision(paddleY);
//Score
fill('#d9c3f7');
textSize(24);
text("Score: " + score, 60, 25);
// Requirement 12: Playability
if (ball.y + ball.r >= height) {
gameState = "playAgain";
}
}
function playAgainScreen() {
//background(randomBgColor());
background(185, 245, 216);
fill('#d9c3f7');
textSize(32);
textAlign(CENTER);
text("Game Over", width / 2, height / 2 - 40);
textSize(24);
text("Click to Play Again", width / 2, height / 2);
}
// Requirement 11: User Input
function keyPressed() {
if (key === 'P' || key === 'p') {
if (gameState === "playing") {
gameState = "paused";
} else if (gameState === "paused") {
gameState = "playing";
}
}
}
html, body {
margin: 0;
padding: 0;
}
canvas {
display: block;
}
</script>
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/addons/p5.sound.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
<meta charset="utf-8" />
</head>
<body>
<main>
</main>
<script src="sketch.js"></script>
</body>
</html>
The problem is that you are changing ball's both speeds(x,y) during the collision with
sin,cosfunctions, whereas you have to changeyspeed. The origin of the coordinates is in the top left corner. As the paddle is always at the bottom, it means during the collision, you have to changeyto a positive value, which can be done as follows:editor
Also, since the paddle also moves along the
yaxis, you may have collision triggered several times, which would spam the score. We can be confident that in the ideal case, the ball can't collide with the paddle two times in a row. Therefore, we will add a boolean flag that indicates if the previous collision was with the paddle or not. The initial value should be false:Then in the
ball.bounce(), if we touch the borders we will set theisLastCollisionWithPaddleto false:The remaining part is to make sure that we only change the speed and score if and only if the previous collision wasn't with the paddle:
editor