2016-11-19 224 views
0

我想在去(郎)創建遊戲循環,所以我想這:遊戲循環模擬Golang

package main 

import (
    "fmt" 
    // "runtime" 
    "sync" 
    "time" 
) 

var v = 0 
var wg sync.WaitGroup 
var sec = 5 

func main() { 
    wg.Add(1) 
    gameLoop() 
    wg.Wait() 
} 

func gameLoop() { 
    time.AfterFunc(16*time.Millisecond, gameLoop) 
    v++ 
    fmt.Println(v) 
    if v == sec*60 { 
     // fmt.Println("Goroutines: ", runtime.NumGoroutine()) 
     panic("err") 
     wg.Done() 
    } 
} 

這個程序在爲62.5Hz (16*time.Millisecond)運行,VAR sec用5秒鐘後調用wg.Done()並導致var v打印300次。

調用panic("err")使得最後結果是這樣的:

panic: err 

goroutine 314 [running]: 
panic(0x493c60, 0xc420094370) 
    /usr/local/go/src/runtime/panic.go:500 +0x1a1 
main.gameLoop() 
    /home/billyzaelani/Desktop/main.go:26 +0x11f 
created by time.goFunc 
    /usr/local/go/src/time/sleep.go:154 +0x44 
exit status 2 

那麼什麼是goroutine 314 [running]意思?我是否使用314 goroutine進行5秒遊戲循環?如果這運行幾個小時?

但是,如果程序使用運行時包和打印runtime.NumGoroutine這是夠程的回報數字,結果是Goroutines: 2

所以,回來是什麼goroutine 314 [running]意思?而運行時包則說不同的事情。

最後一個,如果有人能告訴我更好的方式來創建golang遊戲循環,我真的很感激的是,三江源

回答

5

AfterFunc執行註冊功能的夠程。 https://golang.org/pkg/time/#AfterFunc

儘管一次只運行2個例程,但在整個程序中已經有314個(也許不知道goroutine ID如何工作)例程。


我不認爲這是一個「更好」的方式,而是以不同的方式,和我的首選,可能是遊戲循環作爲for環模型。

func gameLoop() { 
    tick := time.Tick(16 * time.Millisecond) 

    for { 
     select { 
     case <-tick: 

     } 
    } 
} 

除了簡明地註冊的情況下,一個時間間隔,選擇通過信道讓您輕鬆,或用於取消,通過加入另一種情況下用於一<-done信道模型超時,通過加入另一種情況下爲<-time.After

+4

它甚至可以用更短的方式寫出:'範圍time.Tick(16 * time.Millisecond){...}'。你的建議是更好 - 更緊湊,更可讀,GC壓力更少,上下文切換更少,當然更多的慣用。 –

+0

嗯,我發現這比'time.AfterFunc()'更優雅。感謝你的回答。 – billyzaelani

+0

這就像有一個時間步驟?這是否適用於每秒30幀? – majidarif