2016-11-19 188 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