README

Pacman

Go to game Go Report Card

Classic Pacman with procedurally generated infinite vertical maze.

Sample

Motivation

I came across Eller's algorithm for maze generation, a few months back. Eller's algorithm creates a perfect maze, by generating next row, on basis of current row. Giving us ability to create maze with infinite rows.

Since then I have been toying with idea of creating a game around it. It wasn't until a few days ago that I finally decided to use Pacman as the basis for game. I had experimented with Ebiten 2D game engine a bit and this gave me a good opportunity to use it. For maze generation I slightly modified Eller's algorithm to create non-perfect mazes.

Build

Using go get & without go modules.

$ go get -u github.com/skatiyar/pacman
$ cd skatiyar/pacman
$ go get ./...
$ cd build/pacman #goto build dir
$ go build -o pacman main.go
$ ./pacman

Using git clone & go modules.

$ git clone https://github.com/skatiyar/pacman.git
$ cd pacman/build/pacman #goto build dir
$ go build -o pacman main.go
$ ./pacman

Build gh-pages

Golang code is converted to JS by using gopherjs. Ebiten supports browsers by using webgl.

Note: Setup repo beforehand, as shown above.

To build just go code.

$ go get -u github.com/gopherjs/gopherjs
$ cd pacman/build/pacman
$ gopherjs build --tags=pacman --output=pacman.js

To build gh-pages.

$ go get -u github.com/gopherjs/gopherjs
$ cd pacman/build/pacman-pages
$ yarn install && yarn build

How to play

  • Use arrow keys to move pacman.
  • Gain points by eating dots.
  • Ghosts try to chase player and on collision player looses a life.
  • Player starts with 5 lives and can have upto 7.
  • Collect diamond to increase lives.
  • Use flask to gain ability to destroy ghosts, ability lasts for 10 Sec & ghosts try to runaway from player.
  • Eating a running away ghost gives a bonus of 200 points.

Thanks to

Expand ▾ Collapse ▴

Documentation

Overview

Package pacman implements the classic Pacman game, with a procedurally generated, infinite vertical maze.

How to play: Use direction keys to move pacman. Ghosts try to chase player and on collision player looses a life. Player starts with 5 lives and can have upto 7. Collect diamond to increase lives. Use flask to gain ability to destroy ghosts, ability lasts for 10 seconds & ghosts try to runaway from player. Eating a ghost gives bonus of 200 points.

Index

Constants

const (
	North direction = iota
	East
	South
	West
)

const (
	Ghost1 ghostType = iota
	Ghost2
	Ghost3
	Ghost4
)

const (
	Life powerType = iota
	Invincibility
)

const (
	GameLoading gameState = iota
	GameStart
	GamePause
	GameOver

	OffsetY = CellSize * 10
)

const CellSize = 64

const Columns = 10

Columns defines the number of cells in a row in maze.


const GridViewSize = 1024

const MagicNumber = 0.7

MagicNumber for deciding whether or not to tear down wall between two columns.


const MaxLifes = 7

const MaxScoreView = 999999999

const MazeViewSize = 1536

Variables

var GrayColor = color.RGBA{236, 240, 241, 255.0}

Functions

func GridView

func GridView(
	characters *assets.Characters,
	powers *assets.Powers,
	arcadeFont *truetype.Font,
	mazeView func(state gameState, data *Data) (*ebiten.Image, error),
) (func(state gameState, data *Data) (*ebiten.Image, error), error)

func MazeView

func MazeView(
	walls *assets.Walls,
) (func(state gameState, data *Data) (*ebiten.Image, error), error)

func SkinView

func SkinView(
	skin *ebiten.Image,
	powers *assets.Powers,
	arcadeFont *truetype.Font,
) (func(state gameState, data *Data) (*ebiten.Image, error), error)

Types

type Audio

type Audio struct {
	// contains filtered or unexported fields
}

func NewAudio

func NewAudio() (*Audio, error)

type AudioPlayers

type AudioPlayers struct {
	Beginning *audio.Player
	Chomp     *audio.Player
	Death     *audio.Player
	EatFlask  *audio.Player
	EatGhost  *audio.Player
	ExtraPac  *audio.Player
}

type Data

type Data struct {
	// contains filtered or unexported fields
}

func NewData

func NewData() *Data

type Game

type Game struct {
	// contains filtered or unexported fields
}

func NewGame

func NewGame() (*Game, error)

func (*Game) Run

func (g *Game) Run() error

type Ghost

type Ghost struct {
	Position
	// contains filtered or unexported fields
}

func NewGhost

func NewGhost(x, y int, kind ghostType, dir direction) Ghost

type Maze

type Maze struct {
	// contains filtered or unexported fields
}

Maze represents a maze of size rows x 10.

Maze creation is based on modified version of Eller's algorithm http://weblog.jamisbuck.org/2010/12/29/maze-generation-eller-s-algorithm. Eller's algorithm creates a perfect maze, a perfect maze has only one path between any two cells. Secondly to create next row, it requires knowledge of current row only. Giving us ability to create maze with infinite rows.

Current implementation has been modified to give a non-perfect maze i.e. it can have more than one path between any two cells.

func NewMaze

func NewMaze(rows int, src *rand.Rand) *Maze

NewMaze returns an unintialized maze with given number of rows. Rand source is used for all random operations, to give deterministic results for a given seed.

func NewPopulatedMaze

func NewPopulatedMaze(rows int, src *rand.Rand) *Maze

NewPopulatedMaze returns a valid maze with given number of rows. It calls Populate after calling NewMaze.

func (*Maze) Compact

func (m *Maze) Compact(n int)

Compact removes given number of rows from head of grid and also creates walls in South direction to prevent player from acessing previous rows.

func (*Maze) Get

func (m *Maze) Get(from, upto int) [][Columns][4]rune

Get returns section of maze specified by indexes. It reorders from & upto if from is greater than upto. In case upto is bigger than number of rows, all rows till last are returned.

func (*Maze) GrowBy

func (m *Maze) GrowBy(n int)

GrowBy extends the grid by given number & creates a valid maze out of new rows.

func (*Maze) Populate

func (m *Maze) Populate()

Populate creates a valid maze for given grid.

func (*Maze) Rows

func (m *Maze) Rows() int

Rows returns number of rows in maze.

type Pacman

type Pacman struct {
	Position
}

type Position

type Position struct {
	// contains filtered or unexported fields
}

type Power

type Power struct {
	Position
	// contains filtered or unexported fields
}

func NewPower

func NewPower(x, y int, kind powerType) Power

Directories

Path Synopsis
assets Package assets contains font, image & sound resources needed by the game
assets/fonts Package fonts contains variables holding font files.
assets/images Package images contains variables holding image files.
assets/sounds Package sounds contains variables holding sound files.
build/pacman
spritetools Package spritetools provides functions to manipulate ebiten images.