Skip to content

Instantly share code, notes, and snippets.

@Studio1HQ
Created May 22, 2025 15:32
Show Gist options
  • Select an option

  • Save Studio1HQ/f5deb4c6bf3559a71b12d185961d4637 to your computer and use it in GitHub Desktop.

Select an option

Save Studio1HQ/f5deb4c6bf3559a71b12d185961d4637 to your computer and use it in GitHub Desktop.
3D ping Pong Game by Grok 3
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Tron Ping Pong</title>
<script src="<https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.2/p5.min.js>"></script>
<style>
body {
margin: 0;
background: #111;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
canvas {
border: 2px solid #0ff;
}
</style>
</head>
<body>
<script>
let ball;
let paddles;
let particles = [];
let sparks = [];
function setup() {
createCanvas(800, 600);
ball = {
pos: createVector(width / 2, height / 2),
vel: createVector(random(-5, 5), random(-5, 5)),
r: 10,
color: color(0, 255, 255),
};
paddles = [
{
x: 50,
y: height / 2 - 50,
w: 10,
h: 100,
color: color(255, 0, 255),
score: 0,
speed: 5,
},
{
x: width - 60,
y: height / 2 - 50,
w: 10,
h: 100,
color: color(0, 255, 0),
score: 0,
speed: 5,
},
];
}
function draw() {
// Draw dark grid background
background(10, 10, 20);
stroke(0, 100, 100, 50);
strokeWeight(1);
for (let x = 0; x < width; x += 20) line(x, 0, x, height);
for (let y = 0; y < height; y += 20) line(0, y, width, y);
// Draw arena borders
noFill();
stroke(0, 255, 255);
strokeWeight(4);
rect(10, 10, width - 20, height - 20);
// Update and draw ball
ball.pos.add(ball.vel);
for (let i = 0; i < 2; i++) {
let p = paddles[i];
if (
ball.pos.x - ball.r < p.x + p.w &&
ball.pos.x + ball.r > p.x &&
ball.pos.y > p.y &&
ball.pos.y < p.y + p.h
) {
let hitPos = (ball.pos.y - (p.y + p.h / 2)) / (p.h / 2);
let angle = map(hitPos, -1, 1, -PI / 4, PI / 4);
let speed = ball.vel.mag();
ball.vel
.set(cos(angle) * (i === 0 ? 1 : -1), sin(angle))
.setMag(speed * 1.05);
createSparks(ball.pos.x, ball.pos.y, p.color);
}
}
// Ball wall collisions
if (ball.pos.y - ball.r < 10 || ball.pos.y + ball.r > height - 10) {
ball.vel.y *= -1;
createSparks(ball.pos.x, ball.pos.y, ball.color);
}
// Scoring
if (ball.pos.x < 0) {
paddles[1].score++;
resetBall();
} else if (ball.pos.x > width) {
paddles[0].score++;
resetBall();
}
// Draw ball with glow
noStroke();
fill(ball.color);
ellipse(ball.pos.x, ball.pos.y, ball.r * 2);
fill(255, 255, 255, 100);
ellipse(ball.pos.x, ball.pos.y, ball.r * 1.5);
// Particle trail
particles.push({ pos: ball.pos.copy(), life: 60 });
particles = particles.filter((p) => p.life > 0);
for (let p of particles) {
fill(0, 255, 255, map(p.life, 0, 60, 0, 100));
noStroke();
ellipse(p.pos.x, p.pos.y, 5);
p.life--;
}
// Sparks
sparks = sparks.filter((s) => s.life > 0);
for (let s of sparks) {
fill(s.color, map(s.life, 0, 30, 0, 200));
noStroke();
ellipse(s.pos.x, s.pos.y, s.size);
s.pos.add(s.vel);
s.life--;
}
// Update and draw paddles
if (keyIsDown(87)) paddles[0].y -= paddles[0].speed; // W
if (keyIsDown(83)) paddles[0].y += paddles[0].speed; // S
if (keyIsDown(UP_ARROW)) paddles[1].y -= paddles[1].speed;
if (keyIsDown(DOWN_ARROW)) paddles[1].y += paddles[1].speed;
for (let p of paddles) {
p.y = constrain(p.y, 10, height - p.h - 10);
fill(p.color);
noStroke();
rect(p.x, p.y, p.w, p.h);
fill(255, 255, 255, 100);
rect(p.x, p.y, p.w, p.h * 0.8);
}
// Draw scores
textSize(32);
textAlign(CENTER);
fill(0, 255, 255);
text(paddles[0].score, width / 4, 50);
text(paddles[1].score, (3 * width) / 4, 50);
}
function resetBall() {
ball.pos.set(width / 2, height / 2);
ball.vel.set(random(-5, 5), random(-5, 5));
}
function createSparks(x, y, c) {
for (let i = 0; i < 10; i++) {
sparks.push({
pos: createVector(x, y),
vel: p5.Vector.random2D().mult(random(2, 5)),
size: random(2, 6),
life: 30,
color: c,
});
}
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment