Skip to content

Commit

Permalink
Ping Ball Game (#127)
Browse files Browse the repository at this point in the history
## Related Issue #109 

[Cite any related issue(s) this pull request addresses. If none, simply
state "None”]
write issue no. here

## Email id used to regsiter for VSoc'24: monishr608@gmail.com


## Description

[Please include a brief description of the changes or features added]

## Type of PR

- [ ] Bug fix
- [ ] Feature enhancement
- [ ] Documentation update
- [ ] Security enhancement
- [ ] Other (specify): _______________


check in issue by entering [X] in boxes

## Screenshots / Videos (if applicable)




https://github.com/dhairyagothi/50_days_50_web_project/assets/140420819/76a8fc58-6928-44dd-a012-47c51bee41ad





[Attach any relevant screenshots or videos demonstrating the changes]

## Checklist
- [ ] I have performed a self-review of my code.
- [ ] I have read and followed the Contribution Guidelines.
- [ ] I have tested the changes thoroughly before submitting this pull
request.
- [ ] I have provided relevant issue numbers, screenshots, and videos
after making the changes.
- [ ] I have commented my code, particularly in hard-to-understand
areas.
- [ ] I have followed the code style guidelines of this project.
- [ ] I have checked for any existing open issues that my pull request
may address.
- [ ] I have ensured that my changes do not break any existing
functionality.
- [ ] Each contributor is allowed to create a maximum of 4 issues per
day. This helps us manage and address issues efficiently.
- [ ] I have read the resources for guidance listed below.
- [ ] I have followed security best practices in my code changes.

check in issue by entering [X] in boxes
## Additional Context

[Include any additional information or context that might be helpful for
reviewers.]




## Contribution Guidelines

Thank you for considering contributing to our project! To ensure smooth
collaboration and effective contribution management, please adhere to
the following guidelines:

### Issue Creation

1. **Limit on Issues:**
- Each contributor is allowed to create a maximum of **4 issues per
day**. This helps us manage and address issues efficiently.

### Contribution Levels

2. **Basic Contributions:**
- This project is primarily focused on documentation. Most of the setup
has been completed, so contributors will generally need to work on basic
code tasks, such as writing tests.
   - For these tasks, issues will be assigned the **Easy** label.

3. **Acknowledging Hard Work:**
- If a contributor puts in significant effort on a task, the issue will
be upgraded to **Medium**. This is our way of recognizing and
appreciating extra effort.

4. **Feature Additions and Component Work:**
- Contributors working on new features or components using JSX/TSX will
be assigned a level based on the complexity and quality of their work.
- The more complex and valuable the contribution, the higher the level
assigned.

### Level Definitions

- **Easy:**
- Tasks are straightforward, such as fixing minor bugs, writing tests,
or making simple documentation updates.
- **Medium:**
- Tasks require more effort, such as addressing complex bugs, improving
existing features, or making substantial documentation improvements.
- **Hard:**
- Tasks are highly complex and involve significant new feature
development, major refactoring, or extensive contributions to the
project’s core components.

We look forward to your contributions and appreciate your effort in
helping us improve the project!
  • Loading branch information
dhairyagothi authored Jun 20, 2024
2 parents b41afcf + 7ef4897 commit 9485723
Show file tree
Hide file tree
Showing 4 changed files with 327 additions and 3 deletions.
6 changes: 3 additions & 3 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -264,9 +264,9 @@
<a href="Palindrome_Generator/index.html" class="demo-link">Demo</a>
</div>
<div class="table">
<div class="day-number">Day 47</div>
<div class="project-name">Budget Tracker</div>
<a href="Budget Tracker/index.html" class="demo-link">Demo</a>
<div class="day-number">Day 48</div>
<div class="project-name">Ping Pong Game</div>
<a href="ping/index.html" class="demo-link">Demo</a>
</div>
</div>

Expand Down
24 changes: 24 additions & 0 deletions public/ping/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<script src="script.js" defer></script>
<title>Ping Pong Game</title>
</head>
<body>
<div class="header">
<img src="https://img.freepik.com/premium-vector/table-tennis-vector-logo-ping-pong-ball-with-emblem-shape-perfect-table-tennis_297778-950.jpg" alt="logo" width="60px">
<div class="buttons">
<button class="start-btn">Start</button>
<button class="pause-btn">Pause</button>
<button class="restart-btn">Restart</button>
</div>
</div>

<div class="pong-wrapper">
<canvas id="ping-pong" width="600px" height="400px"></canvas>
</div>
</body>
</html>
230 changes: 230 additions & 0 deletions public/ping/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
const canvas = document.querySelector("#ping-pong");

const context = canvas.getContext("2d");

const startBtn = document.querySelector(".start-btn");

const pauseBtn = document.querySelector(".pause-btn");

const restartBtn = document.querySelector(".restart-btn");

let gameRunning = false;

let animationId;

//CREATE USER PADDLE
const user = {
x: 0,
y: canvas.height/2 - 100/2,
width: 10,
height: 100,
color: "red",
score: 0
}

//CREATE COMPUTER PADDLE
const computer = {
x: canvas.width - 10,
y: canvas.height/2 - 100/2,
width: 10,
height: 100,
color: "black",
score: 0
}

//CREATE THE BALL
const ball = {
x: canvas.width / 2,
y: canvas.height / 2,
radius: 10,
speed: 10,
velocityX: 5,
velocityY: 5,
color: "white"
}

//CREATE THE NET
const net = {
x: canvas.width/2 - 1,
y: 0,
width: 2,
height: 10,
color: "white"
}

restartBtn.addEventListener("click", () => {
document.location.reload();
});

addEventListener("load", (event) => {
render();
});

//DRAW NET FUNCTION
function drawNet() {
const netWidth = 4; // Adjust the net width as needed
const netSpacing = 15; // Adjust the spacing as needed

// Draw the left half of the net
for (let i = 0; i <= canvas.height; i += netSpacing) {
drawRectangle(net.x, net.y + i, netWidth, net.height, net.color);
}

// Draw the right half of the net
for (let i = 0; i <= canvas.height; i += netSpacing) {
drawRectangle(net.x + net.width - netWidth, net.y + i, netWidth, net.height, net.color);
}
}


//DRAW RECTANGLE FUNCTION
function drawRectangle(x, y, w, h, color) {
context.fillStyle = color;
context.fillRect(x, y, w, h);
}

//DRAW CIRCLE FUNCTION
function drawCircle(x, y, r, color) {
context.fillStyle = color;
context.beginPath();
context.arc(x, y, r, 0, Math.PI * 2, false);
context.closePath();
context.fill();
}

//DRAW TEXT FUNCTION
function drawText(text, x, y, color) {
context.fillStyle = color;
context.font = "45px fantasy";
context.fillText(text, x, y);
}

//RENDER GAME FUNCTION
// Inside the render() function
function render() {
// CLEAR THE CANVAS
drawRectangle(0, 0, canvas.width, canvas.height, "green");

// DRAW THE NET
drawNet();

// DRAW THE SCORE
drawText(user.score, canvas.width / 4, canvas.height / 5, "white");
drawText(computer.score, (3 * canvas.width) / 4, canvas.height / 5, "white");

// DRAW THE USER AND COMPUTER PADDLES
drawRectangle(user.x, user.y, user.width, user.height, user.color);
drawRectangle(computer.x, computer.y, computer.width, computer.height, computer.color);

// DRAW THE BALL
drawCircle(ball.x, ball.y, ball.radius, ball.color);

// DRAW THE WHITE LINE IN THE MIDDLE
drawRectangle(net.x, net.y, net.width, canvas.height, net.color);
}

//CONTROL USERS PADDLE
canvas.addEventListener("mousemove", movePaddle);

function movePaddle(evt) {
let rectangle = canvas.getBoundingClientRect();

user.y = evt.clientY - rectangle.top - user.height/2;
}

//COLLISION DETECTION FUNCTION
function collision(b, p) {
b.top = b.y - b.radius;
b.bottom = b.y + b.radius;
b.left = b.x - b.radius;
b.right = b.x + b.radius;

p.top = p.y;
p.bottom = p.y + p.height;
p.left = p.x;
p.right = p.x + p.width;

return b.right > p.left && b.bottom > p.top && b.left < p.right && b.top < p.bottom;
}

//RESET BALL FUNCTION
function resetBall() {
ball.x = canvas.width / 2;
ball.y = canvas.height / 2;

ball.speed = 5;
ball.velocityX = -ball.velocityX;
}

//UPDATE FUNCTION
function update() {
ball.x += ball.velocityX;
ball.y += ball.velocityY;

//SIMPLE AI TO CONTROL THE COMPUTER PADDLE
let computerLevel = 0.1;
computer.y += (ball.y - (computer.y + computer.height/2)) * computerLevel;

if(ball.y + ball.radius > canvas.height || ball.y - ball.radius < 0) {
ball.velocityY = -ball.velocityY;
}

let player = (ball.x < canvas.width/2) ? user : computer;

if(collision(ball, player)) {
//WHERE THE BALL HIT THE PLAYER
let collidePoint = ball.y - (player.y + player.height/2);

//NORMALIZATION
collidePoint = collidePoint / (player.height/2);

//CALCULATE THE ANGLE IN RADIAN
let angleRad = collidePoint * Math.PI/4;

//X DIRECTION OF THE BALL WHEN IT'S HIT
let direction = (ball.x < canvas.width/2) ? 1 : -1;


//CHANGE VELOCITY OF X AND Y
ball.velocityX = direction * ball.speed * Math.cos(angleRad);

ball.velocityY = ball.speed * Math.sin(angleRad);

//Everytime a ball is hit by a paddle, we increase its speed
ball.speed += 0.5;
}
//UPDATE THE SCORE
if(ball.x - ball.radius < 0) {
//THE COMPUTER GAINS 1 POINT
computer.score++;
resetBall();
} else if(ball.x + ball.radius > canvas.width){
//THE USER GAINS 1 POINT
user.score++;
resetBall();
}
}

//GAME INITIALIZATION FUNCTION
function animate() {
if(!gameRunning) {
return; // Don't continue the animation if it's paused
}

update();
render();
animationId = requestAnimationFrame(animate);
}


startBtn.addEventListener("click", () => {
if (!gameRunning) {
gameRunning = true;
animate();
}
});

pauseBtn.addEventListener("click", () => {
gameRunning = false;
cancelAnimationFrame(animationId);
});
70 changes: 70 additions & 0 deletions public/ping/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}

body{
background-color: darkgrey;
}

.header {
display: flex;
align-items: center;
justify-content: space-around;
padding: 0.1em;
margin-top: 0.1em;
background-color: green;
}

.header img {
width: 60px;
}

.buttons button {
letter-spacing: 2px;
text-transform: uppercase;
border: none;
color: white;
background-color: green;
padding: 10px;
letter-spacing: 1px;
font-size: 1em;
font-weight: bold;
font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;
}

.buttons button:hover {
text-decoration: underline;
font-size: 1.05em;
}

.pong-wrapper {
display: flex;
justify-content: center;
align-items: center;
margin-top: 3em;
}

#ping-pong {
width: 80%;
max-width: 680px;
border: 12px solid white;
}

@media screen and (max-width: 480px) {
.header img {
width: 40px;
}
.buttons button {
letter-spacing: 1px;
padding: 5px;
letter-spacing: 1px;
font-size: 0.7em;
}

.buttons button:hover {
text-decoration: underline;
font-size: 1.05em;
}
}

0 comments on commit 9485723

Please sign in to comment.