ebitick

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

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

Go to latest
Published: Oct 9, 2023 License: MIT Imports: 2 Imported by: 1

README

ebitick⏱️

Go Reference

ebitick is a timer system for Ebitengine games.

Why?

Because timing stuff is important and can be done in an easy to use, set-it-and-forget-it kinda way. You can just use time.After(), but that works on an additional goroutine, which can introduce race conditions into the mix. Ebitick, in comparison, works on the same goroutine as the rest of your game.

❗ : Note that ebitick keeps time by counting ticks against the target tickrate (TPS), so it won't work properly if you change the tickrate while timers are running.

How?

go get github.com/solarlune/ebitick


package main

import (
    "fmt"
    "time"
    
    "github.com/hajimehoshi/ebiten/v2"
    "github.com/solarlune/ebitick"
)

type Game struct {
    TimerSystem *ebitick.TimerSystem
}

func NewGame() *Game {

    game := &Game{
        TimerSystem: ebitick.NewTimerSystem(),
    }

    // Below, we specify that after a second has passed,
    // we run the given function literal.
    game.TimerSystem.After(time.Second, func() {
        fmt.Println("A second has passed.")
    })

    // There's also a TimerSystem.AfterTicks() function if you want to use
    // ticks exactly without any human-readable time.Duration conversions.
    
    // The After functions return the created Timer, allowing you to pause it
    // later as necessary or set it to loop, for example. Once the timer elapses,
    // it is removed from the TimerSystem and its state is set to StateFinished,
    // so you can check for that if necessary as well.

    return game

}

func (game *Game) Update() error {

    // We have the TimerSystem update by one once per game tick, and that's it.
    game.TimerSystem.Update(1)

    return nil

}

func (game *Game) Draw(screen *ebiten.Image) {}

func (game *Game) Layout(w, h int) (int, int) { return 320, 240 }

func main() {

    ebiten.SetWindowTitle("Ebitick Minimal Example")
    ebiten.RunGame(NewGame())

}

Shout-outs

Ebitengine's Discord server~

Documentation

Index

Constants

View Source
const (
	StateRunning = iota
	StateCanceled
	StatePaused
	StateFinished
)

The various possible states for a Timer.

Variables

This section is empty.

Functions

This section is empty.

Types

type TimeUnit

type TimeUnit float32

TimeUnit represents a game tick in an ebitengine game. For simplicity, a TimeUnit can be used as either a timestamp (think time.Time{}, time.Now()), or a duration of time (time.Duration{}, time.Since()) depending on the context with which the value is used. It is a float so that a TimerSystem can run at faster or slower speeds.

func ToTimeUnit

func ToTimeUnit(duration time.Duration) TimeUnit

ToTimeUnit converts the given number of seconds to a TimeUnit using Ebiten's current TPS value.

func (TimeUnit) ToDuration

func (ts TimeUnit) ToDuration() time.Duration

ToDuration converts the timestamp to a generic time.Duration.

type Timer

type Timer struct {
	StartTick TimeUnit // On what tick of the TimerSystem the Timer was initially started.

	OnExecute func() // What the timer does once it elapses.
	Loop      bool   // If the Timer should loop after elapsing. Defaults to off.
	State     int    // What state the Timer is in.
	// contains filtered or unexported fields
}

Timer represents a timer that elapses after a given amount of time.

func (*Timer) Cancel

func (timer *Timer) Cancel()

Cancel cancels a Timer, removing it from the TimerSystem the next time TimerSystem.Update() is called. This does nothing on a finished Timer.

func (*Timer) Pause

func (timer *Timer) Pause()

Pause pauses the Timer. While paused, a Timer is not incrementing time. This does nothing on a Timer if it isn't running, specifically.

func (*Timer) Restart

func (timer *Timer) Restart()

func (*Timer) Resume

func (timer *Timer) Resume()

Resume resumes a paused Timer. This does nothing on a Timer if it isn't paused, specifically.

func (*Timer) SetDuration

func (timer *Timer) SetDuration(duration TimeUnit)

func (*Timer) TimeLeft

func (timer *Timer) TimeLeft() TimeUnit

TimeLeft returns a TimeUnit indicating how much -absolute- time is left on the Timer. This value is multiplied by the owning system's current speed value.

type TimerSystem

type TimerSystem struct {
	Timers      []*Timer // The Timers presently existing in the System.
	CurrentTime TimeUnit // The current TimeUnit (tick) of the TimerSystem. TimerSystem.Update() increments this by TimerSystem.Speed each game tick.
	Speed       float64  // Overall update speed of the system; changing this changes how fast the TimerSystem runs. Defaults to 1.
}

TimerSystem represents a system that updates and triggers timers added to the System.

func NewTimerSystem

func NewTimerSystem() *TimerSystem

NewTimerSystem creates a new TimerSystem instance.

func (*TimerSystem) After

func (ts *TimerSystem) After(duration time.Duration, onElapsed func()) *Timer

After creates a new Timer that will elapse after the given duration, running the onElapsed() function when it does so. Note that the granularity for conversion from time.Duration is whole ticks, so fractions will be rounded down. For example, if your game runs at 60 FPS / TPS, then a tick is 16.67 milliseconds. If you pass a duration of 20 milliseconds, the timer will trigger after one tick. If you pass a duration of 16 milliseconds, the timer will trigger immediately. This will happen on whatever thread TimerSystem.Update() is called on (most probably the main thread).

func (*TimerSystem) AfterTicks

func (ts *TimerSystem) AfterTicks(tickCount TimeUnit, onElapsed func()) *Timer

AfterTicks creates a new Timer that will elapse after tickCount ticks, running the onElapsed() function when it does so. This will happen on whatever thread TimerSystem.Update() is called on (most probably the main thread).

func (*TimerSystem) Clear

func (ts *TimerSystem) Clear()

Clear cancels all Timers that belong to the TimerSystem and removes them from the TimerSystem. This is safe to call from a Timer's elapsing function.

func (*TimerSystem) Update

func (ts *TimerSystem) Update()

Update updates the TimerSystem and triggers any Timers that have elapsed. This should be called once per frame in your game's update loop. Note that timers will no longer be accurate if Ebitengine's TPS is changed while they are running.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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