egriden

package module
v0.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 15, 2024 License: BSD-3-Clause Imports: 8 Imported by: 0

README

Go Reference Go Report Card

egriden is a framework for the Ebitengine game engine, perfect for creating simple grid-based puzzle or strategy games.

Current features:

  • A grid layer system
  • Levels (aka scenes) and conventional free layers
  • "Gobjects" with custom draw and update scripts
  • Animatable sprite system with easy loading from PNG files

Instead of the common component approach seen in engines like Unity, it is more akin to GameMaker with how it handles object interactions.

It is an evolution of the messy code base created for TacZ and is currently used by me to create a word-based action puzzle game. Click here to follow development.

Currently unstable! Contributions of any kind are welcome. Check the changelog for updates.

Install

This is meant to be used with (rather than instead of) Ebitengine so follow the installation guide for Ebitengine.

In your go project's directory:

$ go get github.com/greenthepear/egriden

or to get the latest development version of this repo:

$ go get github.com/greenthepear/egriden@main

Quick boilerplate tutorial

package main

import (
    "github.com/greenthepear/egriden"
    "github.com/hajimehoshi/ebiten/v2"
)

type Game struct {
    egriden.EgridenAssets //Add assets needed for Egriden
    
    //Anything else you want here.
}

func (g *Game) Draw(screen *ebiten.Image) {
    g.DrawAllGridLayers(screen) //Draw layers according to their Z order

    // or do it your way with g.GridLayer(z).Draw()
}

func (g *Game) Update() error {
    // ... your game logic here
}

func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
    return 320, 320 //Define screen layout
}

func main(){
    //Initialize
    g := &Game{}
    g.InitEgridenAssets()

    layer0 := g.CreateGridLayerOnTop(
        "Background", //Name
        16, //Pixel size of a tile in the grid
        10, 10, //Width and height of the grid
        egriden.Sparce, //Draw mode
        0, 0) //Draw offset from the top left corner

    //Create an image sequence from all the PNGs in a folder
    //Image sequences are made of frames, controlled by the frame index
    seq, err := egriden.CreateImageSequenceFromFolder("idle", "./Graphics/player/idle/")
    if err != nil {
        log.Fatal(err)
    }

    //Create SpritePack with the sequence. A sprite pack can have multiple sequences,
    //which can be switched using their names (keys)
    playerSprites := egriden.NewSpritePackWithSequence(seq)

    //Create Gobject (short for grid object or go object or game object or whatever
    //you like) with the ImagePack
    goPlayer := egriden.NewBaseGobject("player", playerSprites)

    //Add to layer, Build() method needed for a baseGobject, otherwise create your own
    //structure for the Gobject interface. You can define update, draw
    //functions, sprite drawing options and other fun stuff.
    layer0.AddGobject(goPlayer.Build(), 1, 5)

    //Run the game
    if err = ebiten.RunGame(g); err != nil {
        log.Fatal(err)
    }
}

License

BSD-3-Clause license

Ebitengine by Hajime Hoshi is licensed under the Apache License 2.0

Documentation

Index

Constants

View Source
const (
	//Used for sparcely populated grids, ranges over a map for drawing
	Sparce drawMode = iota
	//Used for thickly populated grids, ranges over a slice for drawing
	Dense
	//Used for layers that don't get updated often, creates ebiten.Image of the the entire layer.
	//Can be refreshed with GridLayer.RefreshImage().
	Static
)

Variables

This section is empty.

Functions

func ScreenXYtoGrid added in v0.2.0

func ScreenXYtoGrid[T, R int | float64](l GridLayer, x, y T) (R, R)

Returns the layer's grid position corresponding to the given XY on the screen.

Will return negative or otherwise out of bounds positions if XY is not within the grid on the screen so either check the screen bounds beforehand or grid bounds afterhand before accessing grid coordinates derived from this function.

func SnapScreenXYtoCellAnchor added in v0.2.0

func SnapScreenXYtoCellAnchor[T, R int | float64](l GridLayer, x, y T) (R, R)

Returns the anchor (top left point on the screen) of a cell in a grid layer according to screen's XY.

Like ScreenXYtoGrid it can return positions out of grid bounds if XY is.

To visualize: ┌─┬─┬─┐ ┌─┬─┬─┐ │⠐│ │⠄│ │⠁│ │⠁│ ├─┼─┼─┤ becomes: ├─┼─┼─┤ │⠠│ │ │ │⠁│ │ │ └─┴─┴─┘ └─┴─┴─┘

Types

type BaseGobject

type BaseGobject struct {
	OnDrawFunc   func(self Gobject, i *ebiten.Image, l Layer)
	OnUpdateFunc func(self Gobject, l Layer)
	// contains filtered or unexported fields
}

The BaseGobject. Use it for simple Gobjects or implement your own Gobject by embedding this struct in your own.

func NewBaseGobject

func NewBaseGobject(name string, sprites SpritePack) BaseGobject

Create a new BaseGobject. Use BaseGobject.Build() to create a scriptless Gobject that can be added to a layer

func (BaseGobject) Build

func (o BaseGobject) Build() Gobject

Makes a copy of the Gobject

func (*BaseGobject) DrawSprite

func (o *BaseGobject) DrawSprite(on *ebiten.Image, l Layer)

Default function for drawing the sprite in the grid.

func (*BaseGobject) IsVisible

func (o *BaseGobject) IsVisible() bool

func (*BaseGobject) Name

func (o *BaseGobject) Name() string

func (*BaseGobject) NextFrame

func (o *BaseGobject) NextFrame()

Increments frame by one. Wraps back to 0 if out of range.

func (*BaseGobject) OnDraw added in v0.2.0

func (o *BaseGobject) OnDraw() func(Gobject, *ebiten.Image, Layer)

func (*BaseGobject) OnUpdate added in v0.2.0

func (o *BaseGobject) OnUpdate() func(Gobject, Layer)

func (*BaseGobject) SetDrawOffsets added in v0.2.0

func (o *BaseGobject) SetDrawOffsets(x, y float64)

Quick way to make the sprite draw with x and y added to the screen position.

func (*BaseGobject) SetDrawOptions added in v0.2.0

func (o *BaseGobject) SetDrawOptions(op *ebiten.DrawImageOptions)

Set custom ebiten draw options. Remember that tx and ty get translated depending on the grid position and layers offset.

func (*BaseGobject) SetFrame

func (o *BaseGobject) SetFrame(i int)

Sets the frame to `i % len(frames)`

func (*BaseGobject) SetImageSequence

func (o *BaseGobject) SetImageSequence(name string) error

Sets Image Sequence under name, returns error if the name key is not present

func (*BaseGobject) SetSpritePack

func (o *BaseGobject) SetSpritePack(sp SpritePack)

Assigns Sprite Pack. Should not be used during game updates.

func (*BaseGobject) Sprite

func (o *BaseGobject) Sprite() *ebiten.Image

Returns the current sprite. Used for built-in drawing.

func (*BaseGobject) SpritePack added in v0.2.0

func (o *BaseGobject) SpritePack() SpritePack

func (*BaseGobject) XY

func (o *BaseGobject) XY() (int, int)

type BaseLevel added in v0.2.0

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

func NewBaseLevel added in v0.2.0

func NewBaseLevel(name string) *BaseLevel

func (*BaseLevel) CreateFreeLayerOnTop added in v0.2.0

func (le *BaseLevel) CreateFreeLayerOnTop(name string, xOffset, yOffset float64) *FreeLayer

Creates a new FreeLayer and returns a pointer to it.

func (*BaseLevel) CreateGridLayerOnTop added in v0.2.0

func (le *BaseLevel) CreateGridLayerOnTop(name string, squareLength int, width, height int, drawMode drawMode, XOffset, YOffset float64) *GridLayer

Creates a grid layer at the lowest empty Z and returns a pointer to it.

See drawMode constants for which one you can use, but for small grids Sparce/Dense doesn't make much of a difference.

func (*BaseLevel) CreateStaticFreeLayerOnTop added in v0.2.0

func (le *BaseLevel) CreateStaticFreeLayerOnTop(
	name string, imgWidth, imgHeight int, xOffset, yOffset float64) *FreeLayer

Creates a free layer whose image needs to to be refreshed to be updated. Remember to call Refresh() at least once after populating, otherwise you'll just get an empty image.

func (*BaseLevel) DrawAllFreeLayers added in v0.2.0

func (le *BaseLevel) DrawAllFreeLayers(on *ebiten.Image)

Draws all free layers according to their Z order

func (*BaseLevel) DrawAllGridLayers added in v0.2.0

func (le *BaseLevel) DrawAllGridLayers(on *ebiten.Image)

Draws all grid layers according to their Z order

func (*BaseLevel) FreeLayer added in v0.2.0

func (le *BaseLevel) FreeLayer(z int) *FreeLayer

Retruns FreeLayer at given z layer, returns nil if out of bounds

func (*BaseLevel) FreeLayers added in v0.2.0

func (le *BaseLevel) FreeLayers() []*FreeLayer

func (*BaseLevel) GridLayer added in v0.2.0

func (le *BaseLevel) GridLayer(z int) *GridLayer

Returns a GridLayer at z, returns nil if out of bounds

func (*BaseLevel) GridLayers added in v0.2.0

func (le *BaseLevel) GridLayers() []*GridLayer

Returns slice of all current grid layers

func (*BaseLevel) Index added in v0.2.0

func (le *BaseLevel) Index() int

func (*BaseLevel) Init added in v0.2.0

func (le *BaseLevel) Init()

Initialize by creating slices for layers

func (*BaseLevel) Name added in v0.2.0

func (le *BaseLevel) Name() string

func (*BaseLevel) RunUpdateScripts added in v0.2.0

func (le *BaseLevel) RunUpdateScripts()

UNTESTED! Run all the onUpdate() functions of Gobjects that have them

type EgridenAssets

type EgridenAssets struct {
	Levels            []Level
	CurrentLevelIndex int
}

Egriden components to be embedded in your Game{} struct.

You need to run []

func (*EgridenAssets) AddLevel added in v0.2.0

func (g *EgridenAssets) AddLevel(le Level) Level

Append level to the end of the list and return it

func (*EgridenAssets) CreateFreeLayerOnTop added in v0.2.0

func (g *EgridenAssets) CreateFreeLayerOnTop(name string, xOffset, yOffset float64) *FreeLayer

Shortcut for g.Level().CreateFreeLayerOnTop(). Level implementation must have BaseLevel component.

func (*EgridenAssets) CreateGridLayerOnTop

func (g *EgridenAssets) CreateGridLayerOnTop(name string, squareLength int, width, height int, drawMode drawMode, XOffset, YOffset float64) *GridLayer

Short hand for BaseLevel.CreateGridLayerOnTop() for the current level

func (*EgridenAssets) CreateStaticFreeLayerOnTop added in v0.2.0

func (g *EgridenAssets) CreateStaticFreeLayerOnTop(
	name string, imgWidth, imgHeight int, xOffset, yOffset float64) *FreeLayer

Shortcut for g.Level().CreateStaticFreeLayerOnTop(). Level implementation must have BaseLevel component.

func (EgridenAssets) DrawAllFreeLayers added in v0.2.0

func (g EgridenAssets) DrawAllFreeLayers(on *ebiten.Image)

Draw all free layers of the current Level in their Z order.

func (EgridenAssets) DrawAllGridLayers added in v0.2.0

func (g EgridenAssets) DrawAllGridLayers(on *ebiten.Image)

Draw all GridLayers of the current Level in their Z order.

func (EgridenAssets) GridLayer

func (g EgridenAssets) GridLayer(z int) *GridLayer

Returns a GridLayer at z in the current Level, returns nil if out of bounds.

func (EgridenAssets) GridLayers

func (g EgridenAssets) GridLayers() []*GridLayer

func (*EgridenAssets) InitEgridenAssets added in v0.2.0

func (g *EgridenAssets) InitEgridenAssets()

Run this while initializing the game, before adding any layers. Creates a level called `Default`

func (*EgridenAssets) Level added in v0.2.0

func (g *EgridenAssets) Level() Level

Get the current level

func (*EgridenAssets) LevelByName added in v0.2.0

func (g *EgridenAssets) LevelByName(name string) Level

Get a level by it's name. Returns nil if not found.

func (*EgridenAssets) NextLevel added in v0.2.0

func (g *EgridenAssets) NextLevel()

Set the next level by iterating the level index

func (*EgridenAssets) RunUpdateScripts

func (g *EgridenAssets) RunUpdateScripts()

UNTESTED! Run all the onUpdate() functions of Gobjects that have them within the current level

func (*EgridenAssets) SetLevelTo added in v0.2.0

func (g *EgridenAssets) SetLevelTo(le Level)

Sets the current game's level or adds it if it's not in the assets already

type FreeLayer added in v0.2.0

type FreeLayer struct {
	Name string

	Visible bool

	XOffset, YOffset float64
	// contains filtered or unexported fields
}

A free layer is a layer where the default drawing position of Gobjects is only determined by their XY coordinates and can be anywhere on the screen or outside of it.

func (*FreeLayer) AddGobject added in v0.2.0

func (fl *FreeLayer) AddGobject(o Gobject, x, y int)

func (*FreeLayer) DeleteGobject added in v0.2.0

func (fl *FreeLayer) DeleteGobject(o Gobject)

func (FreeLayer) Draw added in v0.2.0

func (fl FreeLayer) Draw(on *ebiten.Image)

Draw the layer

func (FreeLayer) DrawSprite added in v0.2.0

func (fl FreeLayer) DrawSprite(o Gobject, on *ebiten.Image)

func (*FreeLayer) MoveGobjectTo added in v0.2.0

func (fl *FreeLayer) MoveGobjectTo(o Gobject, x, y int)

func (*FreeLayer) Offsets added in v0.2.0

func (fl *FreeLayer) Offsets() (float64, float64)

func (*FreeLayer) RefreshImage added in v0.2.0

func (fl *FreeLayer) RefreshImage()

Refresh/create image of a static free layer

func (*FreeLayer) SetVisibility added in v0.2.0

func (le *FreeLayer) SetVisibility(to bool)

func (*FreeLayer) Z added in v0.2.0

func (fl *FreeLayer) Z() int

type Gobject

type Gobject interface {
	Name() string
	XY() (int, int)

	IsVisible() bool
	Sprite() *ebiten.Image
	SpritePack() SpritePack
	SetDrawOptions(*ebiten.DrawImageOptions)
	SetDrawOffsets(float64, float64)
	SetImageSequence(string) error
	NextFrame()
	SetFrame(int)

	OnUpdate() func(self Gobject, l Layer)                //Runs every game.Update() call
	OnDraw() func(self Gobject, i *ebiten.Image, l Layer) //Runs ever game.Draw() call
	DrawSprite(*ebiten.Image, Layer)                      //Default sprite drawing function
	// contains filtered or unexported methods
}

Gobject is an object that exists in a layer

type GridLayer

type GridLayer struct {
	Name string // Name of the layer, for convenience sake

	SquareLength  int
	Width, Height int
	Visible       bool

	XOffset, YOffset float64
	NumOfGobjects    int
	// contains filtered or unexported fields
}

func (*GridLayer) AddGobject added in v0.2.0

func (l *GridLayer) AddGobject(o Gobject, x, y int)

Adds Gobject to the layer at x y. Will overwrite the any existing Gobject there.

func (*GridLayer) DeleteAt added in v0.2.0

func (l *GridLayer) DeleteAt(x, y int)

func (GridLayer) Draw

func (l GridLayer) Draw(on *ebiten.Image)

Draw the layer

func (GridLayer) DrawSprite added in v0.2.0

func (l GridLayer) DrawSprite(o Gobject, on *ebiten.Image)

func (GridLayer) GobjectAt

func (l GridLayer) GobjectAt(x, y int) Gobject

Returns Gobject at x y, nil if empty. Panics if out of bounds.

func (GridLayer) IsOccupiedAt

func (l GridLayer) IsOccupiedAt(x, y int) bool

func (GridLayer) IsScreenXYwithinBounds added in v0.2.0

func (l GridLayer) IsScreenXYwithinBounds(x, y int) bool

Checks if XY is within bounds on the screen, taking into account the layer offsets.

func (GridLayer) IsXYwithinBounds added in v0.2.0

func (l GridLayer) IsXYwithinBounds(x, y int) bool

Returns true if cell coordinate is within width and height of the grid layer

func (*GridLayer) MoveGobjectTo added in v0.2.0

func (l *GridLayer) MoveGobjectTo(o Gobject, x, y int)

Moves Gobject by first finding itself in the layer with its XY coordinates, but will panic if the Gobject in that cell is not the same, so you cannot use this with Gobjects that are not in the layer, obviously.

func (*GridLayer) Offsets added in v0.2.0

func (l *GridLayer) Offsets() (float64, float64)

func (*GridLayer) RefreshImage

func (l *GridLayer) RefreshImage()

Refresh image of a static grid layer

func (*GridLayer) SetVisibility

func (l *GridLayer) SetVisibility(to bool)

False visibility disables drawing both the Sprites and custom draw scripts of all Gobjects.

func (*GridLayer) Z

func (l *GridLayer) Z() int

Returns the Z level

type ImageSequence

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

ImageSequence is a sequence of images aka frames.

func CreateImageSequenceFromFolder

func CreateImageSequenceFromFolder(name, folderPath string) (ImageSequence, error)

Searches for PNG files in the folder and creates an ImageSequence, with frame order based on the alphabetical order of the file names.

func CreateImageSequenceFromPaths

func CreateImageSequenceFromPaths(name string, paths ...string) (ImageSequence, error)

Create an ImageSequence using multiple (or just one) file paths.

type Layer added in v0.2.0

type Layer interface {
	DrawSprite(o Gobject, on *ebiten.Image)
	Offsets() (float64, float64)
}

type Level added in v0.2.0

type Level interface {
	Name() string
	Index() int

	GridLayer(int) *GridLayer
	GridLayers() []*GridLayer

	FreeLayer(int) *FreeLayer
	FreeLayers() []*FreeLayer
	// contains filtered or unexported methods
}

Levels are essentially different collections of layers. They are often called scenes in game dev.

type SpritePack

type SpritePack struct {
	DrawOptions      *ebiten.DrawImageOptions
	XOffset, YOffset float64
	// contains filtered or unexported fields
}

SpritePack is a collection of ImageSequences and controls things like the frame index.

func EmptySpritePack

func EmptySpritePack() SpritePack

A sprite pack that will not render anything

func NewSpritePack

func NewSpritePack() SpritePack

func NewSpritePackWithSequence

func NewSpritePackWithSequence(is ImageSequence) SpritePack

Create SpritePack and assign sequence

func NewSpritePackWithSequences

func NewSpritePackWithSequences(is ...ImageSequence) SpritePack

Create SpritePack and assign multiple sequences

func (*SpritePack) AddImageSequence

func (ip *SpritePack) AddImageSequence(is ImageSequence)

Assigns an ImageSequence to SpritePack

func (SpritePack) Sprite

func (sp SpritePack) Sprite() *ebiten.Image

type StaticFreeLayerOp added in v0.2.0

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

Options for a static free layer

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL