Using ChatGPT to write Pong in the browser
Tags: webdev, javascript, programming, productivity
Published: 2023-03-17 14:07:03

ChatGPT is all over the news at the moment. OpenAI's chat bot is capable of amazing things, but one thing it's shown it is quite adept at is writing code.

There are lots of conversations happening about how ChatGPT will make developers all over the world redundant. I think that's a very, very long way away, but there is no getting away from the productivity benefits it brings for developers of all levels.

As an experiment (full disclosure: I actually saw someone else do this on Twitter so thought I would try it myself!), I thought I would speak to ChatGPT and ask it to recreate the famous game of Pong, but in the browser.

I'm using ChatGPT 4.0, which is the new version that isn't publicly available yet. You will probably get a similar experience with ChatGPT 3.5, but my experience is that there are many more bugs in code produced in 3.5 than in 4.0.

Anyway, let's get started.

> Me: You are DeveloperGPT, an advanced AI developer tool. You answer developer's questions, and respond with useful example code blocks. If you are OK with this, say "Yes Accreditly"

To begin, you always get better results if you tell ChatGPT what context you want. If we tell it that we want it to be a developer and give us code examples, then that's what we get. A good tip is to tell it what to respond with with these kinds of messages, otherwise you'll get an essay about how to be a developer.

> ChatGPT: Yes Accreditly, I'm here to help with your developer questions and provide useful example code blocks. Please feel free to ask anything related to development.

OK, good. Now let's get into it.

> Me: I would like to build a pong game that works in the browser. I want to host it on JSFiddle to show people on dev.to

Again, I've given it a bit of context of what I want to do here. The dev.to bit is irrelevant, but JSFiddle is important, and I'll comment on why shortly.

> ChatGPT: To create a simple Pong game that works in the browser, you can use HTML, CSS, and JavaScript. You can then host your game on JSFiddle and share the link with others.
> 
> Here's a basic implementation:
> HTML:

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Pong Game</title>
    <style>
        /* Add CSS code here */
    </style>
</head>
<body>
    <canvas id="pong" width="600" height="400"></canvas>
    <script>
        // Add JavaScript code here
    </script>
</body>
</html>
```

> 
> CSS

```css
body {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
    background-color: #000;
}

canvas {
    border: 1px solid #fff;
}
```

> JavaScript:
```javascript
const canvas = document.getElementById('pong');
const ctx = canvas.getContext('2d');

canvas.addEventListener('mousemove', (e) => {
    player.y = e.clientY - player.height / 2;
});

const player = {
    x: 10,
    y: canvas.height / 2 - 50,
    width: 10,
    height: 100,
    color: '#fff',
};

const ai = {
    x: canvas.width - 20,
    y: canvas.height / 2 - 50,
    width: 10,
    height: 100,
    color: '#fff',
};

const ball = {
    x: canvas.width / 2,
    y: canvas.height / 2,
    radius: 8,
    color: '#fff',
    speed: 5,
    velocityX: 5,
    velocityY: 5,
};

function drawRect(x, y, width, height, color) {
    ctx.fillStyle = color;
    ctx.fillRect(x, y, width, height);
}

function drawBall(x, y, radius, color) {
    ctx.fillStyle = color;
    ctx.beginPath();
    ctx.arc(x, y, radius, 0, Math.PI * 2, false);
    ctx.closePath();
    ctx.fill();
}

function game() {
    update();
    render();
    requestAnimationFrame(game);
}

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

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

    let paddle = ball.x < canvas.width / 2 ? player : ai;
    if (collision(ball, paddle)) {
        let angle = (Math.random() - 0.5) * Math.PI / 4;
        ball.velocityX = -ball.velocityX * 1.1;
        ball.velocityY = ball.speed * Math.sin(angle);
    }

    if (ball.x - ball.radius < 0) {
        resetBall();
    } else if (ball.x + ball.radius > canvas.width) {
        resetBall();
    }

    ai.y += (ball.y - (ai.y + ai.height / 2)) * 0.1;
}

function collision(b, p) {
    return (
        b.x + b.radius > p.x &&
        b.x - b.radius < p.x + p.width &&
        b.y + b.radius > p.y &&
        b.y - b.radius < p.y + p.height
    );
}

function resetBall()
```

So we've got code split into 3 parts here; HTML, CSS and JavaScript. In my tests ChatGPT only did this when I mentioned JSFiddle, presumably because JSFiddle expects your code to be split out that way. Handy.

You might have noticed the JavaScript seems to have ended without the `resetBall` function being complete. ChatGPT has a cap on character length returned, but it doesn't actually tell you that, it just stops. Let's ask for the rest.

> Me: Can you continue, please?

And now we get the rest.

> ChatGPT: Here's the continuation of the JavaScript code:

```javascript
function resetBall() {
    ball.x = canvas.width / 2;
    ball.y = canvas.height / 2;
    ball.speed = 5;
    ball.velocityX = -ball.velocityX;
    ball.velocityY = (Math.random() - 0.5) * 10;
}

function render() {
    drawRect(0, 0, canvas.width, canvas.height, '#000');
    drawRect(player.x, player.y, player.width, player.height, player.color);
    drawRect(ai.x, ai.y, ai.width, ai.height, ai.color);
    drawBall(ball.x, ball.y, ball.radius, ball.color);
}

game();
```

> With this code, you'll have a basic Pong game that works in the browser. You can now host it on JSFiddle. To do this, follow these steps:
> 1. Visit jsfiddle.net.
> 2. Copy and paste the HTML code (excluding the `<style>` and `<script>` tags) into the HTML panel.
> 3. Copy and paste the CSS code into the CSS panel.
> 4. Copy and paste the JavaScript code into the JavaScript panel.
> 5. Click the "Run" button to see the game in action.
> 6. Click "Save" to generate a shareable link, which you can then share on dev.to.
> Remember to adjust the game's parameters to your liking, such as paddle and ball sizes, colors, and speeds.

And there we have it. A fully working game that works in your browser. It even gave me the step by step instructions for getting it working in JSFiddle.

I've included the JSFiddle below:
{% embed https://jsfiddle.net/accreditly/4tm1gjsd/2/ %}

For the astute among you you might notice a few bugs. It's not perfect - on some screens the bat is a little offset from the mouse, mobile support isn't great, and if you survive for too long the ball goes too fast for the end of game collision mechanism to work. It definitely needs work, but it's certainly most of the way there.