Guarantee 60 FPS

This commit is contained in:
Hajime Hoshi 2015-02-21 22:00:02 +09:00
parent a67a8a03ec
commit f2a496b6ad

38
run.go
View File

@ -28,7 +28,8 @@ var runContext = &struct {
newScreenScale int newScreenScale int
}{} }{}
// CurrentFPS returns the current number of frames per second. // CurrentFPS returns the current number of rendering per second.
// Be careful this is different from the 'game' FPS (the number of calling your callback (f in Run) per second).
func CurrentFPS() float64 { func CurrentFPS() float64 {
return runContext.fps return runContext.fps
} }
@ -39,9 +40,8 @@ func CurrentFPS() float64 {
// //
// This function must be called from the main thread. // This function must be called from the main thread.
// //
// The given function f is expected to be called 60 times a second, // The given function f is guaranteed to be called 60 times a second
// but this is not strictly guaranteed. // even if a rendering frame is skipped.
// If you need to care about time, you need to check current time every time f is called.
func Run(f func(*Image) error, width, height, scale int, title string) error { func Run(f func(*Image) error, width, height, scale int, title string) error {
runContext.running = true runContext.running = true
defer func() { defer func() {
@ -60,7 +60,8 @@ func Run(f func(*Image) error, width, height, scale int, title string) error {
} }
frames := 0 frames := 0
t := ui.Now() gameTime := ui.Now()
before := ui.Now()
for { for {
if 0 < runContext.newScreenWidth || 0 < runContext.newScreenHeight || 0 < runContext.newScreenScale { if 0 < runContext.newScreenWidth || 0 < runContext.newScreenHeight || 0 < runContext.newScreenScale {
changed := false changed := false
@ -93,25 +94,30 @@ func Run(f func(*Image) error, width, height, scale int, title string) error {
if ui.IsClosed() { if ui.IsClosed() {
return nil return nil
} }
if err := graphicsContext.preUpdate(); err != nil { now := ui.Now()
return err for gameTime < now {
} gameTime += int64(time.Second / 60)
err := f(graphicsContext.screen) //gopherjs:blocking
if err != nil { if err := graphicsContext.preUpdate(); err != nil {
return err return err
}
if err := f(graphicsContext.screen); err != nil {
return err
}
audio.Tick()
} }
if err := graphicsContext.postUpdate(); err != nil { if err := graphicsContext.postUpdate(); err != nil {
return err return err
} }
audio.Tick()
ui.SwapBuffers() ui.SwapBuffers()
// Calc the current FPS. // Calc the current FPS.
now := ui.Now() now = ui.Now()
frames++ frames++
if time.Second <= time.Duration(now-t) { if time.Second <= time.Duration(now-before) {
runContext.fps = float64(frames) * float64(time.Second) / float64(now-t) runContext.fps = float64(frames) * float64(time.Second) / float64(now-before)
t = now before = now
frames = 0 frames = 0
} }
} }