Documentation ¶
Index ¶
- Constants
- Variables
- func BPMs(transPoints []*TransPoint, duration int64) (main, min, max float64)
- func ChartFileMode(fpath string) int
- func Level(c interface{ ... }) (float64, [3]float64)
- func LoadChartInfosSet(modeProps []ModeProp) error
- func LoadGeneralSkin()
- func LoadHandlers(props []ModeProp)
- func LoadReplays(replayRoot string) ([]*osr.Format, error)
- func NewBackground(path string) draws.Sprite
- func NewCursorKeyHandler(cursor *int, len int) ctrl.KeyHandler
- func Paths(base string) (paths []string)
- func SaveChartInfosSet(modeProps []ModeProp)
- func SetKeySettings(props []ModeProp)
- func SetTPS()
- func SetTitle(c ChartHeader)
- func Sort(sortBy int)
- func Sum(vs []float64) (sum float64)
- func TickToTime(tick int) int64
- func TidyChartInfosSet(modeProps []ModeProp)
- func TimeToTick(time int64) int
- type BackgroundDrawer
- type ChartHeader
- type ChartInfo
- type Game
- type Judgment
- type KeyLogger
- type MeterDrawer
- type MeterMark
- type ModeProp
- type MusicPlayer
- type NumberDrawer
- type PlayToResultArgs
- type Result
- type Sample
- type Scene
- type SceneSelect
- type ScoreDrawer
- type Scorer
- type SelectToPlayArgs
- type Timer
- type TransPoint
Constants ¶
const ( SignDot = iota SignComma SignPercent )
const ( SortByName = iota SortByLevel )
const ( DecayFactor = 0.95 LevelPower = 1.15 LevelScale = 0.02 )
Todo: find the best SliceDuration value
const ( ModeNone = iota - 1 ModePiano4 // 1 to 4 Key ModePiano7 // 5, 6 Key and 7+ Key ModeDrum ModeKaraoke )
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
const ( ScreenSizeX = screenSizeX ScreenSizeY = screenSizeY )
ScreenSize is a logical size of in-game screen.
const ( CursorSpriteBase = iota CursorSpriteAdditive CursorSpriteTrail )
const Wait = 1800
Variables ¶
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 )
FaceDefault = basicfont.Face7x13
var ( MusicVolume float64 = 0.25 EffectVolume float64 = 0.25 BackgroundBrightness float64 = 0.6 Offset int = -65 )
var ( ModeKeyHandler ctrl.KeyHandler SortKeyHandler ctrl.KeyHandler MusicVolumeKeyHandler ctrl.KeyHandler EffectVolumeKeyHandler ctrl.KeyHandler BrightKeyHandler ctrl.KeyHandler OffsetKeyHandler ctrl.KeyHandler )
var ( MusicRoot = "music" WindowSizeX = 1600 WindowSizeY = 900 )
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 )
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.
var ( SelectSound []byte SwipeSound []byte TapSound []byte ToggleSounds [2][]byte TransitionSounds [2][]byte )
var DefaultMaxScores = [4]float64{
7 * 1e5,
3 * 1e5,
1 * 1e5,
11 * 1e5,
}
var MeterMarkColors = []color.NRGBA{
{255, 255, 255, 192},
{213, 0, 242, 192},
{252, 83, 6, 255},
}
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 ¶
Mode determines a mode of chart file by its path.
func Level ¶
No need to define interface{} called ChartAnalyzer: https://go.dev/play/p/PtgBkwKZFhP
func LoadChartInfosSet ¶
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 ¶
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 NewCursorKeyHandler ¶
func NewCursorKeyHandler(cursor *int, len int) ctrl.KeyHandler
func SaveChartInfosSet ¶
func SaveChartInfosSet(modeProps []ModeProp)
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 TickToTime ¶
func TidyChartInfosSet ¶
func TidyChartInfosSet(modeProps []ModeProp)
TidyChartInfosSet drops unavailable chart infos from games.
func TimeToTick ¶
Time is a point of time, duration a length of time.
Types ¶
type BackgroundDrawer ¶
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
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 ¶
Todo: mode of ChartSet as a move unit
func (ChartInfo) BackgroundPath ¶
func (ChartInfo) NewChartBoard ¶
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 (ChartInfo) TimeString ¶
type Judgment ¶
type KeyLogger ¶
func NewKeyLogger ¶
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 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 ¶
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 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 (*Scorer) BreakCombo ¶
func (s *Scorer) BreakCombo()
func (*Scorer) SetMaxScores ¶
type SelectToPlayArgs ¶
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 }
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