Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
KalebHawkins committed Jun 23, 2024
0 parents commit c1be082
Show file tree
Hide file tree
Showing 11 changed files with 329 additions and 0 deletions.
Binary file added assets/EmpireStateNF.ttf
Binary file not shown.
Binary file added assets/background.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions assets/embed.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package assets

import (
_ "embed"
)

var (
//go:embed EmpireStateNF.ttf
EmpireStateNF_ttf []byte

//go:embed background.png
Background []byte
)
54 changes: 54 additions & 0 deletions docs/GameDesignDoc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Pong: Game Design Document

## Introduction

This document outlines the design for a classic Pong game. Pong is a simple yet addictive two-dimensional table tennis video game. The objective is to defeat your opponent (or the AI) by deflecting a ball with a paddle and preventing it from reaching your goal.

## Gameplay

**Core Mechanic:** Players control paddles on opposite sides of a rectangular playing field. They use the paddles to deflect a moving ball and prevent it from entering their goal area.

**Scoring:** A point is awarded to the player who fails to deflect the ball, allowing it to pass their paddle and reach the goal area.

**Winning:** The first player to reach a predetermined score wins the game.

## Game Features

**Singleplayer:** Play against a computer-controlled opponent with adjustable difficulty levels.

**Multiplayer:** Option for two players to compete locally on the same device.

**Controls:** Players use keyboards or joysticks to move their paddles up and down. Simple one-button controls (up/down or left/right for paddles) are ideal.

**Visuals:** Simple 2D graphics with a clean and minimalist aesthetic. The playing field, paddles, and ball will be represented by basic shapes.

**Audio:** Basic sound effects for ball collisions with paddles and walls, and scoring events. Optional background music with low intensity to avoid distraction.

**Difficulty:** Adjustable AI difficulty for the single-player mode, allowing players of various skill levels to enjoy the game.

## Technical Specifications

**Platform:** This game can be developed for various platforms, including PC, mobile devices (iOS and Android), and web browsers. The chosen platform will determine the specific programming languages and tools used.

**Graphics:** 2D vector graphics are ideal for a clean and scalable visual style.
Physics: Simple collision detection between the ball, paddles, and walls will be implemented to govern ball movement.

## Target Audience

Pong is a casual game targeted towards a broad audience. Its simple mechanics and easy-to-understand gameplay make it enjoyable for players of all ages and gaming experience levels.

## Monetization (Optional)

This version of Pong can be completely free-to-play.

For future versions, optional in-app purchases for cosmetic customization of paddles or visual themes can be considered.

## Future Considerations

**Power-Ups:** Introduce temporary power-ups that appear on the field during gameplay, granting players temporary advantages like paddle size increase, speed boost, or ball deflection manipulation.

**Game Modes:** Include additional game modes like variations in field size, multiple balls, or wrapped edges where the ball can bounce off the sides and continue play.

**Online Multiplayer:** Implement online multiplayer functionality for players to compete across a network.

This Game Design Document provides a basic framework for the development of a Pong game. The features and technical specifications can be expanded upon to create a more engaging and feature-rich experience.
47 changes: 47 additions & 0 deletions docs/GameObjects.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
```mermaid
---
title: Game Objects
---
classDiagram
class Game {
+ Cfg Cfg
+ state state
+ playerOne paddle
+ playerTwo paddle
+ ball ball
+ background *ebiten.Image
+ Update() error
+ Draw(*ebiten.Image)
+ Layout(int, int) int int
+ Run() error
+ Reset()
+ drawMainMenu(screen *ebiten.Image)
}
class Cfg {
+screenWidth int
+screenHeight int
+WindowTitle string
faceSource *text.GoTextFaceSource
}
class paddle {
+ int x
+ int y
+ int dx
+ *ebiten.Image
+ int score
}
class ball {
+ int x
+ int y
+ int dx
+ int dy
+ *ebiten.Image
}
```
31 changes: 31 additions & 0 deletions docs/GameStates.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
```mermaid
---
title: Game State Document
---
stateDiagram-v2
state "Main Menu" as main
state "Game Loop" as gameLoop
state "Paused" as pause
state "Game Over" as gameOver
state numPlayers <<choice>>
state restartQuit <<choice>>
[*] --> main
main --> numPlayers
numPlayers --> OnePlayer
numPlayers --> TwoPlayer
OnePlayer --> gameLoop
TwoPlayer --> gameLoop
gameLoop --> pause
pause --> gameLoop
gameLoop --> gameOver
gameOver --> restartQuit
restartQuit --> Quit
restartQuit --> Restart
Restart --> main
Quit --> [*]
17 changes: 17 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module gtihub.com/KalebHawkins/pong

go 1.22.3

require github.com/hajimehoshi/ebiten/v2 v2.7.5

require (
github.com/ebitengine/gomobile v0.0.0-20240518074828-e86332849895 // indirect
github.com/ebitengine/hideconsole v1.0.0 // indirect
github.com/ebitengine/purego v0.7.0 // indirect
github.com/go-text/typesetting v0.1.1-0.20240325125605-c7936fe59984 // indirect
github.com/jezek/xgb v1.1.1 // indirect
golang.org/x/image v0.16.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.20.0 // indirect
golang.org/x/text v0.15.0 // indirect
)
24 changes: 24 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
github.com/ebitengine/gomobile v0.0.0-20240518074828-e86332849895 h1:48bCqKTuD7Z0UovDfvpCn7wZ0GUZ+yosIteNDthn3FU=
github.com/ebitengine/gomobile v0.0.0-20240518074828-e86332849895/go.mod h1:XZdLv05c5hOZm3fM2NlJ92FyEZjnslcMcNRrhxs8+8M=
github.com/ebitengine/hideconsole v1.0.0 h1:5J4U0kXF+pv/DhiXt5/lTz0eO5ogJ1iXb8Yj1yReDqE=
github.com/ebitengine/hideconsole v1.0.0/go.mod h1:hTTBTvVYWKBuxPr7peweneWdkUwEuHuB3C1R/ielR1A=
github.com/ebitengine/purego v0.7.0 h1:HPZpl61edMGCEW6XK2nsR6+7AnJ3unUxpTZBkkIXnMc=
github.com/ebitengine/purego v0.7.0/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ=
github.com/go-text/typesetting v0.1.1-0.20240325125605-c7936fe59984 h1:NwCC36eQsDf1xVZG9jD7ngXNNjsvk8KXky15ogA1Vo0=
github.com/go-text/typesetting v0.1.1-0.20240325125605-c7936fe59984/go.mod h1:2+owI/sxa73XA581LAzVuEBZ3WEEV2pXeDswCH/3i1I=
github.com/go-text/typesetting-utils v0.0.0-20240317173224-1986cbe96c66 h1:GUrm65PQPlhFSKjLPGOZNPNxLCybjzjYBzjfoBGaDUY=
github.com/go-text/typesetting-utils v0.0.0-20240317173224-1986cbe96c66/go.mod h1:DDxDdQEnB70R8owOx3LVpEFvpMK9eeH1o2r0yZhFI9o=
github.com/hajimehoshi/bitmapfont/v3 v3.0.0 h1:r2+6gYK38nfztS/et50gHAswb9hXgxXECYgE8Nczmi4=
github.com/hajimehoshi/bitmapfont/v3 v3.0.0/go.mod h1:+CxxG+uMmgU4mI2poq944i3uZ6UYFfAkj9V6WqmuvZA=
github.com/hajimehoshi/ebiten/v2 v2.7.5 h1:jN6FnhCd9NGYCsm5GtrweuikrlyVGCSUpH5YgL+7UKA=
github.com/hajimehoshi/ebiten/v2 v2.7.5/go.mod h1:H2pHVgq29rfm5yeQ7jzWOM3VHsjo7/AyucODNLOhsVY=
github.com/jezek/xgb v1.1.1 h1:bE/r8ZZtSv7l9gk6nU0mYx51aXrvnyb44892TwSaqS4=
github.com/jezek/xgb v1.1.1/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk=
golang.org/x/image v0.16.0 h1:9kloLAKhUufZhA12l5fwnx2NZW39/we1UhBesW433jw=
golang.org/x/image v0.16.0/go.mod h1:ugSZItdV4nOxyqp56HmXwH0Ry0nBCpjnZdpDaIHdoPs=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
14 changes: 14 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package main

import "gtihub.com/KalebHawkins/pong/pong"

func main() {
cfg := &pong.Cfg{
ScreenWidth: 640,
ScreenHeight: 480,
WindowTitle: "Pong",
}

g := pong.NewGame(cfg)
g.Run()
}
118 changes: 118 additions & 0 deletions pong/pong.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package pong

import (
"bytes"
"fmt"
"image/color"

"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/ebitenutil"
"github.com/hajimehoshi/ebiten/v2/text/v2"
"gtihub.com/KalebHawkins/pong/assets"
)

const (
fontSize = 48
titleFontSize = fontSize * 1.5
)

// Game is a structure containing the game data and configuration.
type Game struct {
*Cfg
state
}

// Cfg contains the Game's configuration data.
type Cfg struct {
// ScreenWidth represents the width of the window
ScreenWidth int
// ScreenHeight represents the height of the window
ScreenHeight int
// WindowTitle is the title displayed in the window's title bar
WindowTitle string
// faceSource is the font face used for the menu, scoreboard, etc
faceSource *text.GoTextFaceSource
// backgroundImage is the background image
backgroundImage *ebiten.Image
}

// NewGame returns a Game instance to be ran.
func NewGame(cfg *Cfg) *Game {
fs, err := text.NewGoTextFaceSource(bytes.NewReader(assets.EmpireStateNF_ttf))
if err != nil {
panic(fmt.Sprintf("failed to load font file: %v", err))
}

bgImg, _, err := ebitenutil.NewImageFromReader(bytes.NewReader(assets.Background))
if err != nil {
panic(fmt.Sprintf("failed to background texture: %v", err))
}

cfg.faceSource = fs
cfg.backgroundImage = bgImg

return &Game{
Cfg: cfg,
state: mainMenu,
}
}

// Update manages user input, handles physics processes and updates game states.
func (g *Game) Update() error {
switch g.state {
case mainMenu:

}

return nil
}

// Draw draws the appropriate images to the screen based on game state.
func (g *Game) Draw(screen *ebiten.Image) {
switch g.state {
case mainMenu:
g.drawMainMenu(screen)
}
}

// Layout returns the screen's logical width and height.
func (g *Game) Layout(w, h int) (int, int) {
return w, h
}

// Run runs begins the game loop.
func (g *Game) Run() error {
ebiten.SetWindowSize(g.Cfg.ScreenWidth, g.Cfg.ScreenHeight)
ebiten.SetWindowTitle(g.Cfg.WindowTitle)

return ebiten.RunGame(g)
}

func (g *Game) drawMainMenu(screen *ebiten.Image) {
imgOpts := &ebiten.DrawImageOptions{}
imgOpts.GeoM.Scale(3, 2)
screen.DrawImage(g.backgroundImage, imgOpts)

titleTextFace := &text.GoTextFace{
Source: g.Cfg.faceSource,
Size: titleFontSize,
}
menuTextFace := &text.GoTextFace{
Source: g.Cfg.faceSource,
Size: fontSize,
}

opts := &text.DrawOptions{}
opts.GeoM.Translate(float64(g.ScreenWidth)/2, titleFontSize)
opts.PrimaryAlign = text.AlignCenter
opts.LineSpacing = titleFontSize
opts.ColorScale.ScaleWithColor(color.Black)
text.Draw(screen, "Pong", titleTextFace, opts)

opts = &text.DrawOptions{}
opts.GeoM.Translate(float64(g.ScreenWidth)/2, 3*titleFontSize)
opts.LineSpacing = fontSize
opts.PrimaryAlign = text.AlignCenter
opts.ColorScale.ScaleWithColor(color.Black)
text.Draw(screen, "Single Player\nMultiplayer", menuTextFace, opts)
}
11 changes: 11 additions & 0 deletions pong/states.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package pong

// state represents the games state
type state int

const (
mainMenu state = iota
gameLoop
paused
gameOver
)

0 comments on commit c1be082

Please sign in to comment.