mode

package
v0.3.1 Latest Latest
Warning

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

Go to latest
Published: Nov 28, 2022 License: Apache-2.0 Imports: 17 Imported by: 0

Documentation

Index

Constants

View Source
const (
	DecayFactor = 0.95
	LevelPower  = 1.15
	LevelScale  = 0.02
)

Todo: find the best SliceDuration value

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 (
	// Currently, TPS should be 1000 or greater.
	// 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().
	// Todo: add lower TPS support
	TPS = 1000

	// ScreenSize is a logical size of in-game screen.
	ScreenSizeX = 1600
	ScreenSizeY = 900
)
View Source
const (
	Default = iota
	User
	Play // For skin. Refreshes on every play.
)
View Source
const (
	ScoreDot = iota
	ScoreComma
	ScorePercent
)
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 (
	UserSettings = NewSettings()
	S            = &UserSettings
)
View Source
var (
	DefaultSkin = &Skin{}
	UserSkin    = &Skin{}
)
View Source
var (
	ToTick = times.ToTick
	ToTime = times.ToTime
)
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},
}

Todo: refactor MeterDrawer code

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 Level

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

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

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(fsys fs.FS, name string) draws.Sprite

func Normalize

func Normalize[V Number](v *V, min, max V)

func NormalizeKeys

func NormalizeKeys(names []string) []string

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(dst draws.Image)
func (d *BackgroundDrawer) Update() {
	if v := UserSettings.BackgroundBrightness; d.Brightness != v {
		d.Brightness = v
	}
}

type Chart

type Chart interface {
	WindowTitle() string
}

type ChartHeader

type ChartHeader struct {
	SetID         int64 // Compatibility for osu.
	ID            int64
	MusicName     string
	MusicUnicode  string
	Artist        string
	ArtistUnicode string
	MusicSource   string
	ChartName     string
	Charter       string
	HolderID      int64

	PreviewTime     int64
	MusicFilename   string // Filename is fine to use (cf. Filepath)
	ImageFilename   string
	VideoFilename   string
	VideoTimeOffset int64

	Mode    int
	SubMode int
}

ChartHeader contains non-play information. Changing 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) WindowTitle

func (c ChartHeader) WindowTitle() string

type ComboDrawer

type ComboDrawer struct {
	draws.Timer
	DigitWidth float64 // Use number 0's width.
	DigitGap   float64
	Combo      int
	Bounce     float64
	Sprites    [10]draws.Sprite
}

Todo: add combo *int and skip passing combo value?

func (ComboDrawer) Draw

func (d ComboDrawer) Draw(dst draws.Image)

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

func (*ComboDrawer) Update

func (d *ComboDrawer) Update(combo int)

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

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) IsValid

func (j Judgment) IsValid() bool

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

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. Todo: should w and h be math.Ceil()?

func (*MeterDrawer) AddMark

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

func (MeterDrawer) Draw

func (d MeterDrawer) Draw(dst draws.Image)

func (MeterDrawer) MarkAge

func (d MeterDrawer) MarkAge(m MeterMark) float64

Todo: remove

func (*MeterDrawer) Update

func (d *MeterDrawer) Update()

type MeterMark

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

type Number

type Number interface{ int | int64 | float64 }

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 ScoreDrawer

type ScoreDrawer struct {
	DigitGap float64
	ZeroFill int
	Score    draws.Delayed
	Sprites  []draws.Sprite
	// contains filtered or unexported fields
}

func NewScoreDrawer

func NewScoreDrawer(sprites []draws.Sprite) ScoreDrawer

func (ScoreDrawer) Draw

func (d ScoreDrawer) Draw(dst draws.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 Settings

type Settings struct {
	VolumeMusic          float64
	VolumeSound          float64
	Offset               int64
	BackgroundBrightness float64

	MeterUnit     float64 // number of pixels per 1ms
	MeterHeight   float64
	ScoreScale    float64
	ScoreDigitGap float64
}

Struct as a type of settings value is discouraged. Unmatched fields will not be touched, feel free to pre-fill default values. Todo: alert warning message to user when some lines are failed to be decoded Todo: BackgroundBrightness -> Brightness Todo: Brightness first, then Offset

func NewSettings

func NewSettings() Settings

func (*Settings) Load

func (s *Settings) Load(src Settings)

type Skin

type Skin struct {
	DefaultBackground draws.Sprite
	Score             [13]draws.Sprite // number + sign(. , %)
}

In narrow meaning, Skin stands for a set of Sprites. In wide meaning, Skin also includes a set of sounds. Package defaultskin has a set of sounds.

func (*Skin) Load

func (skin *Skin) Load(fsys fs.FS)

type Timer

type Timer struct {
	StartTime time.Time
	Now       int64
	Offset    int64

	Tick    int
	MaxTick int
	TPS     int
	// contains filtered or unexported fields
}

func NewTimer

func NewTimer(duration int64, offset *int64, tps int) Timer

func (Timer) IsDone

func (t Timer) IsDone() bool

func (*Timer) SetDone

func (t *Timer) SetDone()

func (*Timer) Ticker

func (t *Timer) Ticker()

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

Jump to

Keyboard shortcuts

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