prestige

package module
v0.0.0-...-b278557 Latest Latest
Warning

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

Go to latest
Published: May 31, 2024 License: MIT Imports: 4 Imported by: 1

README

Prestige

Go Reference

A simple scene manager for ebitengine.


prestige is heavily inspired by stagehand, but aims to simplify and clarify some parts. It also comes with (way) fewer features, but should suffice, or be easily extendable, to accommodate other use cases. This document contains some details about the structure of this package. Please read it for a better understanding of how this package works; if anything here is unclear, it is considered a bug.

The main file is scene-manager.go which defines two crucial interfaces, Scene[T] and Transition. fade.go and simple.go contain two simple implementations of Transition. examples/basic contains a simple example showing how to use this package. You can run it using go run ..

The idea is as follows:

  • You have a state struct, which has the same purpose as the usual Game struct in ebitengine. It should contain state used across all scenes. It is also recommended to add a SceneManager field in your state. For example, the state in examples/basic is just
type State struct {
    Manager *prestige.SceneManager[State]
}

and it is initialized as

basicScene := &BasicScene{}
state := State{}
manager := prestige.NewSceneManager(basicScene, &state)
state.Manager = manager

Having the manager in your state will allow you to call methods on it, for instance, to do transitions, like so:

// Fade transition for 1s to a new instance of BasicScene
state.Manager.Transition(&BasicScene{}, prestige.NewFadeTransition(1)) 
  • For each scene you have a struct (say BasicScene) such that *BasicScene implements Scene[T] where T is the type of your state. The methods needed of Scene[T] contain those needed of *Game in ebitengine, but with the additional state *T parameter passed in:
Draw(state *T, screen *ebiten.Image)
Update(state *T) error
Layout(state *T, outsideWidth, outsideHeight int) (screenWidth, screenHeight int)

Take a look at examples/basic/main.go for an example implementation of these methods. These implementations should look very similar to analogous implementations of *Game, but now you have two sources of state: the first is the method received *BasicState, and the second is the overall state passed to the method *T.

  • But there are also four lifecycle methods
// Transition has started to enter your scene, load your stuff now
EnterStart(state *T)
// Transition has finished entering your scene, enable scene mechanics if they were disabled
EnterEnd(state *T)

// Transition has started to exit your scene, disable scene mechanics if you like
ExitStart(state *T)
// Transition has finished exiting your scene, wrap up now
ExitEnd(state *T)

The functionality here is clear. If you do not wish to do anything special to accommodate transitions, all four of these would be empty. However, during a transition, you may wish to freeze inputs and such, which may be accomplished by implementing these methods.

When the first scene is loaded, EnterStart and EnterEnd are called in succession (see the implementation of NewSceneManager), so you may use them consistently to load dependencies.

  • Transitions are completely decoupled from the scenes, so they have no type parameter. They implement the interface
// Called before the transition begins. Initialize the state
Start()

// Interpolate between two images produced by the two scenes between whom this transition exists
Interpolate(screen *ebiten.Image, src *ebiten.Image, dest *ebiten.Image)

// Update the state of the transition and return whether the transition has finished
Update() bool

The functionality is clear, but I will elaborate a bit on Interpolate. Essentially, interpolate is given the images output by the current scene and the next scene (loading and initializing them are taken care of by the scene manager). The job of this function is to just interpolate the two images anyway you see fit. For instance, see the implementation in fade.go.

If you really need the current state in the transition, you may query that from SceneManager.State and insert it into the state for your Transition during construction.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type FadeTransition

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

A simple fade transition, that uses half the time to fade out of the current scene and half the time to fade into the new scene. You may wish to freeze inputs during the fade, which you can accomplish in the `ExitStart` and `EnterStart` phase of your scenes, and unfreeze during `EnterEnd` for the new scene.

func NewFadeTransition

func NewFadeTransition(duration float64) *FadeTransition

Pass in the total duration (in seconds) to construct a new fade transition.

func (*FadeTransition) Interpolate

func (self *FadeTransition) Interpolate(screen *ebiten.Image, src *ebiten.Image, dest *ebiten.Image)

func (*FadeTransition) Start

func (self *FadeTransition) Start()

func (*FadeTransition) Update

func (self *FadeTransition) Update() bool

type Scene

type Scene[T any] interface {
	// Transition has started to enter your scene, load your stuff now
	EnterStart(state *T)
	// Transition has finished entering your scene, enable scene mechanics if they were disabled
	EnterEnd(state *T)

	Draw(state *T, screen *ebiten.Image)
	Update(state *T) error
	Layout(state *T, outsideWidth, outsideHeight int) (screenWidth, screenHeight int)

	// Transition has started to exit your scene, disable scene mechanics if you like
	ExitStart(state *T)
	// Transition has finished exiting your scene, wrap up now
	ExitEnd(state *T)
}

Your should implement this on *YourScene, and T should be your global state across scenes. Your scene may have scene-local state as well.

type SceneManager

type SceneManager[T any] struct {
	State *T
	// contains filtered or unexported fields
}

The only field accessible here is State. The only use for this should be to implement custom transitions that also depend on the current state (for instance if you wish to show scores on the transition screen).

func NewSceneManager

func NewSceneManager[T any](firstScene Scene[T], state *T) (manager *SceneManager[T])

Construct a new scene manager, given the initial scene and initial state.

func (*SceneManager[T]) Draw

func (self *SceneManager[T]) Draw(screen *ebiten.Image)

func (*SceneManager[T]) Layout

func (self *SceneManager[T]) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int)

func (*SceneManager[T]) Transition

func (self *SceneManager[T]) Transition(dest Scene[T], transition Transition) error

Call this to transition to a new scene.

func (*SceneManager[T]) Update

func (self *SceneManager[T]) Update() error

type SimpleTransition

type SimpleTransition struct {
}

A simple transition that immediately transfers from the current state to the next

func (*SimpleTransition) Interpolate

func (self *SimpleTransition) Interpolate(screen *ebiten.Image, src *ebiten.Image, dest *ebiten.Image)

func (*SimpleTransition) Start

func (self *SimpleTransition) Start()

func (*SimpleTransition) Update

func (self *SimpleTransition) Update() bool

type Transition

type Transition interface {
	// Called before the transition begins. Initialize the state
	Start()

	// Interpolate between two images produced by the two scenes between whom this transition exists
	Interpolate(screen *ebiten.Image, src *ebiten.Image, dest *ebiten.Image)

	// Update the state of the transition and return whether the transition has finished
	Update() bool
}

Directories

Path Synopsis
examples module

Jump to

Keyboard shortcuts

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