gosu

package module
v0.2.1 Latest Latest
Warning

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

Go to latest
Published: Oct 18, 2022 License: Apache-2.0 Imports: 30 Imported by: 0

Documentation

Index

Constants

View Source
const (
	SignDot = iota
	SignComma
	SignPercent
)
View Source
const (
	SortByName = iota
	SortByLevel
)
View Source
const (
	DecayFactor = 0.95
	LevelPower  = 1.15
	LevelScale  = 0.02
)

Todo: find the best SliceDuration value

View Source
const (
	ModeNone   = iota - 1
	ModePiano4 // 1 to 4 Key
	ModePiano7 // 5, 6 Key and 7+ Key
	ModeDrum
	ModeKaraoke
)
View Source
const (
	Flow = iota
	Acc
	Extra
	Total
)

Total score consists of 3 scores: Flow, Acc, and Kool rate score. Flow score is calculated with sum of Flow. Flow once named as Karma. Acc score is calculated with sum of Acc of judgments. Extra score is calculated with a sum of Extra primitive. Flow recovers fast when its value is low, vice versa: math.Pow(x, a); a < 1 Acc and Extra score increase faster as each parameter approaches to max value: math.Pow(x, b); b > 1

View Source
const (
	ScreenSizeX = screenSizeX
	ScreenSizeY = screenSizeY
)

ScreenSize is a logical size of in-game screen.

View Source
const (
	CursorSpriteBase = iota
	CursorSpriteAdditive
	CursorSpriteTrail
)
View Source
const Wait = 1800

Variables

View Source
var (
	ColorKool = color.NRGBA{0, 170, 242, 255}   // Blue
	ColorCool = color.NRGBA{85, 251, 255, 255}  // Skyblue
	ColorGood = color.NRGBA{51, 255, 40, 255}   // Lime
	ColorBad  = color.NRGBA{244, 177, 0, 255}   // Yellow
	ColorMiss = color.NRGBA{109, 120, 134, 255} // Gray
)
View Source
var (
	Face12 font.Face
	Face16 font.Face
	Face20 font.Face
	Face24 font.Face
)

FaceDefault = basicfont.Face7x13

View Source
var (
	MusicVolume          float64 = 0.25
	EffectVolume         float64 = 0.25
	BackgroundBrightness float64 = 0.6

	Offset int = -65
)
View Source
var (
	ModeKeyHandler ctrl.KeyHandler

	SortKeyHandler ctrl.KeyHandler

	MusicVolumeKeyHandler ctrl.KeyHandler

	EffectVolumeKeyHandler ctrl.KeyHandler

	BrightKeyHandler ctrl.KeyHandler

	OffsetKeyHandler ctrl.KeyHandler
)
View Source
var (
	MusicRoot   = "music"
	WindowSizeX = 1600
	WindowSizeY = 900
)
View Source
var (
	// TPS supposed to be multiple of 1000, since only one speed value
	// goes passed per Update, while unit of TransPoint's time is 1ms.
	// TPS affects only on Update(), not on Draw().
	TPS int = 1000 // TPS should be 1000 or greater.

	CursorScale        float64 = 0.1
	ChartInfoBoxWidth  float64 = 450
	ChartInfoBoxHeight float64 = 50
	ChartInfoBoxShrink float64 = 0.15

	ScoreScale    float64 = 0.65
	ScoreDigitGap float64 = 0
	MeterWidth    float64 = 4 // The number of pixels per 1ms.
	MeterHeight   float64 = 50
)
View Source
var (
	DefaultBackground  draws.Sprite
	CursorSprites      [3]draws.Sprite
	ChartItemBoxSprite draws.Sprite

	ScoreSprites [10]draws.Sprite
	SignSprites  [3]draws.Sprite
)

Skin is a set of Sprites and sounds.

View Source
var (
	SelectSound      []byte
	SwipeSound       []byte
	TapSound         []byte
	ToggleSounds     [2][]byte
	TransitionSounds [2][]byte
)
View Source
var DefaultMaxScores = [4]float64{
	7 * 1e5,
	3 * 1e5,
	1 * 1e5,
	11 * 1e5,
}
View Source
var MeterMarkColors = []color.NRGBA{
	{255, 255, 255, 192},
	{213, 0, 242, 192},
	{252, 83, 6, 255},
}
View Source
var (
	SpeedScaleKeyHandler ctrl.KeyHandler
)

Functions

func BPMs

func BPMs(transPoints []*TransPoint, duration int64) (main, min, max float64)

BPM with longest duration will be main BPM. When there are multiple BPMs with same duration, larger one will be main BPM.

func ChartFileMode

func ChartFileMode(fpath string) int

Mode determines a mode of chart file by its path.

func Level

func Level(c interface{ Difficulties() []float64 }) (float64, [3]float64)

No need to define interface{} called ChartAnalyzer: https://go.dev/play/p/PtgBkwKZFhP

func LoadChartInfosSet

func LoadChartInfosSet(modeProps []ModeProp) error

LoadChartInfos supposes Game's Modes has already set. ChartInfos are sorted with path, then mods. Todo: can the slice be sorted with Mode first, then MusicName?

func LoadGeneralSkin

func LoadGeneralSkin()

func LoadHandlers

func LoadHandlers(props []ModeProp)

func LoadReplays

func LoadReplays(replayRoot string) ([]*osr.Format, error)

Todo: Make own ScenePlay for calculating score from input replay file Todo: implement non-playing score simulator NewScenePlayCalc(Chart, Mods, *osr.Format); Update returns PlayToResultArgs {} if finished.

func NewBackground

func NewBackground(path string) draws.Sprite

func NewCursorKeyHandler

func NewCursorKeyHandler(cursor *int, len int) ctrl.KeyHandler

func Paths

func Paths(base string) (paths []string)

func SaveChartInfosSet

func SaveChartInfosSet(modeProps []ModeProp)

func SetKeySettings

func SetKeySettings(props []ModeProp)

Temporary function.

func SetTPS

func SetTPS()

Todo: reset all tick-dependent variables. They are mostly at drawer.go or play.go, settings.go Keyword: TimeToTick

func SetTitle

func SetTitle(c ChartHeader)

func Sort

func Sort(sortBy int)

func Sum

func Sum(vs []float64) (sum float64)

func TickToTime

func TickToTime(tick int) int64

func TidyChartInfosSet

func TidyChartInfosSet(modeProps []ModeProp)

TidyChartInfosSet drops unavailable chart infos from games.

func TimeToTick

func TimeToTick(time int64) int

Time is a point of time, duration a length of time.

Types

type BackgroundDrawer

type BackgroundDrawer struct {
	Brightness *float64
	Sprite     draws.Sprite
}

Order of fields of drawer: updating fields, others fields, sprites.

func (BackgroundDrawer) Draw

func (d BackgroundDrawer) Draw(screen *ebiten.Image)

type ChartHeader

type ChartHeader struct {
	ChartID       int64
	MusicName     string
	MusicUnicode  string
	Artist        string
	ArtistUnicode string
	MusicSource   string
	ChartName     string
	Charter       string
	HolderID      int64

	PreviewTime     int64
	MusicFilename   string
	ImageFilename   string
	VideoFilename   string
	VideoTimeOffset int64
}

ChartHeader contains non-play information. Chaning ChartHeader's data will not affect integrity of the chart. Mode-specific fields are located to each Chart struct.

func NewChartHeader

func NewChartHeader(f any) (c ChartHeader)

func (ChartHeader) BackgroundPath

func (c ChartHeader) BackgroundPath(cpath string) string

func (ChartHeader) MusicPath

func (c ChartHeader) MusicPath(cpath string) (string, bool)

type ChartInfo

type ChartInfo struct {
	Path string
	// Mods    Mods
	// Header  ChartHeader
	ChartHeader
	Mode    int
	SubMode int
	Level   float64

	Duration   int64
	NoteCounts []int
	MainBPM    float64
	MinBPM     float64
	MaxBPM     float64
}

ChartInfo is used at SceneSelect.

func PutChartInfo

func PutChartInfo(infos []ChartInfo, info ChartInfo) []ChartInfo

Todo: mode of ChartSet as a move unit

func (ChartInfo) BPMString

func (c ChartInfo) BPMString() string

func (ChartInfo) BackgroundPath

func (c ChartInfo) BackgroundPath() string

func (ChartInfo) NewChartBoard

func (c ChartInfo) NewChartBoard() draws.Box

Background brightness at Song select: 60% (153 / 255), confirmed. Score box color: Gray128 with 50% transparent Hovered Score box color: Gray96 with 50% transparent

func (ChartInfo) NoteCountString

func (c ChartInfo) NoteCountString() string

func (ChartInfo) Text

func (c ChartInfo) Text() string

func (ChartInfo) TimeString

func (c ChartInfo) TimeString() string

type Game

type Game struct {
	Scene
}

func NewGame

func NewGame(props []ModeProp) *Game

Todo: load settings

func (*Game) Draw

func (g *Game) Draw(screen *ebiten.Image)

func (*Game) Layout

func (g *Game) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int)

func (*Game) Update

func (g *Game) Update() (err error)

type Judgment

type Judgment struct {
	Flow   float64
	Acc    float64
	Window int64
}

func Judge

func Judge(js []Judgment, td int64) Judgment

func Verdict

func Verdict(js []Judgment, a input.KeyAction, td int64) Judgment

Verdict for normal notes, e.g., Note, Head at Piano mode.

func (Judgment) Is

func (j Judgment) Is(j2 Judgment) bool

Is returns whether j and j2 are equal by its window size.

func (Judgment) Valid

func (j Judgment) Valid() bool

Valid returns whether j is not a blank judgment by its window size.

type KeyLogger

type KeyLogger struct {
	FetchPressed func() []bool
	LastPressed  []bool
	Pressed      []bool
}

func NewKeyLogger

func NewKeyLogger(keySettings []input.Key) (k KeyLogger)

func (KeyLogger) KeyAction

func (l KeyLogger) KeyAction(k int) input.KeyAction

type MeterDrawer

type MeterDrawer struct {
	MaxCountdown int
	Marks        []MeterMark
	Meter        draws.Sprite
	Anchor       draws.Sprite
	Unit         draws.Sprite
}

func NewMeterDrawer

func NewMeterDrawer(js []Judgment, colors []color.NRGBA) (d MeterDrawer)

Anchor is a unit sprite constantly drawn at the middle of meter.

func (*MeterDrawer) AddMark

func (d *MeterDrawer) AddMark(offset int, colorType int)

func (MeterDrawer) Draw

func (d MeterDrawer) Draw(screen *ebiten.Image)

func (MeterDrawer) MarkAge

func (d MeterDrawer) MarkAge(m MeterMark) float64

func (*MeterDrawer) Update

func (d *MeterDrawer) Update()

type MeterMark

type MeterMark struct {
	Countdown int
	Offset    int // Derived from time error.
	ColorType int
}

type ModeProp

type ModeProp struct {
	Name           string
	Mode           int
	ChartInfos     []ChartInfo
	Cursor         int                 // Todo: custom chart infos - custom cursor
	Results        map[[16]byte]Result // md5.Size = 16
	LastUpdateTime time.Time
	LoadSkin       func()
	// Skin interface{ Load() } // Todo: use this later
	SpeedKeyHandler ctrl.KeyHandler
	SpeedScale      *float64
	NewChartInfo    func(string) (ChartInfo, error)
	NewScenePlay    func(cpath string, rf *osr.Format) (Scene, error)
	ExposureTime    func(float64) float64
	KeySettings     map[int][]input.Key
}

ModeProp stands for Mode properties.

func (ModeProp) LoadNewChartInfos

func (prop ModeProp) LoadNewChartInfos(musicRoot string) []ChartInfo

Todo: multiple music root. Would be not that hard. func LoadNewChartInfos(musicRoot string, prop *ModeProp) []ChartInfo {

type MusicPlayer

type MusicPlayer struct {
	*Timer
	Volume float64
	Player *audio.Player
	Closer func() error
	// contains filtered or unexported fields
}

func NewMusicPlayer

func NewMusicPlayer(path string, timer *Timer) (MusicPlayer, error)

func (MusicPlayer) Close

func (p MusicPlayer) Close()

func (*MusicPlayer) Update

func (p *MusicPlayer) Update()

type NumberDrawer

type NumberDrawer struct {
	draws.BaseDrawer
	DigitWidth float64
	DigitGap   float64
	Combo      int
	Bounce     float64
	Sprites    [10]draws.Sprite
}

func (NumberDrawer) Draw

func (d NumberDrawer) Draw(screen *ebiten.Image)

ComboDrawer's Draw draws each number at constant x regardless of their widths.

func (*NumberDrawer) Update

func (d *NumberDrawer) Update(combo int)

Each number has different width. Number 0's width is used as standard.

type PlayToResultArgs

type PlayToResultArgs struct {
	Result
}

type Result

type Result struct {
	MD5        [16]byte  // MD5 for raw chart file. md5.Size = 16
	PlayedTime time.Time // Finish time of playing.

	ScoreFactors   [3]float64 // Retrieved from the chart.
	Scores         [4]float64
	JudgmentCounts []int
	MaxCombo       int
}

Todo: SceneResult. keep playing music when at SceneResult. Todo: implement Replay

type Sample

type Sample struct {
	Name   string // aka SampleFilename.
	Volume float64
}

func NewSample

func NewSample(f any) (s Sample)

func (Sample) Path

func (n Sample) Path(cpath string) (string, bool)

type Scene

type Scene interface {
	Update() any
	Draw(screen *ebiten.Image)
}

type SceneSelect

type SceneSelect struct {
	// Query     string
	View             []ChartInfo // Todo: ChartInfo -> *ChartInfo?
	Cursor           int
	CursorKeyHandler ctrl.KeyHandler

	BackgroundDrawer BackgroundDrawer
	MusicPlayer      *audio.Player // Todo: Rewind after preview has finished.
	MusicCloser      io.Closer
}

SceneSelect might be created after one play at multiplayer. Todo: fetch Score with Replay Todo: preview music. Start at PreviewTime, keeps playing until end.

func NewSceneSelect

func NewSceneSelect() *SceneSelect

func (SceneSelect) DebugPrint

func (s SceneSelect) DebugPrint(screen *ebiten.Image)

func (SceneSelect) Draw

func (s SceneSelect) Draw(screen *ebiten.Image)

Currently Chart infos are not in loop. May add extra effect to box arrangement. e.g., x -= y / 5

func (*SceneSelect) Update

func (s *SceneSelect) Update() any

func (*SceneSelect) UpdateBackground

func (s *SceneSelect) UpdateBackground()

func (*SceneSelect) UpdateMode

func (s *SceneSelect) UpdateMode()

func (SceneSelect) Viewport

func (s SceneSelect) Viewport() ([]ChartInfo, int)

type ScoreDrawer

type ScoreDrawer struct {
	draws.BaseDrawer
	DigitWidth float64 // Use number 0's width.
	DigitGap   float64
	ZeroFill   int
	Score      ctrl.Delayed
	Sprites    [10]draws.Sprite
}

Todo: DigitWidth -> digitWidth with ScoreSprites[0].W()

func NewScoreDrawer

func NewScoreDrawer() ScoreDrawer

func (ScoreDrawer) Draw

func (d ScoreDrawer) Draw(screen *ebiten.Image)

NumberDrawer's Draw draws each number at the center of constant-width bound.

func (*ScoreDrawer) Update

func (d *ScoreDrawer) Update(score float64)

type Scorer

type Scorer struct {
	Flow       float64
	Combo      int
	Primitives [3]float64 // Sum of aquired primitive.
	Ratios     [3]float64
	Weights    [3]float64 // Works as current max value of note weights.
	MaxWeights [3]float64 // Works as Upper bound.

	ScoreFactors   [3]float64
	Scores         [4]float64
	ScoreBounds    [4]float64
	MaxScores      [4]float64
	JudgmentCounts []int
	MaxCombo       int
}

func NewScorer

func NewScorer(scoreFactors [3]float64) Scorer

func (*Scorer) AddCombo

func (s *Scorer) AddCombo()

func (*Scorer) BreakCombo

func (s *Scorer) BreakCombo()

func (*Scorer) CalcScore

func (s *Scorer) CalcScore(kind int, value, weight float64)

s.Primitives[Flow]+=math.Pow(s.Flow, a) * n.Weight()

func (Scorer) NewResult

func (s Scorer) NewResult(md5 [16]byte) Result

func (*Scorer) SetMaxScores

func (s *Scorer) SetMaxScores(maxScores [4]float64)

type SelectToPlayArgs

type SelectToPlayArgs struct {
	// Mode int
	// Mods   Mods
	Path   string
	Replay *osr.Format
}

type Timer

type Timer struct {
	StartTime time.Time
	Offset    int64
	// Duration  time.Duration
	Tick    int
	MaxTick int // A tick corresponding to EndTime = Duration + WaitAfter
	Now     int64
	Pause   bool
}

func NewTimer

func NewTimer(duration int64) Timer

func (Timer) IsDone

func (t Timer) IsDone() bool
func (t Timer) IsDone() bool {
	return ebiten.IsKeyPressed(ebiten.KeyEscape) || t.Tick >= t.MaxTick // time.Since(t.StartTime) >= t.Duration
}

func (*Timer) Sync

func (t *Timer) Sync()

func (*Timer) Ticker

func (t *Timer) Ticker()

func (t *Timer) SwitchPause() {}

type TransPoint

type TransPoint struct {
	Time      int64
	BPM       float64
	Speed     float64
	Meter     int
	NewBeat   bool    // NewBeat draws a bar.
	Volume    float64 // Range is [0, 1].
	Highlight bool

	Position float64
	Next     *TransPoint
	Prev     *TransPoint
}

func NewTransPoints

func NewTransPoints(f any) []*TransPoint

First BPM is used as temporary main BPM. No two TransPoints have same Time.

func (TransPoint) BeatDuration

func (tp TransPoint) BeatDuration() float64

func (*TransPoint) FetchByTime

func (tp *TransPoint) FetchByTime(time int64) *TransPoint

Directories

Path Synopsis
cmd
web
format
osr
osu
mode
test

Jump to

Keyboard shortcuts

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