在Golang中的游戏循环模拟

huangapple go评论76阅读模式
英文:

Game Loop simulation in Golang

问题

我想在Go语言中创建游戏循环,所以我尝试了以下代码:

package main

import (
	"fmt"
	"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 {
		panic("err")
		wg.Done()
	}
}

这个程序以62.5Hz的速度运行(16*time.Millisecond),变量sec用于在5秒后调用wg.Done(),并导致变量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]的意思是什么?我在5秒的游戏循环中使用了314个goroutine吗?如果程序运行数小时会怎样?

但是,如果程序使用runtime包并打印runtime.NumGoroutine,它返回的结果是Goroutines: 2

所以,goroutine 314 [running]的意思是什么?而runtime包则给出了不同的结果。

最后,如果有人能向我展示更好的在Go语言中创建游戏循环的方法,我会非常感激。谢谢!

英文:

I want to create game loop in go(lang), so i tried this:

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()
	}
}

This program running at 62.5Hz (16*time.Millisecond), var sec is used for calling wg.Done() after 5 second and caused var v printed 300 times.

calling panic("err") making the result like this:

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

Well what is the meaning of goroutine 314 [running] ? did i use 314 goroutine for 5 second game loop? how if this run for hours?

But, if the program use runtime package and print runtime.NumGoroutine which is return number of goroutine, the result is Goroutines: 2

So, back again what is the meaning of goroutine 314 [running]? while runtime package say different things.

Last one, if anyone can show me the better way to create game loop in golang, i really appreciate that, thankyou

答案1

得分: 7

AfterFunc在一个goroutine中执行注册的函数。https://golang.org/pkg/time/#AfterFunc

虽然一次只有2个goroutine在运行,但在整个程序中可能已经有314个goroutine(不确定goroutine的id是如何工作的)。


我不认为这是一种“更好”的方式,而是一种不同的方式,也是我更喜欢的方式,可以将游戏循环建模为一个for循环。

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

    for {
        select {
        case <-tick:

        }
    }
}

除了简洁地注册一个间隔的case外,通过在通道上进行选择,您还可以轻松地建模超时,只需为<-time.After添加另一个case,或者通过为<-done通道添加另一个case来进行取消。

英文:

AfterFunc executes the registered function in a goroutine. https://golang.org/pkg/time/#AfterFunc

While there are only 2 go routines running at a time, there have been 314 (maybe?? Not sure how goroutine ids work) goroutines throughout the program.


i don't consider it a "better" way, but a different way, and my preferred, could be to model the game loop as a for loop.

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

	for {
		select {
		case &lt;-tick:

		}
	}
}

In addition to concisely registering a case for an interval, selecting over a channel allows you to easily model a timeout, by adding another case for &lt;-time.After, or for cancellation, by adding another case for a &lt;-done channel.

huangapple
  • 本文由 发表于 2016年11月20日 02:27:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/40696458.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定