Pong Game in Go Programming Language

 

Introduction

The Pong game is a classic arcade game that simulates table tennis. The objective is to control a paddle and hit a ball back and forth across the screen, preventing the ball from passing your paddle. The game ends when one player fails to hit the ball, and the opponent scores a point. In this tutorial, we will learn how to implement a simple Pong game using the Go programming language, leveraging the github.com/hajimehoshi/ebiten package for rendering and game mechanics.

Objective

The goal of this project is to create a basic Pong game where two players can control paddles, try to score points by bouncing a ball back and forth, and see the result on the screen. You will learn how to set up a Go project, use external libraries for game development, and manage game logic like collision detection and scoring.

Go Pong Game Code


        package main

        import (
            "github.com/hajimehoshi/ebiten/v2"
            "github.com/hajimehoshi/ebiten/v2/ebitenutil"
            "image/color"
            "log"
            "math"
        )

        const (
            screenWidth  = 640
            screenHeight = 480
        )

        type Game struct {
            paddle1Y, paddle2Y float64
            paddleSpeed        float64
            ballX, ballY       float64
            ballDX, ballDY     float64
            score1, score2     int
        }

        func (g *Game) Update() error {
            // Handle paddle movement
            if ebiten.IsKeyPressed(ebiten.KeyW) {
                g.paddle1Y -= g.paddleSpeed
            }
            if ebiten.IsKeyPressed(ebiten.KeyS) {
                g.paddle1Y += g.paddleSpeed
            }
            if ebiten.IsKeyPressed(ebiten.KeyArrowUp) {
                g.paddle2Y -= g.paddleSpeed
            }
            if ebiten.IsKeyPressed(ebiten.KeyArrowDown) {
                g.paddle2Y += g.paddleSpeed
            }

            // Ball movement
            g.ballX += g.ballDX
            g.ballY += g.ballDY

            // Ball collision with top and bottom
            if g.ballY <= 0 || g.ballY >= screenHeight {
                g.ballDY = -g.ballDY
            }

            // Ball collision with paddles
            if (g.ballX <= 10 && g.ballY >= g.paddle1Y && g.ballY <= g.paddle1Y+60) || (g.ballX >= screenWidth-20 && g.ballY >= g.paddle2Y && g.ballY <= g.paddle2Y+60) {
                g.ballDX = -g.ballDX
            }

            // Scoring
            if g.ballX <= 0 { g.score2++ g.resetBall() } else if g.ballX >= screenWidth {
                g.score1++
                g.resetBall()
            }

            return nil
        }

        func (g *Game) resetBall() {
            g.ballX = screenWidth / 2
            g.ballY = screenHeight / 2
            g.ballDX = -g.ballDX
            g.ballDY = 2 * (math.Rand.Float64() - 0.5) * 2
        }

        func (g *Game) Draw(screen *ebiten.Image) {
            screen.Fill(color.Black)

            // Draw paddles
            ebitenutil.DrawRect(screen, 10, g.paddle1Y, 10, 60, color.White)
            ebitenutil.DrawRect(screen, screenWidth-20, g.paddle2Y, 10, 60, color.White)

            // Draw ball
            ebitenutil.DrawRect(screen, g.ballX, g.ballY, 10, 10, color.White)

            // Draw scores
            ebitenutil.DebugPrintAt(screen, "Player 1: "+strconv.Itoa(g.score1), 10, 10)
            ebitenutil.DebugPrintAt(screen, "Player 2: "+strconv.Itoa(g.score2), screenWidth-120, 10)
        }

        func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
            return screenWidth, screenHeight
        }

        func main() {
            g := &Game{
                paddleSpeed: 4,
                ballX:       screenWidth / 2,
                ballY:       screenHeight / 2,
                ballDX:      2,
                ballDY:      2,
            }

            ebiten.SetWindowSize(screenWidth, screenHeight)
            ebiten.SetWindowTitle("Pong Game in Go")
            if err := ebiten.RunGame(g); err != nil {
                log.Fatal(err)
            }
        }
        

Program Structure and How to Run the Program

This Pong game is structured into different sections to handle game mechanics, rendering, and user inputs:

  • Game struct: This holds the variables like paddle positions, ball position, speed, and scores.
  • Update method: This handles the main game logic like paddle movement, ball movement, collision detection, and scoring.
  • Draw method: This renders the paddles, ball, and score on the screen.
  • resetBall method: This resets the ball’s position after a point is scored.
  • Main function: This initializes the game and runs the game loop using the Ebiten library.

To run the program:

  1. Ensure you have Go installed on your system.
  2. Install the Ebiten library with the command: go get github.com/hajimehoshi/ebiten/v2
  3. Create a new Go file and paste the code provided above.
  4. Run the program with the command: go run .go

The game will open in a new window where you can use the W/S keys to move the left paddle and the Up/Down Arrow keys to move the right paddle. The ball will bounce back and forth between the paddles, and you will score a point when the ball passes the opponent’s paddle.

© 2025 Learn Programming

 

Leave a Reply

Your email address will not be published. Required fields are marked *